-
Notifications
You must be signed in to change notification settings - Fork 6k
[windows] Enable smooth resizing on windows #23701
Conversation
It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie on the #hackers channel in Chat. Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. |
f36188b
to
946ffd5
Compare
|
||
if (resize_target_width_ == width && resize_target_height_ == height) { | ||
surface_manager_->ResizeSurface(GetRenderTarget(), width, height); | ||
surface_manager_->MakeCurrent(); |
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.
Do we actually need these two steps to done within the lock? It's unclear to me if the mutex is also intended to protect the actual buffer swap, or just the ivars.
Relatedly, it would be helpful to annotate all these lock-using methods with the thread we expect them to be called on so it's easier to understand the flow.
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.
surface_manager_
methods here don't need to be protected by the mutex, the line immediately after this needs to be protected. That being said having these be protected by the mutex shouldn't cause any contention (for the flow as it stands now) given that all the surface manager methods will be invoked on the raster task runner.
I had a question about validating the task runner, i see this pattern a lot: GetTaskRunner()->RunsTasksOnCurrentThread()
, but it looks like in the case of windows the emedding only has a handle to the platform task runner / thread. I added comments to the methods with the task runner they run on, but i suspect theres something better we can do. Any ideas?
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.
Yes, we only have access to the task runners of threads we provide custom runners for. Comments are fine here; my concern wasn't enforcing invariants, just helping readers understand the threading flow (the assertion version is nice because then you have confidence that the comments aren't out of sync with reality, but I don't think that's a significant concern here.)
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.
That being said having these be protected by the mutex shouldn't cause any contention (for the flow as it stands now) given that all the surface manager methods will be invoked on the raster task runner.
Just to make sure I'm understanding: the reason we don't care about the lock blocking the platform thread unnecessarily during these steps is that if this block is running the platform thread is blocked on this whole step completing regardless, right?
It wouldn't hurt to put a comment here to that effect so that it doesn't look like a locking mistake (which tends to be my default concern when I see non-trivial function calls happening inside a lock).
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.
Added a comment clarifying that platform thread is blocked for the entirety of the step.
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.
LGTM with one suggestion
} | ||
|
||
void FlutterWindowsView::OnWindowSizeChanged(size_t width, size_t height) { | ||
// platform task runner |
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.
Does this comment mean this method must be called from the platform thread? If that is true would be great to flesh out the comment and / or maybe also express this in the header comment for this function since callers (UWP or win32 FlutterWindow
implementations) have different UI threading models and that contract may have material impact to their implementations.
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.
+1; please use style-conformant (i.e., full-sentence) comments. E.g., "Called on the platform thread."
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.
Converted these to full comments, and also amended the headers.
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.
LGTM with some small comments.
@@ -98,6 +98,8 @@ source_set("flutter_windows_source") { | |||
"win32_window_proc_delegate_manager.cc", | |||
"win32_window_proc_delegate_manager.h", | |||
] | |||
|
|||
libs = [ "dwmapi.lib" ] |
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.
Shouldn't this still be in a !winuwp condition?
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 is in an else block for if (target_os == "winuwp")
already.
std::unique_ptr<WindowBindingHandler> window_binding) | ||
: resize_status_(ResizeState::kDone), | ||
resize_target_width_(0), | ||
resize_target_height_(0) { |
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.
Initializer list is an improvement over the previous version, but I was referring to the C++11 feature of giving the initial value in the header where the value is declared: https://abseil.io/tips/61
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.
👍 done!
} | ||
|
||
void FlutterWindowsView::OnWindowSizeChanged(size_t width, size_t height) { | ||
// platform task runner |
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.
+1; please use style-conformant (i.e., full-sentence) comments. E.g., "Called on the platform thread."
|
||
if (resize_target_width_ == width && resize_target_height_ == height) { | ||
surface_manager_->ResizeSurface(GetRenderTarget(), width, height); | ||
surface_manager_->MakeCurrent(); |
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.
Yes, we only have access to the task runners of threads we provide custom runners for. Comments are fine here; my concern wasn't enforcing invariants, just helping readers understand the threading flow (the assertion version is nice because then you have confidence that the comments aren't out of sync with reality, but I don't think that's a significant concern here.)
@@ -255,7 +287,27 @@ bool FlutterWindowsView::ClearContext() { | |||
} | |||
|
|||
bool FlutterWindowsView::SwapBuffers() { | |||
return surface_manager_->SwapBuffers(); | |||
// raster task runner |
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 wouldn't necessarily name the specific thread for the raster thread cases since that's up to the engine; instead you could say something like "Called on an engine-controlled (non-platform) thread."
(It's particularly confusing to mention in an embedding built on the API, because the API never mentions the raster thread.)
|
||
if (resize_target_width_ == width && resize_target_height_ == height) { | ||
surface_manager_->ResizeSurface(GetRenderTarget(), width, height); | ||
surface_manager_->MakeCurrent(); |
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.
That being said having these be protected by the mutex shouldn't cause any contention (for the flow as it stands now) given that all the surface manager methods will be invoked on the raster task runner.
Just to make sure I'm understanding: the reason we don't care about the lock blocking the platform thread unnecessarily during these steps is that if this block is running the platform thread is blocked on this whole step completing regardless, right?
It wouldn't hurt to put a comment here to that effect so that it doesn't look like a locking mistake (which tends to be my default concern when I see non-trivial function calls happening inside a lock).
This pull request is not suitable for automatic merging in its current state.
|
This reverts commit f6162dc.
Brings #22279 up-to date and some minor modifications.
Related Issues
flutter/flutter#44136
flutter/flutter#66475