| 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 "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/command_line.h" | |
| 10 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
| 11 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| 12 #include "base/trace_event/trace_event.h" | 11 #include "base/trace_event/trace_event.h" |
| 13 #include "third_party/skia/include/core/SkCanvas.h" | 12 #include "third_party/skia/include/core/SkCanvas.h" |
| 14 #include "ui/accelerated_widget_mac/io_surface_layer.h" | 13 #include "ui/accelerated_widget_mac/io_surface_layer.h" |
| 15 #include "ui/accelerated_widget_mac/io_surface_ns_gl_surface.h" | 14 #include "ui/accelerated_widget_mac/io_surface_ns_gl_surface.h" |
| 16 #include "ui/accelerated_widget_mac/surface_handle_types.h" | 15 #include "ui/accelerated_widget_mac/surface_handle_types.h" |
| 17 #include "ui/base/cocoa/animation_utils.h" | 16 #include "ui/base/cocoa/animation_utils.h" |
| 18 #include "ui/base/ui_base_switches.h" | |
| 19 #include "ui/gfx/geometry/dip_util.h" | 17 #include "ui/gfx/geometry/dip_util.h" |
| 20 #include "ui/gl/scoped_cgl.h" | 18 #include "ui/gl/scoped_cgl.h" |
| 21 | 19 |
| 22 namespace ui { | 20 namespace ui { |
| 23 namespace { | 21 namespace { |
| 24 | 22 |
| 25 typedef std::map<gfx::AcceleratedWidget,AcceleratedWidgetMac*> | 23 typedef std::map<gfx::AcceleratedWidget,AcceleratedWidgetMac*> |
| 26 WidgetToHelperMap; | 24 WidgetToHelperMap; |
| 27 base::LazyInstance<WidgetToHelperMap> g_widget_to_helper_map; | 25 base::LazyInstance<WidgetToHelperMap> g_widget_to_helper_map; |
| 28 | 26 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 void AcceleratedWidgetMac::ResetNSView() { | 87 void AcceleratedWidgetMac::ResetNSView() { |
| 90 if (!view_) | 88 if (!view_) |
| 91 return; | 89 return; |
| 92 | 90 |
| 93 // Disable the fade-out animation as the view is removed. | 91 // Disable the fade-out animation as the view is removed. |
| 94 ScopedCAActionDisabler disabler; | 92 ScopedCAActionDisabler disabler; |
| 95 | 93 |
| 96 [flipped_layer_ removeFromSuperlayer]; | 94 [flipped_layer_ removeFromSuperlayer]; |
| 97 DestroyIOSurfaceLayer(io_surface_layer_); | 95 DestroyIOSurfaceLayer(io_surface_layer_); |
| 98 DestroyCAContextLayer(ca_context_layer_); | 96 DestroyCAContextLayer(ca_context_layer_); |
| 97 DestroyIOSurfaceNSGLSurface(); |
| 99 DestroySoftwareLayer(); | 98 DestroySoftwareLayer(); |
| 100 io_surface_ns_gl_surface_.reset(); | |
| 101 | 99 |
| 102 last_swap_size_dip_ = gfx::Size(); | 100 last_swap_size_dip_ = gfx::Size(); |
| 103 view_ = NULL; | 101 view_ = NULL; |
| 104 } | 102 } |
| 105 | 103 |
| 106 bool AcceleratedWidgetMac::HasFrameOfSize( | 104 bool AcceleratedWidgetMac::HasFrameOfSize( |
| 107 const gfx::Size& dip_size) const { | 105 const gfx::Size& dip_size) const { |
| 108 return last_swap_size_dip_ == dip_size; | 106 return last_swap_size_dip_ == dip_size; |
| 109 } | 107 } |
| 110 | 108 |
| 111 int AcceleratedWidgetMac::GetRendererID() const { | 109 int AcceleratedWidgetMac::GetRendererID() const { |
| 112 if (io_surface_layer_) | 110 if (io_surface_layer_) |
| 113 return [io_surface_layer_ rendererID]; | 111 return [io_surface_layer_ rendererID]; |
| 112 if (io_surface_ns_gl_surface_) |
| 113 return io_surface_ns_gl_surface_->GetRendererID(); |
| 114 return 0; | 114 return 0; |
| 115 } | 115 } |
| 116 | 116 |
| 117 bool AcceleratedWidgetMac::IsRendererThrottlingDisabled() const { | 117 bool AcceleratedWidgetMac::IsRendererThrottlingDisabled() const { |
| 118 if (view_) | 118 if (view_) |
| 119 return view_->AcceleratedWidgetShouldIgnoreBackpressure(); | 119 return view_->AcceleratedWidgetShouldIgnoreBackpressure(); |
| 120 return false; | 120 return false; |
| 121 } | 121 } |
| 122 | 122 |
| 123 void AcceleratedWidgetMac::BeginPumpingFrames() { | 123 void AcceleratedWidgetMac::BeginPumpingFrames() { |
| 124 [io_surface_layer_ beginPumpingFrames]; | 124 [io_surface_layer_ beginPumpingFrames]; |
| 125 } | 125 } |
| 126 | 126 |
| 127 void AcceleratedWidgetMac::EndPumpingFrames() { | 127 void AcceleratedWidgetMac::EndPumpingFrames() { |
| 128 [io_surface_layer_ endPumpingFrames]; | 128 [io_surface_layer_ endPumpingFrames]; |
| 129 } | 129 } |
| 130 | 130 |
| 131 void AcceleratedWidgetMac::GotAcceleratedFrame( | 131 void AcceleratedWidgetMac::GotAcceleratedFrame( |
| 132 uint64 surface_handle, | 132 uint64 surface_handle, |
| 133 const std::vector<ui::LatencyInfo>& latency_info, | 133 const std::vector<ui::LatencyInfo>& latency_info, |
| 134 const gfx::Size& pixel_size, | 134 const gfx::Size& pixel_size, |
| 135 float scale_factor, | 135 float scale_factor, |
| 136 const gfx::Rect& pixel_damage_rect, | 136 const gfx::Rect& pixel_damage_rect, |
| 137 const base::Closure& drawn_callback) { | 137 const base::Closure& drawn_callback) { |
| 138 static bool use_ns_gl_surfaces = | |
| 139 base::CommandLine::ForCurrentProcess()->HasSwitch( | |
| 140 switches::kEnableNSGLSurfaces); | |
| 141 | |
| 142 // Record the surface and latency info to use when acknowledging this frame. | 138 // Record the surface and latency info to use when acknowledging this frame. |
| 143 DCHECK(accelerated_frame_drawn_callback_.is_null()); | 139 DCHECK(accelerated_frame_drawn_callback_.is_null()); |
| 144 accelerated_frame_drawn_callback_ = drawn_callback; | 140 accelerated_frame_drawn_callback_ = drawn_callback; |
| 145 accelerated_latency_info_.insert(accelerated_latency_info_.end(), | 141 accelerated_latency_info_.insert(accelerated_latency_info_.end(), |
| 146 latency_info.begin(), latency_info.end()); | 142 latency_info.begin(), latency_info.end()); |
| 147 | 143 |
| 148 // If there is no view and therefore no superview to draw into, early-out. | 144 // If there is no view and therefore no superview to draw into, early-out. |
| 149 if (!view_) { | 145 if (!view_) { |
| 150 AcknowledgeAcceleratedFrame(); | 146 AcknowledgeAcceleratedFrame(); |
| 151 return; | 147 return; |
| 152 } | 148 } |
| 153 | 149 |
| 154 // Disable the fade-in or fade-out effect if we create or remove layers. | 150 // Disable the fade-in or fade-out effect if we create or remove layers. |
| 155 ScopedCAActionDisabler disabler; | 151 ScopedCAActionDisabler disabler; |
| 156 | 152 |
| 157 last_swap_size_dip_ = gfx::ConvertSizeToDIP(scale_factor, pixel_size); | 153 last_swap_size_dip_ = gfx::ConvertSizeToDIP(scale_factor, pixel_size); |
| 158 switch (GetSurfaceHandleType(surface_handle)) { | 154 switch (GetSurfaceHandleType(surface_handle)) { |
| 159 case kSurfaceHandleTypeIOSurface: { | 155 case kSurfaceHandleTypeIOSurface: { |
| 160 IOSurfaceID io_surface_id = IOSurfaceIDFromSurfaceHandle(surface_handle); | 156 IOSurfaceID io_surface_id = IOSurfaceIDFromSurfaceHandle(surface_handle); |
| 161 if (use_ns_gl_surfaces) { | 157 if (IOSurfaceNSGLSurface::CanUseNSGLSurfaceForView( |
| 158 view_->AcceleratedWidgetGetNSView())) { |
| 162 GotAcceleratedIOSurfaceFrameNSGL( | 159 GotAcceleratedIOSurfaceFrameNSGL( |
| 163 io_surface_id, pixel_size, scale_factor, pixel_damage_rect); | 160 io_surface_id, pixel_size, scale_factor, pixel_damage_rect); |
| 164 } else { | 161 } else { |
| 165 GotAcceleratedIOSurfaceFrame(io_surface_id, pixel_size, scale_factor); | 162 GotAcceleratedIOSurfaceFrame(io_surface_id, pixel_size, scale_factor); |
| 166 } | 163 } |
| 167 break; | 164 break; |
| 168 } | 165 } |
| 169 case kSurfaceHandleTypeCAContext: { | 166 case kSurfaceHandleTypeCAContext: { |
| 170 CAContextID ca_context_id = CAContextIDFromSurfaceHandle(surface_handle); | 167 CAContextID ca_context_id = CAContextIDFromSurfaceHandle(surface_handle); |
| 171 GotAcceleratedCAContextFrame(ca_context_id, pixel_size, scale_factor); | 168 GotAcceleratedCAContextFrame(ca_context_id, pixel_size, scale_factor); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 200 // process will do any required throttling). | 197 // process will do any required throttling). |
| 201 AcknowledgeAcceleratedFrame(); | 198 AcknowledgeAcceleratedFrame(); |
| 202 | 199 |
| 203 // If this replacing a same-type layer, remove it now that the new layer is | 200 // If this replacing a same-type layer, remove it now that the new layer is |
| 204 // in the hierarchy. | 201 // in the hierarchy. |
| 205 if (old_ca_context_layer != ca_context_layer_) | 202 if (old_ca_context_layer != ca_context_layer_) |
| 206 DestroyCAContextLayer(old_ca_context_layer); | 203 DestroyCAContextLayer(old_ca_context_layer); |
| 207 | 204 |
| 208 // Remove any different-type layers that this is replacing. | 205 // Remove any different-type layers that this is replacing. |
| 209 DestroyIOSurfaceLayer(io_surface_layer_); | 206 DestroyIOSurfaceLayer(io_surface_layer_); |
| 207 DestroyIOSurfaceNSGLSurface(); |
| 210 DestroySoftwareLayer(); | 208 DestroySoftwareLayer(); |
| 211 } | 209 } |
| 212 | 210 |
| 213 void AcceleratedWidgetMac::GotAcceleratedIOSurfaceFrameNSGL( | 211 void AcceleratedWidgetMac::GotAcceleratedIOSurfaceFrameNSGL( |
| 214 IOSurfaceID io_surface_id, | 212 IOSurfaceID io_surface_id, |
| 215 const gfx::Size& pixel_size, | 213 const gfx::Size& pixel_size, |
| 216 float scale_factor, | 214 float scale_factor, |
| 217 const gfx::Rect& pixel_damage_rect) { | 215 const gfx::Rect& pixel_damage_rect) { |
| 218 if (!io_surface_ns_gl_surface_) { | 216 if (!io_surface_ns_gl_surface_ || |
| 217 io_surface_ns_gl_surface_->NeedsToBeRecreated()) { |
| 219 io_surface_ns_gl_surface_.reset( | 218 io_surface_ns_gl_surface_.reset( |
| 220 IOSurfaceNSGLSurface::Create( | 219 IOSurfaceNSGLSurface::Create( |
| 221 this, view_->AcceleratedWidgetGetNSView())); | 220 this, |
| 221 view_->AcceleratedWidgetGetNSView(), |
| 222 needs_gl_finish_workaround_)); |
| 222 } | 223 } |
| 223 | 224 |
| 224 if (!io_surface_ns_gl_surface_) { | 225 if (!io_surface_ns_gl_surface_) { |
| 225 LOG(ERROR) << "Failed to create IOSurfaceNSGLSurface"; | 226 LOG(ERROR) << "Failed to create IOSurfaceNSGLSurface"; |
| 226 AcknowledgeAcceleratedFrame(); | 227 AcknowledgeAcceleratedFrame(); |
| 227 return; | 228 return; |
| 228 } | 229 } |
| 229 | 230 |
| 230 io_surface_ns_gl_surface_->GotFrame( | 231 io_surface_ns_gl_surface_->GotFrame( |
| 231 io_surface_id, pixel_size, scale_factor, pixel_damage_rect); | 232 io_surface_id, pixel_size, scale_factor, pixel_damage_rect); |
| 233 |
| 234 // Remove any different-type layers that this is replacing. |
| 235 DestroyCAContextLayer(ca_context_layer_); |
| 236 DestroyIOSurfaceLayer(io_surface_layer_); |
| 237 DestroySoftwareLayer(); |
| 232 } | 238 } |
| 233 | 239 |
| 234 void AcceleratedWidgetMac::GotAcceleratedIOSurfaceFrame( | 240 void AcceleratedWidgetMac::GotAcceleratedIOSurfaceFrame( |
| 235 IOSurfaceID io_surface_id, | 241 IOSurfaceID io_surface_id, |
| 236 const gfx::Size& pixel_size, | 242 const gfx::Size& pixel_size, |
| 237 float scale_factor) { | 243 float scale_factor) { |
| 238 // In the layer is replaced, keep the old one around until after the new one | 244 // In the layer is replaced, keep the old one around until after the new one |
| 239 // is installed to avoid flashes. | 245 // is installed to avoid flashes. |
| 240 base::scoped_nsobject<IOSurfaceLayer> old_io_surface_layer = | 246 base::scoped_nsobject<IOSurfaceLayer> old_io_surface_layer = |
| 241 io_surface_layer_; | 247 io_surface_layer_; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 [io_surface_layer_ setNeedsDisplayAndDisplayAndAck]; | 298 [io_surface_layer_ setNeedsDisplayAndDisplayAndAck]; |
| 293 } | 299 } |
| 294 | 300 |
| 295 // If this replacing a same-type layer, remove it now that the new layer is | 301 // If this replacing a same-type layer, remove it now that the new layer is |
| 296 // in the hierarchy. | 302 // in the hierarchy. |
| 297 if (old_io_surface_layer != io_surface_layer_) | 303 if (old_io_surface_layer != io_surface_layer_) |
| 298 DestroyIOSurfaceLayer(old_io_surface_layer); | 304 DestroyIOSurfaceLayer(old_io_surface_layer); |
| 299 | 305 |
| 300 // Remove any different-type layers that this is replacing. | 306 // Remove any different-type layers that this is replacing. |
| 301 DestroyCAContextLayer(ca_context_layer_); | 307 DestroyCAContextLayer(ca_context_layer_); |
| 308 DestroyIOSurfaceNSGLSurface(); |
| 302 DestroySoftwareLayer(); | 309 DestroySoftwareLayer(); |
| 303 io_surface_ns_gl_surface_.reset(); | |
| 304 } | 310 } |
| 305 | 311 |
| 306 void AcceleratedWidgetMac::GotSoftwareFrame(float scale_factor, | 312 void AcceleratedWidgetMac::GotSoftwareFrame(float scale_factor, |
| 307 SkCanvas* canvas) { | 313 SkCanvas* canvas) { |
| 308 if (!canvas || !view_) | 314 if (!canvas || !view_) |
| 309 return; | 315 return; |
| 310 | 316 |
| 311 // Disable the fade-in or fade-out effect if we create or remove layers. | 317 // Disable the fade-in or fade-out effect if we create or remove layers. |
| 312 ScopedCAActionDisabler disabler; | 318 ScopedCAActionDisabler disabler; |
| 313 | 319 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 324 gfx::Size pixel_size(info.width(), info.height()); | 330 gfx::Size pixel_size(info.width(), info.height()); |
| 325 [software_layer_ setContentsToData:pixels | 331 [software_layer_ setContentsToData:pixels |
| 326 withRowBytes:row_bytes | 332 withRowBytes:row_bytes |
| 327 withPixelSize:pixel_size | 333 withPixelSize:pixel_size |
| 328 withScaleFactor:scale_factor]; | 334 withScaleFactor:scale_factor]; |
| 329 last_swap_size_dip_ = gfx::ConvertSizeToDIP(scale_factor, pixel_size); | 335 last_swap_size_dip_ = gfx::ConvertSizeToDIP(scale_factor, pixel_size); |
| 330 | 336 |
| 331 // Remove any different-type layers that this is replacing. | 337 // Remove any different-type layers that this is replacing. |
| 332 DestroyCAContextLayer(ca_context_layer_); | 338 DestroyCAContextLayer(ca_context_layer_); |
| 333 DestroyIOSurfaceLayer(io_surface_layer_); | 339 DestroyIOSurfaceLayer(io_surface_layer_); |
| 340 DestroyIOSurfaceNSGLSurface(); |
| 334 } | 341 } |
| 335 | 342 |
| 336 void AcceleratedWidgetMac::DestroyCAContextLayer( | 343 void AcceleratedWidgetMac::DestroyCAContextLayer( |
| 337 base::scoped_nsobject<CALayerHost> ca_context_layer) { | 344 base::scoped_nsobject<CALayerHost> ca_context_layer) { |
| 338 if (!ca_context_layer) | 345 if (!ca_context_layer) |
| 339 return; | 346 return; |
| 340 [ca_context_layer removeFromSuperlayer]; | 347 [ca_context_layer removeFromSuperlayer]; |
| 341 if (ca_context_layer == ca_context_layer_) | 348 if (ca_context_layer == ca_context_layer_) |
| 342 ca_context_layer_.reset(); | 349 ca_context_layer_.reset(); |
| 343 } | 350 } |
| 344 | 351 |
| 345 void AcceleratedWidgetMac::DestroyIOSurfaceLayer( | 352 void AcceleratedWidgetMac::DestroyIOSurfaceLayer( |
| 346 base::scoped_nsobject<IOSurfaceLayer> io_surface_layer) { | 353 base::scoped_nsobject<IOSurfaceLayer> io_surface_layer) { |
| 347 if (!io_surface_layer) | 354 if (!io_surface_layer) |
| 348 return; | 355 return; |
| 349 [io_surface_layer resetClient]; | 356 [io_surface_layer resetClient]; |
| 350 [io_surface_layer removeFromSuperlayer]; | 357 [io_surface_layer removeFromSuperlayer]; |
| 351 if (io_surface_layer == io_surface_layer_) | 358 if (io_surface_layer == io_surface_layer_) |
| 352 io_surface_layer_.reset(); | 359 io_surface_layer_.reset(); |
| 353 } | 360 } |
| 354 | 361 |
| 362 void AcceleratedWidgetMac::DestroyIOSurfaceNSGLSurface() { |
| 363 io_surface_ns_gl_surface_.reset(); |
| 364 } |
| 365 |
| 355 void AcceleratedWidgetMac::DestroySoftwareLayer() { | 366 void AcceleratedWidgetMac::DestroySoftwareLayer() { |
| 356 if (!software_layer_) | 367 if (!software_layer_) |
| 357 return; | 368 return; |
| 358 [software_layer_ removeFromSuperlayer]; | 369 [software_layer_ removeFromSuperlayer]; |
| 359 software_layer_.reset(); | 370 software_layer_.reset(); |
| 360 } | 371 } |
| 361 | 372 |
| 362 bool AcceleratedWidgetMac::IOSurfaceLayerShouldAckImmediately() const { | 373 bool AcceleratedWidgetMac::IOSurfaceLayerShouldAckImmediately() const { |
| 363 // If there is no view then the accelerated layer is not in the view | 374 // If there is no view then the accelerated layer is not in the view |
| 364 // hierarchy and will never draw. | 375 // hierarchy and will never draw. |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 | 433 |
| 423 void AcceleratedWidgetMacGotSoftwareFrame( | 434 void AcceleratedWidgetMacGotSoftwareFrame( |
| 424 gfx::AcceleratedWidget widget, float scale_factor, SkCanvas* canvas) { | 435 gfx::AcceleratedWidget widget, float scale_factor, SkCanvas* canvas) { |
| 425 AcceleratedWidgetMac* accelerated_widget_mac = | 436 AcceleratedWidgetMac* accelerated_widget_mac = |
| 426 GetHelperFromAcceleratedWidget(widget); | 437 GetHelperFromAcceleratedWidget(widget); |
| 427 if (accelerated_widget_mac) | 438 if (accelerated_widget_mac) |
| 428 accelerated_widget_mac->GotSoftwareFrame(scale_factor, canvas); | 439 accelerated_widget_mac->GotSoftwareFrame(scale_factor, canvas); |
| 429 } | 440 } |
| 430 | 441 |
| 431 } // namespace ui | 442 } // namespace ui |
| OLD | NEW |