Allow overriding the GLFW pixel ratio (flutter/engine#11388)

Allows a client to set a specific pixel ratio rather than using one
computed based on the screen details.

Fixes https://github.com/flutter/flutter/issues/37620
This commit is contained in:
stuartmorgan 2019-08-22 16:49:23 -07:00 committed by GitHub
parent 97e32ac140
commit 11945dd450
5 changed files with 52 additions and 3 deletions

View File

@ -80,6 +80,14 @@ class FlutterWindow {
return FlutterDesktopWindowGetScaleFactor(window_);
}
// Forces a specific pixel ratio for Flutter rendering, rather than one
// computed automatically from screen information.
//
// To clear a previously set override, pass an override value of zero.
void SetPixelRatioOverride(double pixel_ratio) {
FlutterDesktopWindowSetPixelRatioOverride(window_, pixel_ratio);
}
private:
// Handle for interacting with the C API's window.
//

View File

@ -115,6 +115,14 @@ double FlutterDesktopWindowGetScaleFactor(
return 1.0;
}
void FlutterDesktopWindowSetPixelRatioOverride(
FlutterDesktopWindowRef flutter_window,
double pixel_ratio) {
if (s_stub_implementation) {
return s_stub_implementation->SetPixelRatioOverride(pixel_ratio);
}
}
bool FlutterDesktopRunWindowEventLoopWithTimeout(
FlutterDesktopWindowControllerRef controller,
uint32_t millisecond_timeout) {

View File

@ -65,6 +65,9 @@ class StubFlutterGlfwApi {
// Called for FlutterDesktopWindowGetScaleFactor.
virtual double GetWindowScaleFactor() { return 1.0; }
// Called for FlutterDesktopWindowSetPixelRatioOverride.
virtual void SetPixelRatioOverride(double pixel_ratio) {}
// Called for FlutterDesktopRunWindowEventLoopWithTimeout.
virtual bool RunWindowEventLoopWithTimeout(uint32_t millisecond_timeout) {
return true;

View File

@ -92,6 +92,10 @@ struct FlutterDesktopWindow {
// The ratio of pixels per screen coordinate for the window.
double pixels_per_screen_coordinate = 1.0;
// If non-zero, a forced pixel ratio to use instead of one computed based on
// screen information.
double pixel_ratio_override = 0.0;
// Resizing triggers a window refresh, but the resize already updates Flutter.
// To avoid double messages, the refresh after each resize is skipped.
bool skip_next_window_refresh = false;
@ -177,9 +181,14 @@ static void SendWindowMetrics(FlutterDesktopWindowControllerState* state,
event.struct_size = sizeof(event);
event.width = width;
event.height = height;
// The Flutter pixel_ratio is defined as DPI/dp. Limit the ratio to a minimum
// of 1 to avoid rendering a smaller UI on standard resolution monitors.
event.pixel_ratio = std::max(dpi / kDpPerInch, 1.0);
if (state->window_wrapper->pixel_ratio_override == 0.0) {
// The Flutter pixel_ratio is defined as DPI/dp. Limit the ratio to a
// minimum of 1 to avoid rendering a smaller UI on standard resolution
// monitors.
event.pixel_ratio = std::max(dpi / kDpPerInch, 1.0);
} else {
event.pixel_ratio = state->window_wrapper->pixel_ratio_override;
}
FlutterEngineSendWindowMetricsEvent(state->engine, &event);
}
@ -714,6 +723,19 @@ double FlutterDesktopWindowGetScaleFactor(
return flutter_window->pixels_per_screen_coordinate;
}
void FlutterDesktopWindowSetPixelRatioOverride(
FlutterDesktopWindowRef flutter_window,
double pixel_ratio) {
flutter_window->pixel_ratio_override = pixel_ratio;
// Send a metrics update using the new pixel ratio.
int width_px, height_px;
glfwGetFramebufferSize(flutter_window->window, &width_px, &height_px);
if (width_px > 0 && height_px > 0) {
auto* state = GetSavedWindowState(flutter_window->window);
SendWindowMetrics(state, width_px, height_px);
}
}
bool FlutterDesktopRunWindowEventLoopWithTimeout(
FlutterDesktopWindowControllerRef controller,
uint32_t timeout_milliseconds) {

View File

@ -159,6 +159,14 @@ FLUTTER_EXPORT void FlutterDesktopWindowSetFrame(
FLUTTER_EXPORT double FlutterDesktopWindowGetScaleFactor(
FlutterDesktopWindowRef flutter_window);
// Forces a specific pixel ratio for Flutter rendering in |flutter_window|,
// rather than one computed automatically from screen information.
//
// To clear a previously set override, pass an override value of zero.
FLUTTER_EXPORT void FlutterDesktopWindowSetPixelRatioOverride(
FlutterDesktopWindowRef flutter_window,
double pixel_ratio);
// Runs an instance of a headless Flutter engine.
//
// Returns a null pointer in the event of an error.