Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(107)

Side by Side Diff: ui/views/cocoa/bridged_native_widget.mm

Issue 1352743002: MacViews: Synchronize resize operations with the GPU process (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@20150907-MacViews-ResizeHelperContent
Patch Set: rebase Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/views/cocoa/bridged_native_widget.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "ui/views/cocoa/bridged_native_widget.h" 5 #import "ui/views/cocoa/bridged_native_widget.h"
6 6
7 #import <objc/runtime.h> 7 #import <objc/runtime.h>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #import "base/mac/foundation_util.h" 10 #import "base/mac/foundation_util.h"
11 #include "base/mac/mac_util.h" 11 #include "base/mac/mac_util.h"
12 #import "base/mac/sdk_forward_declarations.h" 12 #import "base/mac/sdk_forward_declarations.h"
13 #include "base/thread_task_runner_handle.h" 13 #include "base/thread_task_runner_handle.h"
14 #include "ui/accelerated_widget_mac/window_resize_helper_mac.h"
14 #import "ui/base/cocoa/constrained_window/constrained_window_animation.h" 15 #import "ui/base/cocoa/constrained_window/constrained_window_animation.h"
15 #include "ui/base/hit_test.h" 16 #include "ui/base/hit_test.h"
16 #include "ui/base/ime/input_method.h" 17 #include "ui/base/ime/input_method.h"
17 #include "ui/base/ime/input_method_factory.h" 18 #include "ui/base/ime/input_method_factory.h"
18 #include "ui/gfx/display.h" 19 #include "ui/gfx/display.h"
19 #include "ui/gfx/geometry/dip_util.h" 20 #include "ui/gfx/geometry/dip_util.h"
20 #import "ui/gfx/mac/coordinate_conversion.h" 21 #import "ui/gfx/mac/coordinate_conversion.h"
21 #import "ui/gfx/mac/nswindow_frame_controls.h" 22 #import "ui/gfx/mac/nswindow_frame_controls.h"
22 #include "ui/gfx/screen.h" 23 #include "ui/gfx/screen.h"
23 #import "ui/views/cocoa/bridged_content_view.h" 24 #import "ui/views/cocoa/bridged_content_view.h"
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 if (monitor) 207 if (monitor)
207 return; 208 return;
208 209
209 monitor = [NSEvent 210 monitor = [NSEvent
210 addLocalMonitorForEventsMatchingMask:NSLeftMouseDownMask 211 addLocalMonitorForEventsMatchingMask:NSLeftMouseDownMask
211 handler:^NSEvent*(NSEvent* ns_event) { 212 handler:^NSEvent*(NSEvent* ns_event) {
212 return RepostEventIfHandledByWindow(ns_event); 213 return RepostEventIfHandledByWindow(ns_event);
213 }]; 214 }];
214 } 215 }
215 216
217 // Returns a task runner for creating a ui::Compositor. This allows compositor
218 // tasks to be funneled through ui::WindowResizeHelper's task runner to allow
219 // resize operations to coordinate with frames provided by the GPU process.
220 scoped_refptr<base::SingleThreadTaskRunner> GetCompositorTaskRunner() {
221 // If the WindowResizeHelper's pumpable task runner is set, it means the GPU
222 // process is directing messages there, and the compositor can synchronize
223 // with it. Otherwise, just use the UI thread.
224 scoped_refptr<base::SingleThreadTaskRunner> task_runner =
225 ui::WindowResizeHelperMac::Get()->task_runner();
226 return task_runner ? task_runner : base::ThreadTaskRunnerHandle::Get();
227 }
228
216 } // namespace 229 } // namespace
217 230
218 namespace views { 231 namespace views {
219 232
220 // static 233 // static
221 gfx::Size BridgedNativeWidget::GetWindowSizeForClientSize( 234 gfx::Size BridgedNativeWidget::GetWindowSizeForClientSize(
222 NSWindow* window, 235 NSWindow* window,
223 const gfx::Size& content_size) { 236 const gfx::Size& content_size) {
224 NSRect content_rect = 237 NSRect content_rect =
225 NSMakeRect(0, 0, content_size.width(), content_size.height()); 238 NSMakeRect(0, 0, content_size.width(), content_size.height());
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 // 2: the fullscreen button must be enabled so the user can leave fullscreen. 625 // 2: the fullscreen button must be enabled so the user can leave fullscreen.
613 // This will be reset when a transition out of fullscreen completes. 626 // This will be reset when a transition out of fullscreen completes.
614 gfx::SetNSWindowCanFullscreen(window_, true); 627 gfx::SetNSWindowCanFullscreen(window_, true);
615 628
616 [window_ toggleFullScreen:nil]; 629 [window_ toggleFullScreen:nil];
617 } 630 }
618 631
619 void BridgedNativeWidget::OnSizeChanged() { 632 void BridgedNativeWidget::OnSizeChanged() {
620 gfx::Size new_size = GetClientAreaSize(); 633 gfx::Size new_size = GetClientAreaSize();
621 native_widget_mac_->GetWidget()->OnNativeWidgetSizeChanged(new_size); 634 native_widget_mac_->GetWidget()->OnNativeWidgetSizeChanged(new_size);
622 if (layer()) 635 if (layer()) {
623 UpdateLayerProperties(); 636 UpdateLayerProperties();
637 if ([window_ inLiveResize])
638 MaybeWaitForFrame(new_size);
639 }
624 } 640 }
625 641
626 void BridgedNativeWidget::OnVisibilityChanged() { 642 void BridgedNativeWidget::OnVisibilityChanged() {
627 OnVisibilityChangedTo([window_ isVisible]); 643 OnVisibilityChangedTo([window_ isVisible]);
628 } 644 }
629 645
630 void BridgedNativeWidget::OnVisibilityChangedTo(bool new_visibility) { 646 void BridgedNativeWidget::OnVisibilityChangedTo(bool new_visibility) {
631 if (window_visible_ == new_visibility) 647 if (window_visible_ == new_visibility)
632 return; 648 return;
633 649
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
1005 DCHECK(context_factory); 1021 DCHECK(context_factory);
1006 1022
1007 AddCompositorSuperview(); 1023 AddCompositorSuperview();
1008 1024
1009 // TODO(tapted): Get this value from GpuDataManagerImpl via ViewsDelegate. 1025 // TODO(tapted): Get this value from GpuDataManagerImpl via ViewsDelegate.
1010 bool needs_gl_finish_workaround = false; 1026 bool needs_gl_finish_workaround = false;
1011 1027
1012 compositor_widget_.reset( 1028 compositor_widget_.reset(
1013 new ui::AcceleratedWidgetMac(needs_gl_finish_workaround)); 1029 new ui::AcceleratedWidgetMac(needs_gl_finish_workaround));
1014 compositor_.reset( 1030 compositor_.reset(
1015 new ui::Compositor(context_factory, base::ThreadTaskRunnerHandle::Get())); 1031 new ui::Compositor(context_factory, GetCompositorTaskRunner()));
1016 compositor_->SetAcceleratedWidgetAndStartCompositor( 1032 compositor_->SetAcceleratedWidgetAndStartCompositor(
1017 compositor_widget_->accelerated_widget()); 1033 compositor_widget_->accelerated_widget());
1018 compositor_widget_->SetNSView(this); 1034 compositor_widget_->SetNSView(this);
1019 } 1035 }
1020 1036
1021 void BridgedNativeWidget::InitCompositor() { 1037 void BridgedNativeWidget::InitCompositor() {
1022 DCHECK(layer()); 1038 DCHECK(layer());
1023 float scale_factor = GetDeviceScaleFactorFromView(compositor_superview_); 1039 float scale_factor = GetDeviceScaleFactorFromView(compositor_superview_);
1024 gfx::Size size_in_dip = GetClientAreaSize(); 1040 gfx::Size size_in_dip = GetClientAreaSize();
1025 compositor_->SetScaleAndSize(scale_factor, 1041 compositor_->SetScaleAndSize(scale_factor,
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1102 float scale_factor = GetDeviceScaleFactorFromView(compositor_superview_); 1118 float scale_factor = GetDeviceScaleFactorFromView(compositor_superview_);
1103 compositor_->SetScaleAndSize(scale_factor, 1119 compositor_->SetScaleAndSize(scale_factor,
1104 ConvertSizeToPixel(scale_factor, size_in_dip)); 1120 ConvertSizeToPixel(scale_factor, size_in_dip));
1105 1121
1106 // For a translucent window, the shadow calculation needs to be carried out 1122 // For a translucent window, the shadow calculation needs to be carried out
1107 // after the frame from the compositor arrives. 1123 // after the frame from the compositor arrives.
1108 if (![window_ isOpaque]) 1124 if (![window_ isOpaque])
1109 invalidate_shadow_on_frame_swap_ = true; 1125 invalidate_shadow_on_frame_swap_ = true;
1110 } 1126 }
1111 1127
1128 void BridgedNativeWidget::MaybeWaitForFrame(const gfx::Size& size_in_dip) {
1129 if (!layer()->IsDrawn() || compositor_widget_->HasFrameOfSize(size_in_dip))
1130 return;
1131
1132 const int kPaintMsgTimeoutMS = 50;
1133 const base::TimeTicks start_time = base::TimeTicks::Now();
1134 const base::TimeTicks timeout_time =
1135 start_time + base::TimeDelta::FromMilliseconds(kPaintMsgTimeoutMS);
1136
1137 ui::WindowResizeHelperMac* resize_helper = ui::WindowResizeHelperMac::Get();
1138 for (base::TimeTicks now = start_time; now < timeout_time;
1139 now = base::TimeTicks::Now()) {
1140 if (!resize_helper->WaitForSingleTaskToRun(timeout_time - now))
1141 return; // Timeout.
1142
1143 // Since the UI thread is blocked, the size shouldn't change.
1144 DCHECK(size_in_dip == GetClientAreaSize());
1145 if (compositor_widget_->HasFrameOfSize(size_in_dip))
1146 return; // Frame arrived.
1147 }
1148 }
1149
1112 NSMutableDictionary* BridgedNativeWidget::GetWindowProperties() const { 1150 NSMutableDictionary* BridgedNativeWidget::GetWindowProperties() const {
1113 NSMutableDictionary* properties = objc_getAssociatedObject( 1151 NSMutableDictionary* properties = objc_getAssociatedObject(
1114 window_, &kWindowPropertiesKey); 1152 window_, &kWindowPropertiesKey);
1115 if (!properties) { 1153 if (!properties) {
1116 properties = [NSMutableDictionary dictionary]; 1154 properties = [NSMutableDictionary dictionary];
1117 objc_setAssociatedObject(window_, &kWindowPropertiesKey, 1155 objc_setAssociatedObject(window_, &kWindowPropertiesKey,
1118 properties, OBJC_ASSOCIATION_RETAIN); 1156 properties, OBJC_ASSOCIATION_RETAIN);
1119 } 1157 }
1120 return properties; 1158 return properties;
1121 } 1159 }
1122 1160
1123 void BridgedNativeWidget::SetDraggable(bool draggable) { 1161 void BridgedNativeWidget::SetDraggable(bool draggable) {
1124 [bridged_view_ setMouseDownCanMoveWindow:draggable]; 1162 [bridged_view_ setMouseDownCanMoveWindow:draggable];
1125 // AppKit will not update its cache of mouseDownCanMoveWindow unless something 1163 // AppKit will not update its cache of mouseDownCanMoveWindow unless something
1126 // changes. Previously we tried adding an NSView and removing it, but for some 1164 // changes. Previously we tried adding an NSView and removing it, but for some
1127 // reason it required reposting the mouse-down event, and didn't always work. 1165 // reason it required reposting the mouse-down event, and didn't always work.
1128 // Calling the below seems to be an effective solution. 1166 // Calling the below seems to be an effective solution.
1129 [window_ setMovableByWindowBackground:NO]; 1167 [window_ setMovableByWindowBackground:NO];
1130 [window_ setMovableByWindowBackground:YES]; 1168 [window_ setMovableByWindowBackground:YES];
1131 } 1169 }
1132 1170
1133 } // namespace views 1171 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/cocoa/bridged_native_widget.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698