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

Side by Side Diff: ui/accelerated_widget_mac/accelerated_widget_mac.mm

Issue 1844053002: Add detached mode plumbing (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: And target Created 4 years, 8 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/accelerated_widget_mac/accelerated_widget_mac.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 #include "ui/accelerated_widget_mac/accelerated_widget_mac.h" 5 #include "ui/accelerated_widget_mac/accelerated_widget_mac.h"
6 6
7 #include <map> 7 #include <map>
8 8
9 #include "base/lazy_instance.h" 9 #include "base/lazy_instance.h"
10 #include "base/mac/mac_util.h" 10 #include "base/mac/mac_util.h"
11 #include "base/mac/scoped_cftyperef.h" 11 #include "base/mac/scoped_cftyperef.h"
12 #include "base/mac/sdk_forward_declarations.h" 12 #include "base/mac/sdk_forward_declarations.h"
13 #include "base/message_loop/message_loop.h" 13 #include "base/message_loop/message_loop.h"
14 #include "base/trace_event/trace_event.h" 14 #include "base/trace_event/trace_event.h"
15 #include "third_party/skia/include/core/SkCanvas.h" 15 #include "third_party/skia/include/core/SkCanvas.h"
16 #include "ui/base/cocoa/animation_utils.h" 16 #include "ui/base/cocoa/animation_utils.h"
17 #include "ui/gfx/geometry/dip_util.h" 17 #include "ui/gfx/geometry/dip_util.h"
18 #include "ui/gl/scoped_cgl.h" 18 #include "ui/gl/scoped_cgl.h"
19 19
20 @interface DetachedModeWindow : NSWindow {
21 base::WeakPtr<ui::AcceleratedWidgetMac> accelerated_widget_mac_;
22 base::scoped_nsobject<NSWindow> target_window_;
23 }
24
25 - (id)initWithAcceleratedWidgetMac:
26 (base::WeakPtr<ui::AcceleratedWidgetMac>)accelerated_widget_mac;
27 - (void)startForwardingEvents:(NSWindow*)target_window;
28 - (void)stopForwardingEvents;
29 @end
30
31 @implementation DetachedModeWindow : NSWindow
32 - (id)initWithAcceleratedWidgetMac:
33 (base::WeakPtr<ui::AcceleratedWidgetMac>)accelerated_widget_mac {
34 if (self = [super
35 initWithContentRect:NSMakeRect(0, 0, 100, 100)
36 styleMask:NSTitledWindowMask | NSResizableWindowMask |
37 NSFullSizeContentViewWindowMask
38 backing:NSBackingStoreBuffered
39 defer:NO]) {
40 [self setReleasedWhenClosed:NO];
41 accelerated_widget_mac_ = accelerated_widget_mac;
42 return self;
43 }
44 return nil;
45 }
46
47 - (void)startForwardingEvents:(NSWindow*)target_window {
48 target_window_.reset([target_window retain]);
49 }
50
51 - (void)stopForwardingEvents {
52 target_window_.reset();
53 }
54
55 - (void)close {
56 if (accelerated_widget_mac_)
57 accelerated_widget_mac_->DestroyDetachedModeWindow();
58 [super close];
59 }
60
61 - (void)sendEvent:(NSEvent*)event {
62 // This doesn't actually fix the issue for mouse move. Eh.
63 if (target_window_)
64 [target_window_ sendEvent:event];
65 }
66 @end
67
68 @interface NSWindowController (HorribleHack)
69 - (void)setDetachedVideoLayer:(base::scoped_nsobject<CALayer>)layer;
70 @end
71
20 @interface CALayer (PrivateAPI) 72 @interface CALayer (PrivateAPI)
21 - (void)setContentsChanged; 73 - (void)setContentsChanged;
22 @end 74 @end
23 75
24 namespace ui { 76 namespace ui {
25 namespace { 77 namespace {
26 78
27 typedef std::map<gfx::AcceleratedWidget,AcceleratedWidgetMac*> 79 typedef std::map<gfx::AcceleratedWidget,AcceleratedWidgetMac*>
28 WidgetToHelperMap; 80 WidgetToHelperMap;
29 base::LazyInstance<WidgetToHelperMap> g_widget_to_helper_map; 81 base::LazyInstance<WidgetToHelperMap> g_widget_to_helper_map;
30 82
31 AcceleratedWidgetMac* GetHelperFromAcceleratedWidget( 83 AcceleratedWidgetMac* GetHelperFromAcceleratedWidget(
32 gfx::AcceleratedWidget widget) { 84 gfx::AcceleratedWidget widget) {
33 WidgetToHelperMap::const_iterator found = 85 WidgetToHelperMap::const_iterator found =
34 g_widget_to_helper_map.Pointer()->find(widget); 86 g_widget_to_helper_map.Pointer()->find(widget);
35 // This can end up being accessed after the underlying widget has been 87 // This can end up being accessed after the underlying widget has been
36 // destroyed, but while the ui::Compositor is still being destroyed. 88 // destroyed, but while the ui::Compositor is still being destroyed.
37 // Return NULL in these cases. 89 // Return NULL in these cases.
38 if (found == g_widget_to_helper_map.Pointer()->end()) 90 if (found == g_widget_to_helper_map.Pointer()->end())
39 return NULL; 91 return NULL;
40 return found->second; 92 return found->second;
41 } 93 }
42 94
43 } // namespace 95 } // namespace
44 96
45 //////////////////////////////////////////////////////////////////////////////// 97 ////////////////////////////////////////////////////////////////////////////////
46 // AcceleratedWidgetMac 98 // AcceleratedWidgetMac
47 99
48 AcceleratedWidgetMac::AcceleratedWidgetMac() : view_(nullptr) { 100 AcceleratedWidgetMac::AcceleratedWidgetMac()
101 : view_(nullptr), weak_factory_(this) {
49 // Disable the fade-in animation as the layers are added. 102 // Disable the fade-in animation as the layers are added.
50 ScopedCAActionDisabler disabler; 103 ScopedCAActionDisabler disabler;
51 104
52 // Add a flipped transparent layer as a child, so that we don't need to 105 // Add a flipped transparent layer as a child, so that we don't need to
53 // fiddle with the position of sub-layers -- they will always be at the 106 // fiddle with the position of sub-layers -- they will always be at the
54 // origin. 107 // origin.
55 flipped_layer_.reset([[CALayer alloc] init]); 108 flipped_layer_.reset([[CALayer alloc] init]);
56 [flipped_layer_ setGeometryFlipped:YES]; 109 [flipped_layer_ setGeometryFlipped:YES];
57 [flipped_layer_ setAnchorPoint:CGPointMake(0, 0)]; 110 [flipped_layer_ setAnchorPoint:CGPointMake(0, 0)];
58 [flipped_layer_ 111 [flipped_layer_
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 view_->AcceleratedWidgetGetVSyncParameters(timebase, interval); 165 view_->AcceleratedWidgetGetVSyncParameters(timebase, interval);
113 } else { 166 } else {
114 *timebase = base::TimeTicks(); 167 *timebase = base::TimeTicks();
115 *interval = base::TimeDelta(); 168 *interval = base::TimeDelta();
116 } 169 }
117 } 170 }
118 171
119 void AcceleratedWidgetMac::GotFrame( 172 void AcceleratedWidgetMac::GotFrame(
120 CAContextID ca_context_id, 173 CAContextID ca_context_id,
121 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, 174 base::ScopedCFTypeRef<IOSurfaceRef> io_surface,
175 bool use_detached_mode,
176 CAContextID detached_ca_context_id,
122 const gfx::Size& pixel_size, 177 const gfx::Size& pixel_size,
123 float scale_factor) { 178 float scale_factor) {
124 TRACE_EVENT0("ui", "AcceleratedWidgetMac::GotFrame"); 179 TRACE_EVENT0("ui", "AcceleratedWidgetMac::GotFrame");
125 180
126 // If there is no view and therefore no superview to draw into, early-out. 181 // If there is no view and therefore no superview to draw into, early-out.
127 if (!view_) { 182 if (!view_) {
128 TRACE_EVENT0("ui", "No associated NSView"); 183 TRACE_EVENT0("ui", "No associated NSView");
129 return; 184 return;
130 } 185 }
131 186
132 // Disable the fade-in or fade-out effect if we create or remove layers. 187 // Disable the fade-in or fade-out effect if we create or remove layers.
133 ScopedCAActionDisabler disabler; 188 ScopedCAActionDisabler disabler;
134 189
135 last_swap_size_dip_ = gfx::ConvertSizeToDIP(scale_factor, pixel_size); 190 last_swap_size_dip_ = gfx::ConvertSizeToDIP(scale_factor, pixel_size);
136 191
137 if (ca_context_id) 192 if (ca_context_id)
138 GotCAContextFrame(ca_context_id, pixel_size, scale_factor); 193 GotCAContextFrame(ca_context_id, use_detached_mode, detached_ca_context_id,
194 pixel_size, scale_factor);
139 else 195 else
140 GotIOSurfaceFrame(io_surface, pixel_size, scale_factor); 196 GotIOSurfaceFrame(io_surface, pixel_size, scale_factor);
141 197
198 if (use_detached_mode)
199 EnterDetachedMode();
200 else
201 LeaveDetachedMode();
202
142 view_->AcceleratedWidgetSwapCompleted(); 203 view_->AcceleratedWidgetSwapCompleted();
143 } 204 }
144 205
145 void AcceleratedWidgetMac::GotCAContextFrame(CAContextID ca_context_id, 206 void AcceleratedWidgetMac::GotCAContextFrame(CAContextID ca_context_id,
207 bool use_detached,
208 CAContextID detached_ca_context_id,
146 const gfx::Size& pixel_size, 209 const gfx::Size& pixel_size,
147 float scale_factor) { 210 float scale_factor) {
148 TRACE_EVENT0("ui", "AcceleratedWidgetMac::GotCAContextFrame"); 211 TRACE_EVENT0("ui", "AcceleratedWidgetMac::GotCAContextFrame");
149 212
150 // In the layer is replaced, keep the old one around until after the new one 213 // In the layer is replaced, keep the old one around until after the new one
151 // is installed to avoid flashes. 214 // is installed to avoid flashes.
152 base::scoped_nsobject<CALayerHost> old_ca_context_layer = 215 base::scoped_nsobject<CALayerHost> old_ca_context_layer =
153 ca_context_layer_; 216 ca_context_layer_;
154 217
155 // Create the layer to host the layer exported by the GPU process with this 218 // Create the layer to host the layer exported by the GPU process with this
156 // particular CAContext ID. 219 // particular CAContext ID.
157 if ([ca_context_layer_ contextId] != ca_context_id) { 220 if ([ca_context_layer_ contextId] != ca_context_id) {
158 TRACE_EVENT0("ui", "Creating a new CALayerHost"); 221 TRACE_EVENT0("ui", "Creating a new CALayerHost");
159 ca_context_layer_.reset([[CALayerHost alloc] init]); 222 ca_context_layer_.reset([[CALayerHost alloc] init]);
160 [ca_context_layer_ setContextId:ca_context_id]; 223 [ca_context_layer_ setContextId:ca_context_id];
161 [ca_context_layer_ 224 [ca_context_layer_
162 setAutoresizingMask:kCALayerMaxXMargin|kCALayerMaxYMargin]; 225 setAutoresizingMask:kCALayerMaxXMargin|kCALayerMaxYMargin];
163 [flipped_layer_ addSublayer:ca_context_layer_]; 226 [flipped_layer_ addSublayer:ca_context_layer_];
164 } 227 }
165 228
229 if ([detached_ca_context_layer_ contextId] != detached_ca_context_id) {
230 TRACE_EVENT0("ui", "Creating a new CALayerHost");
231 detached_ca_context_layer_.reset([[CALayerHost alloc] init]);
232 [detached_ca_context_layer_ setContextId:detached_ca_context_id];
233 [detached_ca_context_layer_
234 setAutoresizingMask:kCALayerMaxXMargin | kCALayerMaxYMargin];
235 }
236
166 // If this replacing a same-type layer, remove it now that the new layer is 237 // If this replacing a same-type layer, remove it now that the new layer is
167 // in the hierarchy. 238 // in the hierarchy.
168 if (old_ca_context_layer != ca_context_layer_) 239 if (old_ca_context_layer != ca_context_layer_)
169 DestroyCAContextLayer(old_ca_context_layer); 240 DestroyCAContextLayer(old_ca_context_layer);
170 241
171 // Remove any different-type layers that this is replacing. 242 // Remove any different-type layers that this is replacing.
172 DestroyLocalLayer(); 243 DestroyLocalLayer();
173 } 244 }
174 245
175 void AcceleratedWidgetMac::EnsureLocalLayer() { 246 void AcceleratedWidgetMac::EnsureLocalLayer() {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 if (!local_layer_) 298 if (!local_layer_)
228 return; 299 return;
229 [local_layer_ removeFromSuperlayer]; 300 [local_layer_ removeFromSuperlayer];
230 local_layer_.reset(); 301 local_layer_.reset();
231 } 302 }
232 303
233 void AcceleratedWidgetMacGotFrame( 304 void AcceleratedWidgetMacGotFrame(
234 gfx::AcceleratedWidget widget, 305 gfx::AcceleratedWidget widget,
235 CAContextID ca_context_id, 306 CAContextID ca_context_id,
236 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, 307 base::ScopedCFTypeRef<IOSurfaceRef> io_surface,
308 bool use_detached,
309 CAContextID detached_ca_context_id,
237 const gfx::Size& pixel_size, 310 const gfx::Size& pixel_size,
238 float scale_factor, 311 float scale_factor,
239 base::TimeTicks* vsync_timebase, 312 base::TimeTicks* vsync_timebase,
240 base::TimeDelta* vsync_interval) { 313 base::TimeDelta* vsync_interval) {
241 if (vsync_timebase) 314 if (vsync_timebase)
242 *vsync_timebase = base::TimeTicks(); 315 *vsync_timebase = base::TimeTicks();
243 if (vsync_interval) 316 if (vsync_interval)
244 *vsync_interval = base::TimeDelta(); 317 *vsync_interval = base::TimeDelta();
245 318
246 AcceleratedWidgetMac* accelerated_widget_mac = 319 AcceleratedWidgetMac* accelerated_widget_mac =
247 GetHelperFromAcceleratedWidget(widget); 320 GetHelperFromAcceleratedWidget(widget);
248 321
249 if (accelerated_widget_mac) { 322 if (accelerated_widget_mac) {
250 accelerated_widget_mac->GotFrame(ca_context_id, io_surface, pixel_size, 323 accelerated_widget_mac->GotFrame(ca_context_id, io_surface, use_detached,
324 detached_ca_context_id, pixel_size,
251 scale_factor); 325 scale_factor);
252 if (vsync_timebase && vsync_interval) { 326 if (vsync_timebase && vsync_interval) {
253 accelerated_widget_mac->GetVSyncParameters(vsync_timebase, 327 accelerated_widget_mac->GetVSyncParameters(vsync_timebase,
254 vsync_interval); 328 vsync_interval);
255 } 329 }
256 } 330 }
257 } 331 }
258 332
333 NSWindow* AcceleratedWidgetMac::CreateDetachedModeWindow() {
334 DCHECK(!detached_mode_window_);
335
336 detached_mode_window_.reset([[DetachedModeWindow alloc]
337 initWithAcceleratedWidgetMac:weak_factory_.GetWeakPtr()]);
338
339 NSView* view = [detached_mode_window_ contentView];
340 base::scoped_nsobject<CALayer> background_layer([[CALayer alloc] init]);
341 [background_layer setBackgroundColor:CGColorGetConstantColor(kCGColorBlack)];
342 [view setLayer:background_layer];
343 [view setWantsLayer:YES];
344 [background_layer addSublayer:detached_ca_context_layer_];
345 return [detached_mode_window_ retain];
346 }
347
348 void AcceleratedWidgetMac::EnterDetachedMode() {
349 if (!detached_mode_window_ || in_detached_mode_)
350 return;
351 in_detached_mode_ = true;
352 NSWindow* view_window = [view_->AcceleratedWidgetGetNSView() window];
353 [detached_mode_window_ setFrame:[view_window frame] display:YES];
354 [detached_mode_window_
355 setStyleMask:[detached_mode_window_ styleMask] | NSFullScreenWindowMask];
356 // FIXME: This causes events to not be forwarded to the correct window.
357 [detached_mode_window_ orderWindow:NSWindowAbove
358 relativeTo:[view_window windowNumber]];
359 [detached_mode_window_ startForwardingEvents:view_window];
360 }
361
362 void AcceleratedWidgetMac::LeaveDetachedMode() {
363 if (!detached_mode_window_ || !in_detached_mode_)
364 return;
365 in_detached_mode_ = false;
366 NSWindow* view_window = [view_->AcceleratedWidgetGetNSView() window];
367 [detached_mode_window_ orderWindow:NSWindowBelow
368 relativeTo:[view_window windowNumber]];
369 [detached_mode_window_ stopForwardingEvents];
370 }
371
372 void AcceleratedWidgetMac::DestroyDetachedModeWindow() {
373 LeaveDetachedMode();
374 detached_mode_window_.reset();
375 }
376
259 } // namespace ui 377 } // namespace ui
OLDNEW
« no previous file with comments | « ui/accelerated_widget_mac/accelerated_widget_mac.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698