-
Notifications
You must be signed in to change notification settings - Fork 607
[glfw] Add pixel_ratio to the embedder #187
Conversation
|
I don't think we need the DPI calculations here; on macOS we just pass the pixel scale factor (e.g., 2 for Retina displays), so One you provide a non-1 value for |
|
This was my initial thought as well. But if I used only the pixelsPerScreenCoordinate, the application ofcourse still renders tiny (text barely readable). On my display, 1 pixel = 1 screen coordinate, so nothing changes. I believe that 1:1 ratio is the "normal" case for most linux users; there is no up-scaling performed by the GPU/driver and applications get the full display (in my case 4K) to render. In those cases the ratio would always be After digging into the inner workings of Flutter I found that the logical pixels, as given by the MediaQuery are actually the physical pixels we pass here divided by the ratio we pass here. Logical pixels are used for rendering things equally across devices.
For example: If I create a Container widget at 400 width ( Therefore I think we must take the DPI of the display into account here, so that the logical pixels in Flutter are calculated correctly on any device. The one thing I'm not sure of is screen coordinates vs pixels in GLFW. If Flutter renders to a canvas of screen coordinates, we should not calculate and apply pixelsPerScreenCoordinates. I would break things (render out of frame, or only use a small part of the frame). If Flutter renders to actual physcial pixels (as defined on the framebuffer), then we should.
On my machine I'm running with 1.6, and click handling works as before. But pixelsPerScreenCoordinates is 1.0, so there is no difference between the width/height we pass to flutter here and the coordinates obtained from I will be able to test on multiple monitors soon. I hope that gives me a non-1.0 pixelsPerScreenCoordinates to see how that works out for the rendering. |
I see, it sounds like I'm overfitting from the way macOS handles high-resolution displays then.
Unless the engine works very differently on Linux than macOS (which seems unlikely for the layer that would be involved), the sizes and coordinates passed through the embedding API should be in framebuffer coordinates. E.g., |
beaed7d to
3f4ac9b
Compare
3f4ac9b to
319281a
Compare
|
Pushed a merge, since my refactoring to combine the Linux and Windows implementation conflicted with this. As a result, this now improves the Windows implementation as well :) |
stuartmorgan-g
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some comments on specifics, but overall this looks good, and definitely improves the experience on high-DPI Linux and Windows displays.
I agree that going with this approach for now despite the multi-monitor issue makes sense, since it'll be a big improvement for the common case. The code was changed in the past to add pre-3.3 support, so breaking that again now just for the multi-display case probably isn't the right tradeoff. (I'll file a bug to capture that though.)
library/common/glfw/embedder.cc
Outdated
| FlutterEngineSendWindowMetricsEvent(state->engine, &event); | ||
| } | ||
|
|
||
| static void UpdateMonitorStats(GLFWwindow *window) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs a declaration comment.
Also, since with the changes above this will only compute one value, it would probably be clearer to just make it something like GetMonitorDPI, and have the caller update state with the return value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function only has one caller and very low complexity. Will inline it into CreateFlutterWindow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's enough going on in CreateFlutterWindow that I would prefer monitor detail calculation to stay factored out into a function.
library/common/glfw/embedder.cc
Outdated
| glfwGetWindowSize(window, &width, &height); | ||
| GLFWwindowSizeCallback(window, width, height); | ||
| glfwSetWindowSizeCallback(window, GLFWwindowSizeCallback); | ||
| glfwSetWindowSizeCallback(window, GLFWWindowSizeCallback); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, the lower-case W here was intentional, since the typename of the thing being resized is GLFWwindow rather than GLFWWindow; since it's being removed it doesn't really matter though. The mouse/cursor capitalization looks like a mistake though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed the capitalization because it was inconsistent across GLFW* functions. GLFWKeyCallback is already with capital K. Which should it be?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would argue that it should have been capital W though, because that's just the name of the callback in GLFW.
If we wanted to include the typename of the thing that's on which the callback is applied consistently it should imo be GLFWwindowWindowSizeCallback, GLFWwindowFramebufferSizeCallback, GLFWwindowMouseButtonCallback etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could actually still do that right now? Prefixing all the callback functions with the type on which they are called (GLFWwindow) instead of just GLFW.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Standardizing on capitalizing is the right way to go; I just remember that it came up during the initial review (the argument wasn't based on the parameter being passed, but that it was a GLFWwindow size that was changing). In retrospect it clearly has been confusing and should have been capitalized then.
802c39a to
28ebbe5
Compare
|
Thanks for the feedback @stuartmorgan. I have pushed the changes. There's one conversation still open/unclear to me, about the |
| std::unique_ptr<flutter_desktop_embedding::KeyEventHandler> key_event_handler; | ||
|
|
||
| // Window framebuffer dimensions, in pixels. | ||
| int width_px, height_px = 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are these statefull instead of passed as parameters? It looks like they are only ever stored just before calling a function and read inside that function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check, I have inlined SyncWindowMetrics.
|
The commit history kinda became a mess with all the changes, so I have rebased the changes on the latest master and opened a new PR for it. #204 |
|
For future reference we land all PRs with squash-and-merge, so the commit history of PRs doesn't matter. |

Related to #32
This PR adds pixel_ratio calculations to the linux/GLFW embedder.
The pixel_ratio seems to be based on 160 dpi. This is the same conversion rate for the
dpin Android. The Flutter documentation mentions the Nexus 6 to have a pixel_ratio of 3.5, which matches with it's pixels/dp scale-factor as well.GLFW makes use of screen coordinates, which are a virtual unit and do not always map 1:1 to physical pixels on a device. I am not 100% sure if the conversion to actual pixels is needed, or if Flutter should just know about screen coordinates?