OLD | NEW |
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 "content/browser/compositor/browser_compositor_view_mac.h" | 5 #include "content/browser/compositor/browser_compositor_view_mac.h" |
6 | 6 |
7 #include "base/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
8 #include "base/mac/scoped_cftyperef.h" | 8 #include "base/mac/scoped_cftyperef.h" |
9 #include "content/browser/renderer_host/compositing_iosurface_context_mac.h" | 9 #include "content/browser/renderer_host/compositing_iosurface_context_mac.h" |
10 #include "content/browser/renderer_host/compositing_iosurface_mac.h" | 10 #include "content/browser/renderer_host/compositing_iosurface_mac.h" |
11 #include "content/browser/renderer_host/software_layer_mac.h" | 11 #include "content/browser/renderer_host/software_layer_mac.h" |
12 #include "content/public/browser/context_factory.h" | 12 #include "content/public/browser/context_factory.h" |
13 #include "ui/base/cocoa/animation_utils.h" | 13 #include "ui/base/cocoa/animation_utils.h" |
14 #include "ui/gl/scoped_cgl.h" | 14 #include "ui/gl/scoped_cgl.h" |
15 | 15 |
| 16 @interface BrowserCompositorViewMac (Private) |
| 17 - (void)layerDidDrawFrame; |
| 18 - (void)gotAcceleratedLayerError; |
| 19 @end // BrowserCompositorViewMac (Private) |
| 20 |
| 21 namespace content { |
| 22 |
| 23 // The CompositingIOSurfaceLayerClient interface needs to be implemented as a |
| 24 // C++ class to operate on, rather than Objective C class. This helper class |
| 25 // provides a bridge between the two. |
| 26 class BrowserCompositorViewMacHelper : public CompositingIOSurfaceLayerClient { |
| 27 public: |
| 28 BrowserCompositorViewMacHelper(BrowserCompositorViewMac* view) |
| 29 : view_(view) {} |
| 30 virtual ~BrowserCompositorViewMacHelper() {} |
| 31 |
| 32 private: |
| 33 // CompositingIOSurfaceLayerClient implementation: |
| 34 virtual void AcceleratedLayerDidDrawFrame(bool succeeded) OVERRIDE { |
| 35 [view_ layerDidDrawFrame]; |
| 36 if (!succeeded) |
| 37 [view_ gotAcceleratedLayerError]; |
| 38 } |
| 39 |
| 40 BrowserCompositorViewMac* view_; |
| 41 }; |
| 42 |
| 43 } // namespace content |
| 44 |
| 45 |
16 // The default implementation of additions to the NSView interface for browser | 46 // The default implementation of additions to the NSView interface for browser |
17 // compositing should never be called. Log an error if they are. | 47 // compositing should never be called. Log an error if they are. |
18 @implementation NSView (BrowserCompositorView) | 48 @implementation NSView (BrowserCompositorView) |
19 | 49 |
20 - (void)gotAcceleratedIOSurfaceFrame:(uint64)surface_handle | 50 - (void)gotAcceleratedIOSurfaceFrame:(uint64)surface_handle |
21 withPixelSize:(gfx::Size)pixel_size | 51 withPixelSize:(gfx::Size)pixel_size |
22 withScaleFactor:(float)scale_factor { | 52 withScaleFactor:(float)scale_factor { |
23 DLOG(ERROR) << "-[NSView gotAcceleratedIOSurfaceFrame] called on " | 53 DLOG(ERROR) << "-[NSView gotAcceleratedIOSurfaceFrame] called on " |
24 << "non-overriden class."; | 54 << "non-overriden class."; |
25 } | 55 } |
26 | 56 |
27 - (void)gotSoftwareFrame:(cc::SoftwareFrameData*)frame_data | 57 - (void)gotSoftwareFrame:(cc::SoftwareFrameData*)frame_data |
28 withScaleFactor:(float)scale_factor | 58 withScaleFactor:(float)scale_factor |
29 withCanvas:(SkCanvas*)canvas { | 59 withCanvas:(SkCanvas*)canvas { |
30 DLOG(ERROR) << "-[NSView gotSoftwareFrame] called on non-overridden class."; | 60 DLOG(ERROR) << "-[NSView gotSoftwareFrame] called on non-overridden class."; |
31 } | 61 } |
32 | 62 |
33 @end // NSView (BrowserCompositorView) | 63 @end // NSView (BrowserCompositorView) |
34 | 64 |
35 @implementation BrowserCompositorViewMac : NSView | 65 @implementation BrowserCompositorViewMac : NSView |
36 | 66 |
37 - (id)initWithSuperview:(NSView*)view { | 67 - (id)initWithSuperview:(NSView*)view |
| 68 withClient:(content::BrowserCompositorViewMacClient*)client { |
38 if (self = [super init]) { | 69 if (self = [super init]) { |
| 70 client_ = client; |
| 71 helper_.reset(new content::BrowserCompositorViewMacHelper(self)); |
| 72 |
39 // Disable the fade-in animation as the layer and view are added. | 73 // Disable the fade-in animation as the layer and view are added. |
40 ScopedCAActionDisabler disabler; | 74 ScopedCAActionDisabler disabler; |
41 | 75 |
42 // Make this view host a transparent layer. | 76 // Make this view host a transparent layer. |
43 background_layer_.reset([[CALayer alloc] init]); | 77 background_layer_.reset([[CALayer alloc] init]); |
44 [background_layer_ setContentsGravity:kCAGravityTopLeft]; | 78 [background_layer_ setContentsGravity:kCAGravityTopLeft]; |
45 [self setLayer:background_layer_]; | 79 [self setLayer:background_layer_]; |
46 [self setWantsLayer:YES]; | 80 [self setWantsLayer:YES]; |
47 | 81 |
48 compositor_.reset(new ui::Compositor(self, content::GetContextFactory())); | 82 compositor_.reset(new ui::Compositor(self, content::GetContextFactory())); |
49 [view addSubview:self]; | 83 [view addSubview:self]; |
50 } | 84 } |
51 return self; | 85 return self; |
52 } | 86 } |
53 | 87 |
| 88 - (void)gotAcceleratedLayerError { |
| 89 if (!accelerated_layer_) |
| 90 return; |
| 91 |
| 92 [accelerated_layer_ context]->PoisonContextAndSharegroup(); |
| 93 compositor_->ScheduleFullRedraw(); |
| 94 } |
| 95 |
54 // This function closely mirrors RenderWidgetHostViewMac::LayoutLayers. When | 96 // This function closely mirrors RenderWidgetHostViewMac::LayoutLayers. When |
55 // only delegated rendering is supported, only one copy of this code will | 97 // only delegated rendering is supported, only one copy of this code will |
56 // need to exist. | 98 // need to exist. |
57 - (void)layoutLayers { | 99 - (void)layoutLayers { |
58 // Disable animation of the layers' resizing or repositioning. | 100 // Disable animation of the layers' resizing or repositioning. |
59 ScopedCAActionDisabler disabler; | 101 ScopedCAActionDisabler disabler; |
60 | 102 |
61 NSSize superview_frame_size = [[self superview] frame].size; | 103 NSSize superview_frame_size = [[self superview] frame].size; |
62 [self setFrame:NSMakeRect( | 104 [self setFrame:NSMakeRect( |
63 0, 0, superview_frame_size.width, superview_frame_size.height)]; | 105 0, 0, superview_frame_size.width, superview_frame_size.height)]; |
(...skipping 26 matching lines...) Expand all Loading... |
90 [accelerated_layer_ displayIfNeeded]; | 132 [accelerated_layer_ displayIfNeeded]; |
91 } | 133 } |
92 } | 134 } |
93 | 135 |
94 // The content area of the software layer is the size of the image provided. | 136 // The content area of the software layer is the size of the image provided. |
95 // Make the bounds of the layer match the superview's bounds, to ensure that | 137 // Make the bounds of the layer match the superview's bounds, to ensure that |
96 // the visible contents are drawn. | 138 // the visible contents are drawn. |
97 [software_layer_ setBounds:new_background_frame]; | 139 [software_layer_ setBounds:new_background_frame]; |
98 } | 140 } |
99 | 141 |
| 142 - (void)resetClient { |
| 143 [accelerated_layer_ resetClient]; |
| 144 client_ = NULL; |
| 145 } |
| 146 |
100 - (ui::Compositor*)compositor { | 147 - (ui::Compositor*)compositor { |
101 return compositor_.get(); | 148 return compositor_.get(); |
102 } | 149 } |
103 | 150 |
104 - (void)gotAcceleratedIOSurfaceFrame:(uint64)surface_handle | 151 - (void)gotAcceleratedIOSurfaceFrame:(uint64)surface_handle |
105 withPixelSize:(gfx::Size)pixel_size | 152 withPixelSize:(gfx::Size)pixel_size |
106 withScaleFactor:(float)scale_factor { | 153 withScaleFactor:(float)scale_factor { |
107 ScopedCAActionDisabler disabler; | 154 ScopedCAActionDisabler disabler; |
108 | 155 |
109 // If there is already an accelerated layer, but it has the wrong scale | 156 // If there is already an accelerated layer, but it has the wrong scale |
110 // factor or it was poisoned, remove the old layer and replace it. | 157 // factor or it was poisoned, remove the old layer and replace it. |
111 base::scoped_nsobject<CompositingIOSurfaceLayer> old_accelerated_layer; | 158 base::scoped_nsobject<CompositingIOSurfaceLayer> old_accelerated_layer; |
112 if (accelerated_layer_ && ( | 159 if (accelerated_layer_ && ( |
113 [accelerated_layer_ context]->HasBeenPoisoned() || | 160 [accelerated_layer_ context]->HasBeenPoisoned() || |
114 [accelerated_layer_ iosurface]->scale_factor() != scale_factor)) { | 161 [accelerated_layer_ iosurface]->scale_factor() != scale_factor)) { |
115 old_accelerated_layer = accelerated_layer_; | 162 old_accelerated_layer = accelerated_layer_; |
116 accelerated_layer_.reset(); | 163 accelerated_layer_.reset(); |
117 } | 164 } |
118 | 165 |
119 // If there is not a layer for accelerated frames, create one. | 166 // If there is not a layer for accelerated frames, create one. |
120 if (!accelerated_layer_) { | 167 if (!accelerated_layer_) { |
121 // Disable the fade-in animation as the layer is added. | 168 // Disable the fade-in animation as the layer is added. |
122 ScopedCAActionDisabler disabler; | 169 ScopedCAActionDisabler disabler; |
123 scoped_refptr<content::CompositingIOSurfaceMac> iosurface = | 170 scoped_refptr<content::CompositingIOSurfaceMac> iosurface = |
124 content::CompositingIOSurfaceMac::Create(); | 171 content::CompositingIOSurfaceMac::Create(); |
125 accelerated_layer_.reset([[CompositingIOSurfaceLayer alloc] | 172 accelerated_layer_.reset([[CompositingIOSurfaceLayer alloc] |
126 initWithIOSurface:iosurface | 173 initWithIOSurface:iosurface |
127 withScaleFactor:scale_factor | 174 withScaleFactor:scale_factor |
128 withClient:NULL]); | 175 withClient:helper_.get()]); |
129 [[self layer] addSublayer:accelerated_layer_]; | 176 [[self layer] addSublayer:accelerated_layer_]; |
130 } | 177 } |
131 | 178 |
132 { | 179 { |
133 bool result = true; | 180 bool result = true; |
134 gfx::ScopedCGLSetCurrentContext scoped_set_current_context( | 181 gfx::ScopedCGLSetCurrentContext scoped_set_current_context( |
135 [accelerated_layer_ context]->cgl_context()); | 182 [accelerated_layer_ context]->cgl_context()); |
136 result = [accelerated_layer_ iosurface]->SetIOSurfaceWithContextCurrent( | 183 result = [accelerated_layer_ iosurface]->SetIOSurfaceWithContextCurrent( |
137 [accelerated_layer_ context], surface_handle, pixel_size, scale_factor); | 184 [accelerated_layer_ context], surface_handle, pixel_size, scale_factor); |
138 if (!result) | 185 if (!result) |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 [self layoutLayers]; | 224 [self layoutLayers]; |
178 | 225 |
179 // If there was an accelerated layer, remove it. | 226 // If there was an accelerated layer, remove it. |
180 // Disable the fade-out animation as the layer is removed. | 227 // Disable the fade-out animation as the layer is removed. |
181 { | 228 { |
182 ScopedCAActionDisabler disabler; | 229 ScopedCAActionDisabler disabler; |
183 [accelerated_layer_ resetClient]; | 230 [accelerated_layer_ resetClient]; |
184 [accelerated_layer_ removeFromSuperlayer]; | 231 [accelerated_layer_ removeFromSuperlayer]; |
185 accelerated_layer_.reset(); | 232 accelerated_layer_.reset(); |
186 } | 233 } |
| 234 |
| 235 // This call can be nested insider ui::Compositor commit calls, and can also |
| 236 // make additional ui::Compositor commit calls. Avoid the potential recursion |
| 237 // by acknowledging the frame asynchronously. |
| 238 [self performSelector:@selector(layerDidDrawFrame) |
| 239 withObject:nil |
| 240 afterDelay:0]; |
| 241 } |
| 242 |
| 243 - (void)layerDidDrawFrame { |
| 244 if (client_) |
| 245 client_->BrowserCompositorDidDrawFrame(); |
187 } | 246 } |
188 | 247 |
189 @end // BrowserCompositorViewMac | 248 @end // BrowserCompositorViewMac |
OLD | NEW |