| Index: ui/views/cocoa/bridged_native_widget.mm
|
| diff --git a/ui/views/cocoa/bridged_native_widget.mm b/ui/views/cocoa/bridged_native_widget.mm
|
| index 7031b15e385c3eddabeeb5166054084c068cab68..6e30babc4143567d36136d3fe71638601c979cc2 100644
|
| --- a/ui/views/cocoa/bridged_native_widget.mm
|
| +++ b/ui/views/cocoa/bridged_native_widget.mm
|
| @@ -11,6 +11,7 @@
|
| #include "base/mac/mac_util.h"
|
| #import "base/mac/sdk_forward_declarations.h"
|
| #include "base/thread_task_runner_handle.h"
|
| +#include "ui/accelerated_widget_mac/window_resize_helper_mac.h"
|
| #import "ui/base/cocoa/constrained_window/constrained_window_animation.h"
|
| #include "ui/base/hit_test.h"
|
| #include "ui/base/ime/input_method.h"
|
| @@ -213,6 +214,18 @@ void SetupDragEventMonitor() {
|
| }];
|
| }
|
|
|
| +// Returns a task runner for creating a ui::Compositor. This allows compositor
|
| +// tasks to be funneled through ui::WindowResizeHelper's task runner to allow
|
| +// resize operations to coordinate with frames provided by the GPU process.
|
| +scoped_refptr<base::SingleThreadTaskRunner> GetCompositorTaskRunner() {
|
| + // If the WindowResizeHelper's pumpable task runner is set, it means the GPU
|
| + // process is directing messages there, and the compositor can synchronize
|
| + // with it. Otherwise, just use the UI thread.
|
| + scoped_refptr<base::SingleThreadTaskRunner> task_runner =
|
| + ui::WindowResizeHelperMac::Get()->task_runner();
|
| + return task_runner ? task_runner : base::ThreadTaskRunnerHandle::Get();
|
| +}
|
| +
|
| } // namespace
|
|
|
| namespace views {
|
| @@ -619,8 +632,11 @@ void BridgedNativeWidget::ToggleDesiredFullscreenState() {
|
| void BridgedNativeWidget::OnSizeChanged() {
|
| gfx::Size new_size = GetClientAreaSize();
|
| native_widget_mac_->GetWidget()->OnNativeWidgetSizeChanged(new_size);
|
| - if (layer())
|
| + if (layer()) {
|
| UpdateLayerProperties();
|
| + if ([window_ inLiveResize])
|
| + MaybeWaitForFrame(new_size);
|
| + }
|
| }
|
|
|
| void BridgedNativeWidget::OnVisibilityChanged() {
|
| @@ -1012,7 +1028,7 @@ void BridgedNativeWidget::CreateCompositor() {
|
| compositor_widget_.reset(
|
| new ui::AcceleratedWidgetMac(needs_gl_finish_workaround));
|
| compositor_.reset(
|
| - new ui::Compositor(context_factory, base::ThreadTaskRunnerHandle::Get()));
|
| + new ui::Compositor(context_factory, GetCompositorTaskRunner()));
|
| compositor_->SetAcceleratedWidgetAndStartCompositor(
|
| compositor_widget_->accelerated_widget());
|
| compositor_widget_->SetNSView(this);
|
| @@ -1109,6 +1125,28 @@ void BridgedNativeWidget::UpdateLayerProperties() {
|
| invalidate_shadow_on_frame_swap_ = true;
|
| }
|
|
|
| +void BridgedNativeWidget::MaybeWaitForFrame(const gfx::Size& size_in_dip) {
|
| + if (!layer()->IsDrawn() || compositor_widget_->HasFrameOfSize(size_in_dip))
|
| + return;
|
| +
|
| + const int kPaintMsgTimeoutMS = 50;
|
| + const base::TimeTicks start_time = base::TimeTicks::Now();
|
| + const base::TimeTicks timeout_time =
|
| + start_time + base::TimeDelta::FromMilliseconds(kPaintMsgTimeoutMS);
|
| +
|
| + ui::WindowResizeHelperMac* resize_helper = ui::WindowResizeHelperMac::Get();
|
| + for (base::TimeTicks now = start_time; now < timeout_time;
|
| + now = base::TimeTicks::Now()) {
|
| + if (!resize_helper->WaitForSingleTaskToRun(timeout_time - now))
|
| + return; // Timeout.
|
| +
|
| + // Since the UI thread is blocked, the size shouldn't change.
|
| + DCHECK(size_in_dip == GetClientAreaSize());
|
| + if (compositor_widget_->HasFrameOfSize(size_in_dip))
|
| + return; // Frame arrived.
|
| + }
|
| +}
|
| +
|
| NSMutableDictionary* BridgedNativeWidget::GetWindowProperties() const {
|
| NSMutableDictionary* properties = objc_getAssociatedObject(
|
| window_, &kWindowPropertiesKey);
|
|
|