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" |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 // 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 |
202 // is installed to avoid flashes. | 202 // is installed to avoid flashes. |
203 base::scoped_nsobject<IOSurfaceLayer> old_io_surface_layer = | 203 base::scoped_nsobject<IOSurfaceLayer> old_io_surface_layer = |
204 io_surface_layer_; | 204 io_surface_layer_; |
205 | 205 |
206 // 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 |
207 // 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 |
208 // layer. | 208 // layer. |
209 bool needs_new_layer = | 209 bool needs_new_layer = |
210 !io_surface_layer_ || | 210 !io_surface_layer_ || |
| 211 [io_surface_layer_ hasBeenPoisoned] || |
211 [io_surface_layer_ scaleFactor] != scale_factor; | 212 [io_surface_layer_ scaleFactor] != scale_factor; |
212 if (needs_new_layer) { | 213 if (needs_new_layer) { |
213 io_surface_layer_.reset( | 214 io_surface_layer_.reset( |
214 [[IOSurfaceLayer alloc] initWithClient:this | 215 [[IOSurfaceLayer alloc] initWithClient:this |
215 withScaleFactor:scale_factor]); | 216 withScaleFactor:scale_factor]); |
216 if (io_surface_layer_) | 217 if (io_surface_layer_) |
217 [flipped_layer_ addSublayer:io_surface_layer_]; | 218 [flipped_layer_ addSublayer:io_surface_layer_]; |
218 else | 219 else |
219 LOG(ERROR) << "Failed to create IOSurfaceLayer"; | 220 LOG(ERROR) << "Failed to create IOSurfaceLayer"; |
220 } | 221 } |
221 | 222 |
222 // Open the provided IOSurface. | 223 // Open the provided IOSurface. |
223 [io_surface_layer_ gotFrameWithIOSurface:io_surface_id | 224 if (io_surface_layer_) { |
224 withPixelSize:pixel_size | 225 bool result = [io_surface_layer_ gotFrameWithIOSurface:io_surface_id |
225 withScaleFactor:scale_factor]; | 226 withPixelSize:pixel_size |
| 227 withScaleFactor:scale_factor]; |
| 228 if (!result) { |
| 229 DestroyIOSurfaceLayer(io_surface_layer_); |
| 230 LOG(ERROR) << "Failed open IOSurface in IOSurfaceLayer"; |
| 231 } |
| 232 } |
| 233 |
| 234 // Give a final complaint if anything with the layer's creation went wrong. |
| 235 // This frame will appear blank, the compositor will try to create another, |
| 236 // and maybe that will go better. |
| 237 if (!io_surface_layer_) { |
| 238 LOG(ERROR) << "IOSurfaceLayer is nil, tab will be blank"; |
| 239 IOSurfaceLayerHitError(); |
| 240 } |
226 | 241 |
227 // Make the CALayer draw and set its size appropriately. | 242 // Make the CALayer draw and set its size appropriately. |
228 if (io_surface_layer_) { | 243 if (io_surface_layer_) { |
| 244 [io_surface_layer_ gotNewFrame]; |
| 245 |
229 // 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. |
230 // If the bounds changed, force the content to be displayed immediately. | 247 // If the bounds changed, force the content to be displayed immediately. |
231 CGRect new_layer_bounds = CGRectMake( | 248 CGRect new_layer_bounds = CGRectMake( |
232 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()); |
233 bool bounds_changed = !CGRectEqualToRect( | 250 bool bounds_changed = !CGRectEqualToRect( |
234 new_layer_bounds, [io_surface_layer_ bounds]); | 251 new_layer_bounds, [io_surface_layer_ bounds]); |
235 [io_surface_layer_ setBounds:new_layer_bounds]; | 252 [io_surface_layer_ setBounds:new_layer_bounds]; |
236 if (bounds_changed) | 253 if (bounds_changed) |
237 [io_surface_layer_ setNeedsDisplayAndDisplayAndAck]; | 254 [io_surface_layer_ setNeedsDisplayAndDisplayAndAck]; |
238 } | 255 } |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 accelerated_output_surface_id_ = 0; | 338 accelerated_output_surface_id_ = 0; |
322 } | 339 } |
323 | 340 |
324 if (client_) | 341 if (client_) |
325 client_->BrowserCompositorViewFrameSwapped(accelerated_latency_info_); | 342 client_->BrowserCompositorViewFrameSwapped(accelerated_latency_info_); |
326 | 343 |
327 accelerated_latency_info_.clear(); | 344 accelerated_latency_info_.clear(); |
328 } | 345 } |
329 | 346 |
330 void BrowserCompositorViewMacInternal::IOSurfaceLayerHitError() { | 347 void BrowserCompositorViewMacInternal::IOSurfaceLayerHitError() { |
| 348 // Perform all acks that would have been done if the frame had succeeded, to |
| 349 // un-block the compositor and renderer. |
| 350 IOSurfaceLayerDidDrawFrame(); |
| 351 |
331 // Poison the context being used and request a mulligan. | 352 // Poison the context being used and request a mulligan. |
332 DestroyIOSurfaceLayer(io_surface_layer_); | 353 [io_surface_layer_ poisonContextAndSharegroup]; |
333 compositor_->ScheduleFullRedraw(); | 354 compositor_->ScheduleFullRedraw(); |
334 } | 355 } |
335 | 356 |
336 // static | 357 // static |
337 BrowserCompositorViewMacInternal* BrowserCompositorViewMacInternal:: | 358 BrowserCompositorViewMacInternal* BrowserCompositorViewMacInternal:: |
338 FromAcceleratedWidget(gfx::AcceleratedWidget widget) { | 359 FromAcceleratedWidget(gfx::AcceleratedWidget widget) { |
339 WidgetToInternalsMap::const_iterator found = | 360 WidgetToInternalsMap::const_iterator found = |
340 g_widget_to_internals_map.Pointer()->find(widget); | 361 g_widget_to_internals_map.Pointer()->find(widget); |
341 // 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 |
342 // destroyed, but while the ui::Compositor is still being destroyed. | 363 // destroyed, but while the ui::Compositor is still being destroyed. |
343 // Return NULL in these cases. | 364 // Return NULL in these cases. |
344 if (found == g_widget_to_internals_map.Pointer()->end()) | 365 if (found == g_widget_to_internals_map.Pointer()->end()) |
345 return NULL; | 366 return NULL; |
346 return found->second; | 367 return found->second; |
347 } | 368 } |
348 | 369 |
349 } // namespace content | 370 } // namespace content |
OLD | NEW |