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_private_mac.h" | 5 #include "content/browser/compositor/browser_compositor_view_private_mac.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 | 8 |
9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
12 #include "content/browser/compositor/gpu_process_transport_factory.h" | 12 #include "content/browser/compositor/gpu_process_transport_factory.h" |
13 #include "content/browser/renderer_host/compositing_iosurface_context_mac.h" | 13 #include "content/browser/compositor/io_surface_layer_mac.h" |
14 #include "content/browser/renderer_host/compositing_iosurface_mac.h" | 14 #include "content/browser/compositor/software_layer_mac.h" |
15 #include "content/browser/renderer_host/dip_util.h" | 15 #include "content/browser/renderer_host/dip_util.h" |
16 #include "content/browser/renderer_host/render_widget_resize_helper.h" | 16 #include "content/browser/renderer_host/render_widget_resize_helper.h" |
17 #include "content/browser/renderer_host/software_layer_mac.h" | |
18 #include "content/common/gpu/surface_handle_types_mac.h" | 17 #include "content/common/gpu/surface_handle_types_mac.h" |
19 #include "content/public/browser/context_factory.h" | 18 #include "content/public/browser/context_factory.h" |
20 #include "ui/base/cocoa/animation_utils.h" | 19 #include "ui/base/cocoa/animation_utils.h" |
21 #include "ui/gl/scoped_cgl.h" | 20 #include "ui/gl/scoped_cgl.h" |
22 | 21 |
23 namespace content { | 22 namespace content { |
24 namespace { | 23 namespace { |
25 | 24 |
26 typedef std::map<gfx::AcceleratedWidget,BrowserCompositorViewMacInternal*> | 25 typedef std::map<gfx::AcceleratedWidget,BrowserCompositorViewMacInternal*> |
27 WidgetToInternalsMap; | 26 WidgetToInternalsMap; |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 client_ = NULL; | 105 client_ = NULL; |
107 } | 106 } |
108 | 107 |
109 bool BrowserCompositorViewMacInternal::HasFrameOfSize( | 108 bool BrowserCompositorViewMacInternal::HasFrameOfSize( |
110 const gfx::Size& dip_size) const { | 109 const gfx::Size& dip_size) const { |
111 return last_swap_size_dip_ == dip_size; | 110 return last_swap_size_dip_ == dip_size; |
112 } | 111 } |
113 | 112 |
114 int BrowserCompositorViewMacInternal::GetRendererID() const { | 113 int BrowserCompositorViewMacInternal::GetRendererID() const { |
115 if (io_surface_layer_) | 114 if (io_surface_layer_) |
116 return [io_surface_layer_ iosurface]->GetRendererID(); | 115 return [io_surface_layer_ rendererID]; |
117 return 0; | 116 return 0; |
118 } | 117 } |
119 | 118 |
120 void BrowserCompositorViewMacInternal::BeginPumpingFrames() { | 119 void BrowserCompositorViewMacInternal::BeginPumpingFrames() { |
121 [io_surface_layer_ beginPumpingFrames]; | 120 [io_surface_layer_ beginPumpingFrames]; |
122 } | 121 } |
123 | 122 |
124 void BrowserCompositorViewMacInternal::EndPumpingFrames() { | 123 void BrowserCompositorViewMacInternal::EndPumpingFrames() { |
125 [io_surface_layer_ endPumpingFrames]; | 124 [io_surface_layer_ endPumpingFrames]; |
126 } | 125 } |
127 | 126 |
128 void BrowserCompositorViewMacInternal::GotAcceleratedFrame( | 127 void BrowserCompositorViewMacInternal::GotAcceleratedFrame( |
129 uint64 surface_handle, int output_surface_id, | 128 uint64 surface_handle, int output_surface_id, |
130 const std::vector<ui::LatencyInfo>& latency_info, | 129 const std::vector<ui::LatencyInfo>& latency_info, |
131 gfx::Size pixel_size, float scale_factor) { | 130 gfx::Size pixel_size, float scale_factor) { |
132 // Record the surface and latency info to use when acknowledging this frame. | 131 // Record the surface and latency info to use when acknowledging this frame. |
133 DCHECK(!accelerated_output_surface_id_); | 132 DCHECK(!accelerated_output_surface_id_); |
134 accelerated_output_surface_id_ = output_surface_id; | 133 accelerated_output_surface_id_ = output_surface_id; |
135 accelerated_latency_info_.insert(accelerated_latency_info_.end(), | 134 accelerated_latency_info_.insert(accelerated_latency_info_.end(), |
136 latency_info.begin(), latency_info.end()); | 135 latency_info.begin(), latency_info.end()); |
137 | 136 |
138 // If there is no client and therefore no superview to draw into, early-out. | 137 // If there is no client and therefore no superview to draw into, early-out. |
139 if (!client_) { | 138 if (!client_) { |
140 AcceleratedLayerDidDrawFrame(); | 139 IOSurfaceLayerDidDrawFrame(); |
141 return; | 140 return; |
142 } | 141 } |
143 | 142 |
144 // Disable the fade-in or fade-out effect if we create or remove layers. | 143 // Disable the fade-in or fade-out effect if we create or remove layers. |
145 ScopedCAActionDisabler disabler; | 144 ScopedCAActionDisabler disabler; |
146 | 145 |
147 last_swap_size_dip_ = ConvertSizeToDIP(scale_factor, pixel_size); | 146 last_swap_size_dip_ = ConvertSizeToDIP(scale_factor, pixel_size); |
148 switch (GetSurfaceHandleType(surface_handle)) { | 147 switch (GetSurfaceHandleType(surface_handle)) { |
149 case kSurfaceHandleTypeIOSurface: { | 148 case kSurfaceHandleTypeIOSurface: { |
150 IOSurfaceID io_surface_id = IOSurfaceIDFromSurfaceHandle(surface_handle); | 149 IOSurfaceID io_surface_id = IOSurfaceIDFromSurfaceHandle(surface_handle); |
(...skipping 25 matching lines...) Expand all Loading... |
176 if ([ca_context_layer_ contextId] != ca_context_id) { | 175 if ([ca_context_layer_ contextId] != ca_context_id) { |
177 ca_context_layer_.reset([[CALayerHost alloc] init]); | 176 ca_context_layer_.reset([[CALayerHost alloc] init]); |
178 [ca_context_layer_ setContextId:ca_context_id]; | 177 [ca_context_layer_ setContextId:ca_context_id]; |
179 [ca_context_layer_ | 178 [ca_context_layer_ |
180 setAutoresizingMask:kCALayerMaxXMargin|kCALayerMaxYMargin]; | 179 setAutoresizingMask:kCALayerMaxXMargin|kCALayerMaxYMargin]; |
181 [flipped_layer_ addSublayer:ca_context_layer_]; | 180 [flipped_layer_ addSublayer:ca_context_layer_]; |
182 } | 181 } |
183 | 182 |
184 // Acknowledge the frame to unblock the compositor immediately (the GPU | 183 // Acknowledge the frame to unblock the compositor immediately (the GPU |
185 // process will do any required throttling). | 184 // process will do any required throttling). |
186 AcceleratedLayerDidDrawFrame(); | 185 IOSurfaceLayerDidDrawFrame(); |
187 | 186 |
188 // If this replacing a same-type layer, remove it now that the new layer is | 187 // If this replacing a same-type layer, remove it now that the new layer is |
189 // in the hierarchy. | 188 // in the hierarchy. |
190 if (old_ca_context_layer != ca_context_layer_) | 189 if (old_ca_context_layer != ca_context_layer_) |
191 DestroyCAContextLayer(old_ca_context_layer); | 190 DestroyCAContextLayer(old_ca_context_layer); |
192 | 191 |
193 // Remove any different-type layers that this is replacing. | 192 // Remove any different-type layers that this is replacing. |
194 DestroyIOSurfaceLayer(io_surface_layer_); | 193 DestroyIOSurfaceLayer(io_surface_layer_); |
195 DestroySoftwareLayer(); | 194 DestroySoftwareLayer(); |
196 } | 195 } |
197 | 196 |
198 void BrowserCompositorViewMacInternal::GotAcceleratedIOSurfaceFrame( | 197 void BrowserCompositorViewMacInternal::GotAcceleratedIOSurfaceFrame( |
199 IOSurfaceID io_surface_id, | 198 IOSurfaceID io_surface_id, |
200 gfx::Size pixel_size, | 199 gfx::Size pixel_size, |
201 float scale_factor) { | 200 float scale_factor) { |
202 // In the layer is replaced, keep the old one around until after the new one | 201 // In the layer is replaced, keep the old one around until after the new one |
203 // is installed to avoid flashes. | 202 // is installed to avoid flashes. |
204 base::scoped_nsobject<CompositingIOSurfaceLayer> old_io_surface_layer = | 203 base::scoped_nsobject<IOSurfaceLayer> old_io_surface_layer = |
205 io_surface_layer_; | 204 io_surface_layer_; |
206 | 205 |
207 // Create or re-create an IOSurface layer if needed. If there already exists | 206 // Create or re-create an IOSurface layer if needed. If there already exists |
208 // a layer but it has the wrong scale factor or it was poisoned, re-create the | 207 // a layer but it has the wrong scale factor or it was poisoned, re-create the |
209 // layer. | 208 // layer. |
210 bool needs_new_layer = | 209 bool needs_new_layer = |
211 !io_surface_layer_ || | 210 !io_surface_layer_ || |
212 [io_surface_layer_ context]->HasBeenPoisoned() || | 211 [io_surface_layer_ hasBeenPoisoned] || |
213 [io_surface_layer_ iosurface]->scale_factor() != scale_factor; | 212 [io_surface_layer_ scaleFactor] != scale_factor; |
214 if (needs_new_layer) { | 213 if (needs_new_layer) { |
215 scoped_refptr<content::CompositingIOSurfaceMac> iosurface = | 214 io_surface_layer_.reset( |
216 content::CompositingIOSurfaceMac::Create(); | 215 [[IOSurfaceLayer alloc] initWithClient:this |
217 if (!iosurface) { | 216 withScaleFactor:scale_factor]); |
218 LOG(ERROR) << "Failed to create CompositingIOSurfaceMac"; | 217 if (io_surface_layer_) |
219 } else { | 218 [flipped_layer_ addSublayer:io_surface_layer_]; |
220 io_surface_layer_.reset([[CompositingIOSurfaceLayer alloc] | 219 else |
221 initWithIOSurface:iosurface | 220 LOG(ERROR) << "Failed to create IOSurfaceLayer"; |
222 withScaleFactor:scale_factor | |
223 withClient:this]); | |
224 if (io_surface_layer_) | |
225 [flipped_layer_ addSublayer:io_surface_layer_]; | |
226 else | |
227 LOG(ERROR) << "Failed to create CompositingIOSurfaceLayer"; | |
228 } | |
229 } | 221 } |
230 | 222 |
231 // Open the provided IOSurface. | 223 // Open the provided IOSurface. |
232 if (io_surface_layer_) { | 224 if (io_surface_layer_) { |
233 bool result = true; | 225 bool result = [io_surface_layer_ gotFrameWithIOSurface:io_surface_id |
234 gfx::ScopedCGLSetCurrentContext scoped_set_current_context( | 226 withPixelSize:pixel_size |
235 [io_surface_layer_ context]->cgl_context()); | 227 withScaleFactor:scale_factor]; |
236 result = [io_surface_layer_ iosurface]->SetIOSurfaceWithContextCurrent( | |
237 [io_surface_layer_ context], io_surface_id, pixel_size, scale_factor); | |
238 if (!result) { | 228 if (!result) { |
239 DestroyIOSurfaceLayer(io_surface_layer_); | 229 DestroyIOSurfaceLayer(io_surface_layer_); |
240 LOG(ERROR) << "Failed open IOSurface in CompositingIOSurfaceLayer"; | 230 LOG(ERROR) << "Failed open IOSurface in IOSurfaceLayer"; |
241 } | 231 } |
242 } | 232 } |
243 | 233 |
244 // Give a final complaint if anything with the layer's creation went wrong. | 234 // Give a final complaint if anything with the layer's creation went wrong. |
245 // This frame will appear blank, the compositor will try to create another, | 235 // This frame will appear blank, the compositor will try to create another, |
246 // and maybe that will go better. | 236 // and maybe that will go better. |
247 if (!io_surface_layer_) { | 237 if (!io_surface_layer_) { |
248 LOG(ERROR) << "CompositingIOSurfaceLayer is nil, tab will be blank"; | 238 LOG(ERROR) << "IOSurfaceLayer is nil, tab will be blank"; |
249 AcceleratedLayerHitError(); | 239 IOSurfaceLayerHitError(); |
250 } | 240 } |
251 | 241 |
252 // Make the CALayer draw and set its size appropriately. | 242 // Make the CALayer draw and set its size appropriately. |
253 if (io_surface_layer_) { | 243 if (io_surface_layer_) { |
254 [io_surface_layer_ gotNewFrame]; | 244 [io_surface_layer_ gotNewFrame]; |
255 | 245 |
256 // Set the bounds of the accelerated layer to match the size of the frame. | 246 // Set the bounds of the accelerated layer to match the size of the frame. |
257 // If the bounds changed, force the content to be displayed immediately. | 247 // If the bounds changed, force the content to be displayed immediately. |
258 CGRect new_layer_bounds = CGRectMake( | 248 CGRect new_layer_bounds = CGRectMake( |
259 0, 0, last_swap_size_dip_.width(), last_swap_size_dip_.height()); | 249 0, 0, last_swap_size_dip_.width(), last_swap_size_dip_.height()); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 void BrowserCompositorViewMacInternal::DestroyCAContextLayer( | 299 void BrowserCompositorViewMacInternal::DestroyCAContextLayer( |
310 base::scoped_nsobject<CALayerHost> ca_context_layer) { | 300 base::scoped_nsobject<CALayerHost> ca_context_layer) { |
311 if (!ca_context_layer) | 301 if (!ca_context_layer) |
312 return; | 302 return; |
313 [ca_context_layer removeFromSuperlayer]; | 303 [ca_context_layer removeFromSuperlayer]; |
314 if (ca_context_layer == ca_context_layer_) | 304 if (ca_context_layer == ca_context_layer_) |
315 ca_context_layer_.reset(); | 305 ca_context_layer_.reset(); |
316 } | 306 } |
317 | 307 |
318 void BrowserCompositorViewMacInternal::DestroyIOSurfaceLayer( | 308 void BrowserCompositorViewMacInternal::DestroyIOSurfaceLayer( |
319 base::scoped_nsobject<CompositingIOSurfaceLayer> io_surface_layer) { | 309 base::scoped_nsobject<IOSurfaceLayer> io_surface_layer) { |
320 if (!io_surface_layer) | 310 if (!io_surface_layer) |
321 return; | 311 return; |
322 [io_surface_layer resetClient]; | 312 [io_surface_layer resetClient]; |
323 [io_surface_layer removeFromSuperlayer]; | 313 [io_surface_layer removeFromSuperlayer]; |
324 if (io_surface_layer == io_surface_layer_) | 314 if (io_surface_layer == io_surface_layer_) |
325 io_surface_layer_.reset(); | 315 io_surface_layer_.reset(); |
326 } | 316 } |
327 | 317 |
328 void BrowserCompositorViewMacInternal::DestroySoftwareLayer() { | 318 void BrowserCompositorViewMacInternal::DestroySoftwareLayer() { |
329 if (!software_layer_) | 319 if (!software_layer_) |
330 return; | 320 return; |
331 [software_layer_ removeFromSuperlayer]; | 321 [software_layer_ removeFromSuperlayer]; |
332 software_layer_.reset(); | 322 software_layer_.reset(); |
333 } | 323 } |
334 | 324 |
335 bool BrowserCompositorViewMacInternal::AcceleratedLayerShouldAckImmediately() | 325 bool BrowserCompositorViewMacInternal::IOSurfaceLayerShouldAckImmediately() |
336 const { | 326 const { |
337 // If there is no client then the accelerated layer is not in the hierarchy | 327 // If there is no client then the accelerated layer is not in the hierarchy |
338 // and will never draw. | 328 // and will never draw. |
339 if (!client_) | 329 if (!client_) |
340 return true; | 330 return true; |
341 return client_->BrowserCompositorViewShouldAckImmediately(); | 331 return client_->BrowserCompositorViewShouldAckImmediately(); |
342 } | 332 } |
343 | 333 |
344 void BrowserCompositorViewMacInternal::AcceleratedLayerDidDrawFrame() { | 334 void BrowserCompositorViewMacInternal::IOSurfaceLayerDidDrawFrame() { |
345 if (accelerated_output_surface_id_) { | 335 if (accelerated_output_surface_id_) { |
346 content::ImageTransportFactory::GetInstance()->OnSurfaceDisplayed( | 336 content::ImageTransportFactory::GetInstance()->OnSurfaceDisplayed( |
347 accelerated_output_surface_id_); | 337 accelerated_output_surface_id_); |
348 accelerated_output_surface_id_ = 0; | 338 accelerated_output_surface_id_ = 0; |
349 } | 339 } |
350 | 340 |
351 if (client_) | 341 if (client_) |
352 client_->BrowserCompositorViewFrameSwapped(accelerated_latency_info_); | 342 client_->BrowserCompositorViewFrameSwapped(accelerated_latency_info_); |
353 | 343 |
354 accelerated_latency_info_.clear(); | 344 accelerated_latency_info_.clear(); |
355 } | 345 } |
356 | 346 |
357 void BrowserCompositorViewMacInternal::AcceleratedLayerHitError() { | 347 void BrowserCompositorViewMacInternal::IOSurfaceLayerHitError() { |
358 // Perform all acks that would have been done if the frame had succeeded, to | 348 // Perform all acks that would have been done if the frame had succeeded, to |
359 // un-block the compositor and renderer. | 349 // un-block the compositor and renderer. |
360 AcceleratedLayerDidDrawFrame(); | 350 IOSurfaceLayerDidDrawFrame(); |
361 | 351 |
362 // Poison the context being used and request a mulligan. | 352 // Poison the context being used and request a mulligan. |
363 if (io_surface_layer_) | 353 [io_surface_layer_ poisonContextAndSharegroup]; |
364 [io_surface_layer_ context]->PoisonContextAndSharegroup(); | |
365 compositor_->ScheduleFullRedraw(); | 354 compositor_->ScheduleFullRedraw(); |
366 } | 355 } |
367 | 356 |
368 // static | 357 // static |
369 BrowserCompositorViewMacInternal* BrowserCompositorViewMacInternal:: | 358 BrowserCompositorViewMacInternal* BrowserCompositorViewMacInternal:: |
370 FromAcceleratedWidget(gfx::AcceleratedWidget widget) { | 359 FromAcceleratedWidget(gfx::AcceleratedWidget widget) { |
371 WidgetToInternalsMap::const_iterator found = | 360 WidgetToInternalsMap::const_iterator found = |
372 g_widget_to_internals_map.Pointer()->find(widget); | 361 g_widget_to_internals_map.Pointer()->find(widget); |
373 // This can end up being accessed after the underlying widget has been | 362 // This can end up being accessed after the underlying widget has been |
374 // destroyed, but while the ui::Compositor is still being destroyed. | 363 // destroyed, but while the ui::Compositor is still being destroyed. |
375 // Return NULL in these cases. | 364 // Return NULL in these cases. |
376 if (found == g_widget_to_internals_map.Pointer()->end()) | 365 if (found == g_widget_to_internals_map.Pointer()->end()) |
377 return NULL; | 366 return NULL; |
378 return found->second; | 367 return found->second; |
379 } | 368 } |
380 | 369 |
381 } // namespace content | 370 } // namespace content |
OLD | NEW |