| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/common/gpu/image_transport_surface_overlay_mac.h" | 5 #include "content/common/gpu/image_transport_surface_overlay_mac.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <CoreGraphics/CoreGraphics.h> |
| 8 #include <IOSurface/IOSurface.h> | 9 #include <IOSurface/IOSurface.h> |
| 9 #include <OpenGL/CGLRenderers.h> | 10 #include <OpenGL/CGLRenderers.h> |
| 10 #include <OpenGL/CGLTypes.h> | 11 #include <OpenGL/CGLTypes.h> |
| 11 #include <OpenGL/gl.h> | 12 #include <OpenGL/gl.h> |
| 12 | 13 |
| 13 // This type consistently causes problem on Mac, and needs to be dealt with | 14 // This type consistently causes problem on Mac, and needs to be dealt with |
| 14 // in a systemic way. | 15 // in a systemic way. |
| 15 // http://crbug.com/517208 | 16 // http://crbug.com/517208 |
| 16 #ifndef GL_OES_EGL_image | 17 #ifndef GL_OES_EGL_image |
| 17 typedef void* GLeglImageOES; | 18 typedef void* GLeglImageOES; |
| 18 #endif | 19 #endif |
| 19 | 20 |
| 20 #include "base/command_line.h" | 21 #include "base/command_line.h" |
| 21 #include "base/mac/scoped_cftyperef.h" | 22 #include "base/mac/scoped_cftyperef.h" |
| 22 #include "content/common/gpu/gpu_messages.h" | 23 #include "content/common/gpu/gpu_messages.h" |
| 23 #include "ui/accelerated_widget_mac/io_surface_context.h" | 24 #include "ui/accelerated_widget_mac/io_surface_context.h" |
| 24 #include "ui/accelerated_widget_mac/surface_handle_types.h" | 25 #include "ui/accelerated_widget_mac/surface_handle_types.h" |
| 25 #include "ui/base/cocoa/animation_utils.h" | 26 #include "ui/base/cocoa/animation_utils.h" |
| 26 #include "ui/base/cocoa/remote_layer_api.h" | 27 #include "ui/base/cocoa/remote_layer_api.h" |
| 27 #include "ui/base/ui_base_switches.h" | 28 #include "ui/base/ui_base_switches.h" |
| 28 #include "ui/gfx/geometry/dip_util.h" | 29 #include "ui/gfx/geometry/dip_util.h" |
| 30 #include "ui/gfx/transform.h" |
| 29 #include "ui/gl/gl_context.h" | 31 #include "ui/gl/gl_context.h" |
| 30 #include "ui/gl/gl_fence.h" | 32 #include "ui/gl/gl_fence.h" |
| 31 #include "ui/gl/gl_image_io_surface.h" | 33 #include "ui/gl/gl_image_io_surface.h" |
| 32 #include "ui/gl/gpu_switching_manager.h" | 34 #include "ui/gl/gpu_switching_manager.h" |
| 33 #include "ui/gl/scoped_api.h" | 35 #include "ui/gl/scoped_api.h" |
| 34 #include "ui/gl/scoped_cgl.h" | 36 #include "ui/gl/scoped_cgl.h" |
| 35 | 37 |
| 36 namespace { | 38 namespace { |
| 37 | 39 |
| 38 // Don't let a frame draw until 5% of the way through the next vsync interval | 40 // Don't let a frame draw until 5% of the way through the next vsync interval |
| (...skipping 28 matching lines...) Expand all Loading... |
| 67 void CheckGLErrors(const char* msg) { | 69 void CheckGLErrors(const char* msg) { |
| 68 GLenum gl_error; | 70 GLenum gl_error; |
| 69 while ((gl_error = glGetError()) != GL_NO_ERROR) { | 71 while ((gl_error = glGetError()) != GL_NO_ERROR) { |
| 70 LOG(ERROR) << "OpenGL error hit " << msg << ": " << gl_error; | 72 LOG(ERROR) << "OpenGL error hit " << msg << ": " << gl_error; |
| 71 } | 73 } |
| 72 } | 74 } |
| 73 | 75 |
| 74 void IOSurfaceContextNoOp(scoped_refptr<ui::IOSurfaceContext>) { | 76 void IOSurfaceContextNoOp(scoped_refptr<ui::IOSurfaceContext>) { |
| 75 } | 77 } |
| 76 | 78 |
| 77 gfx::RectF ConvertRectToDIPF(float scale_factor, const gfx::Rect& rect) { | |
| 78 return gfx::ScaleRect(gfx::RectF(rect), 1.0f / scale_factor); | |
| 79 } | |
| 80 | |
| 81 } // namespace | 79 } // namespace |
| 82 | 80 |
| 83 @interface CALayer(Private) | 81 @interface CALayer(Private) |
| 84 -(void)setContentsChanged; | 82 -(void)setContentsChanged; |
| 85 @end | 83 @end |
| 86 | 84 |
| 87 namespace content { | 85 namespace content { |
| 88 | 86 |
| 89 scoped_refptr<gfx::GLSurface> ImageTransportSurfaceCreateNativeSurface( | 87 scoped_refptr<gfx::GLSurface> ImageTransportSurfaceCreateNativeSurface( |
| 90 GpuChannelManager* manager, | 88 GpuChannelManager* manager, |
| 91 GpuCommandBufferStub* stub, | 89 GpuCommandBufferStub* stub, |
| 92 gfx::PluginWindowHandle handle) { | 90 gfx::PluginWindowHandle handle) { |
| 93 return new ImageTransportSurfaceOverlayMac(manager, stub, handle); | 91 return new ImageTransportSurfaceOverlayMac(manager, stub, handle); |
| 94 } | 92 } |
| 95 | 93 |
| 96 class ImageTransportSurfaceOverlayMac::OverlayPlane { | 94 class ImageTransportSurfaceOverlayMac::OverlayPlane { |
| 97 public: | 95 public: |
| 98 OverlayPlane(int z_order, | 96 static linked_ptr<OverlayPlane> CreateWithFrameRect( |
| 99 int io_surface_id, | 97 int z_order, |
| 100 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, | 98 int io_surface_id, |
| 101 const gfx::RectF& dip_frame_rect, | 99 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, |
| 102 const gfx::RectF& contents_rect) | 100 const gfx::RectF& pixel_frame_rect, |
| 103 : z_order(z_order), | 101 const gfx::RectF& contents_rect) { |
| 104 io_surface_id(io_surface_id), | 102 gfx::Transform transform; |
| 105 io_surface(io_surface), | 103 transform.Translate(pixel_frame_rect.x(), pixel_frame_rect.y()); |
| 106 dip_frame_rect(dip_frame_rect), | 104 return linked_ptr<OverlayPlane>( |
| 107 contents_rect(contents_rect), | 105 new OverlayPlane(z_order, io_surface_id, io_surface, contents_rect, 1.f, |
| 108 layer_needs_update(true) {} | 106 base::ScopedCFTypeRef<CGColorRef>(), |
| 107 pixel_frame_rect.size(), transform, pixel_frame_rect)); |
| 108 } |
| 109 |
| 110 static linked_ptr<OverlayPlane> CreateWithTransform( |
| 111 int z_order, |
| 112 int io_surface_id, |
| 113 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, |
| 114 const gfx::RectF& contents_rect, |
| 115 float opacity, |
| 116 base::ScopedCFTypeRef<CGColorRef> background_color, |
| 117 const gfx::SizeF& bounds_size, |
| 118 const gfx::Transform& transform) { |
| 119 gfx::RectF pixel_frame_rect = gfx::RectF(bounds_size); |
| 120 transform.TransformRect(&pixel_frame_rect); |
| 121 return linked_ptr<OverlayPlane>(new OverlayPlane( |
| 122 z_order, io_surface_id, io_surface, contents_rect, opacity, |
| 123 background_color, bounds_size, transform, pixel_frame_rect)); |
| 124 } |
| 125 |
| 109 ~OverlayPlane() { DCHECK(!ca_layer); } | 126 ~OverlayPlane() { DCHECK(!ca_layer); } |
| 110 | 127 |
| 111 const int z_order; | 128 const int z_order; |
| 112 base::scoped_nsobject<CALayer> ca_layer; | 129 base::scoped_nsobject<CALayer> ca_layer; |
| 113 | 130 |
| 114 // The IOSurface to set the CALayer's contents to. | 131 // The IOSurface to set the CALayer's contents to. |
| 115 const int io_surface_id; | 132 const int io_surface_id; |
| 116 const base::ScopedCFTypeRef<IOSurfaceRef> io_surface; | 133 const base::ScopedCFTypeRef<IOSurfaceRef> io_surface; |
| 117 const gfx::RectF dip_frame_rect; | |
| 118 const gfx::RectF contents_rect; | 134 const gfx::RectF contents_rect; |
| 135 float opacity; |
| 136 const base::ScopedCFTypeRef<CGColorRef> background_color; |
| 137 const gfx::SizeF bounds_size; |
| 138 const gfx::Transform transform; |
| 139 |
| 140 const gfx::RectF pixel_frame_rect; |
| 119 | 141 |
| 120 bool layer_needs_update; | 142 bool layer_needs_update; |
| 121 | 143 |
| 122 static bool Compare(const linked_ptr<OverlayPlane>& a, | 144 static bool Compare(const linked_ptr<OverlayPlane>& a, |
| 123 const linked_ptr<OverlayPlane>& b) { | 145 const linked_ptr<OverlayPlane>& b) { |
| 124 return (a->z_order < b->z_order); | 146 return (a->z_order < b->z_order); |
| 125 } | 147 } |
| 126 | 148 |
| 127 void TakeCALayerFrom(OverlayPlane* other_plane) { | 149 void TakeCALayerFrom(OverlayPlane* other_plane) { |
| 128 ca_layer.swap(other_plane->ca_layer); | 150 ca_layer.swap(other_plane->ca_layer); |
| 129 } | 151 } |
| 130 | 152 |
| 131 void UpdateProperties() { | 153 void UpdateProperties() { |
| 132 if (layer_needs_update) { | 154 if (layer_needs_update) { |
| 133 [ca_layer setOpaque:YES]; | 155 [ca_layer setOpaque:YES]; |
| 134 [ca_layer setFrame:dip_frame_rect.ToCGRect()]; | 156 |
| 135 [ca_layer setContentsRect:contents_rect.ToCGRect()]; | |
| 136 id new_contents = static_cast<id>(io_surface.get()); | 157 id new_contents = static_cast<id>(io_surface.get()); |
| 137 if ([ca_layer contents] == new_contents && z_order == 0) { | 158 if ([ca_layer contents] == new_contents && z_order == 0) { |
| 138 [ca_layer setContentsChanged]; | 159 [ca_layer setContentsChanged]; |
| 139 } else { | 160 } else { |
| 140 [ca_layer setContents:new_contents]; | 161 [ca_layer setContents:new_contents]; |
| 141 } | 162 } |
| 163 [ca_layer setContentsRect:contents_rect.ToCGRect()]; |
| 164 |
| 165 [ca_layer setOpacity:opacity]; |
| 166 if (background_color) { |
| 167 [ca_layer setBackgroundColor:background_color]; |
| 168 } else { |
| 169 [ca_layer setBackgroundColor:CGColorGetConstantColor(kCGColorClear)]; |
| 170 } |
| 171 |
| 172 [ca_layer setAnchorPoint:CGPointZero]; |
| 173 [ca_layer setBounds:gfx::RectF(bounds_size).ToCGRect()]; |
| 174 CATransform3D ca_transform; |
| 175 transform.matrix().asColMajord(&ca_transform.m11); |
| 176 [ca_layer setTransform:ca_transform]; |
| 142 } | 177 } |
| 143 static bool show_borders = | 178 static bool show_borders = |
| 144 base::CommandLine::ForCurrentProcess()->HasSwitch( | 179 base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 145 switches::kShowMacOverlayBorders); | 180 switches::kShowMacOverlayBorders); |
| 146 if (show_borders) { | 181 if (show_borders) { |
| 147 base::ScopedCFTypeRef<CGColorRef> color; | 182 base::ScopedCFTypeRef<CGColorRef> color; |
| 148 if (!layer_needs_update) { | 183 if (!layer_needs_update) { |
| 149 // Green represents contents that are unchanged across frames. | 184 // Green represents contents that are unchanged across frames. |
| 150 color.reset(CGColorCreateGenericRGB(0, 1, 0, 1)); | 185 color.reset(CGColorCreateGenericRGB(0, 1, 0, 1)); |
| 151 } else if (z_order != 0) { | 186 } else if (z_order != 0) { |
| 152 // Pink represents overlay planes | 187 // Pink represents overlay planes |
| 153 color.reset(CGColorCreateGenericRGB(1, 0, 1, 1)); | 188 color.reset(CGColorCreateGenericRGB(1, 0, 1, 1)); |
| 154 } else { | 189 } else { |
| 155 // Red represents damaged contents. | 190 // Red represents damaged contents. |
| 156 color.reset(CGColorCreateGenericRGB(1, 0, 0, 1)); | 191 color.reset(CGColorCreateGenericRGB(1, 0, 0, 1)); |
| 157 } | 192 } |
| 158 [ca_layer setBorderWidth:2]; | 193 [ca_layer setBorderWidth:1]; |
| 159 [ca_layer setBorderColor:color]; | 194 [ca_layer setBorderColor:color]; |
| 160 } | 195 } |
| 161 layer_needs_update = false; | 196 layer_needs_update = false; |
| 162 } | 197 } |
| 163 | 198 |
| 164 void Destroy() { | 199 void Destroy() { |
| 165 if (!ca_layer) | 200 if (!ca_layer) |
| 166 return; | 201 return; |
| 167 [ca_layer setContents:nil]; | 202 [ca_layer setContents:nil]; |
| 168 [ca_layer removeFromSuperlayer]; | 203 [ca_layer removeFromSuperlayer]; |
| 204 [ca_layer setBorderWidth:0]; |
| 205 [ca_layer setBorderColor:CGColorGetConstantColor(kCGColorClear)]; |
| 206 [ca_layer setBackgroundColor:CGColorGetConstantColor(kCGColorClear)]; |
| 169 ca_layer.reset(); | 207 ca_layer.reset(); |
| 170 } | 208 } |
| 209 |
| 210 private: |
| 211 OverlayPlane(int z_order, |
| 212 int io_surface_id, |
| 213 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, |
| 214 const gfx::RectF& contents_rect, |
| 215 float opacity, |
| 216 base::ScopedCFTypeRef<CGColorRef> background_color, |
| 217 const gfx::SizeF& bounds_size, |
| 218 const gfx::Transform& transform, |
| 219 const gfx::RectF& pixel_frame_rect) |
| 220 : z_order(z_order), |
| 221 io_surface_id(io_surface_id), |
| 222 io_surface(io_surface), |
| 223 contents_rect(contents_rect), |
| 224 opacity(opacity), |
| 225 background_color(background_color), |
| 226 bounds_size(bounds_size), |
| 227 transform(transform), |
| 228 pixel_frame_rect(pixel_frame_rect), |
| 229 layer_needs_update(true) {} |
| 171 }; | 230 }; |
| 172 | 231 |
| 173 class ImageTransportSurfaceOverlayMac::PendingSwap { | 232 class ImageTransportSurfaceOverlayMac::PendingSwap { |
| 174 public: | 233 public: |
| 175 PendingSwap() {} | 234 PendingSwap() {} |
| 176 ~PendingSwap() { DCHECK(!gl_fence); } | 235 ~PendingSwap() { DCHECK(!gl_fence); } |
| 177 | 236 |
| 178 gfx::Size pixel_size; | 237 gfx::Size pixel_size; |
| 179 float scale_factor; | 238 float scale_factor; |
| 180 gfx::Rect pixel_damage_rect; | 239 gfx::Rect pixel_damage_rect; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 198 }; | 257 }; |
| 199 | 258 |
| 200 ImageTransportSurfaceOverlayMac::ImageTransportSurfaceOverlayMac( | 259 ImageTransportSurfaceOverlayMac::ImageTransportSurfaceOverlayMac( |
| 201 GpuChannelManager* manager, | 260 GpuChannelManager* manager, |
| 202 GpuCommandBufferStub* stub, | 261 GpuCommandBufferStub* stub, |
| 203 gfx::PluginWindowHandle handle) | 262 gfx::PluginWindowHandle handle) |
| 204 : use_remote_layer_api_(ui::RemoteLayerAPISupported()), | 263 : use_remote_layer_api_(ui::RemoteLayerAPISupported()), |
| 205 scale_factor_(1), | 264 scale_factor_(1), |
| 206 gl_renderer_id_(0), | 265 gl_renderer_id_(0), |
| 207 vsync_parameters_valid_(false), | 266 vsync_parameters_valid_(false), |
| 267 next_ca_layer_z_order_(1), |
| 208 display_pending_swap_timer_(true, false), | 268 display_pending_swap_timer_(true, false), |
| 209 weak_factory_(this) { | 269 weak_factory_(this) { |
| 210 helper_.reset(new ImageTransportHelper(this, manager, stub, handle)); | 270 helper_.reset(new ImageTransportHelper(this, manager, stub, handle)); |
| 211 ui::GpuSwitchingManager::GetInstance()->AddObserver(this); | 271 ui::GpuSwitchingManager::GetInstance()->AddObserver(this); |
| 212 } | 272 } |
| 213 | 273 |
| 214 ImageTransportSurfaceOverlayMac::~ImageTransportSurfaceOverlayMac() { | 274 ImageTransportSurfaceOverlayMac::~ImageTransportSurfaceOverlayMac() { |
| 215 ui::GpuSwitchingManager::GetInstance()->RemoveObserver(this); | 275 ui::GpuSwitchingManager::GetInstance()->RemoveObserver(this); |
| 216 Destroy(); | 276 Destroy(); |
| 217 } | 277 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 248 current_overlay_planes_.clear(); | 308 current_overlay_planes_.clear(); |
| 249 } | 309 } |
| 250 | 310 |
| 251 bool ImageTransportSurfaceOverlayMac::IsOffscreen() { | 311 bool ImageTransportSurfaceOverlayMac::IsOffscreen() { |
| 252 return false; | 312 return false; |
| 253 } | 313 } |
| 254 | 314 |
| 255 gfx::SwapResult ImageTransportSurfaceOverlayMac::SwapBuffersInternal( | 315 gfx::SwapResult ImageTransportSurfaceOverlayMac::SwapBuffersInternal( |
| 256 const gfx::Rect& pixel_damage_rect) { | 316 const gfx::Rect& pixel_damage_rect) { |
| 257 TRACE_EVENT0("gpu", "ImageTransportSurfaceOverlayMac::SwapBuffersInternal"); | 317 TRACE_EVENT0("gpu", "ImageTransportSurfaceOverlayMac::SwapBuffersInternal"); |
| 318 next_ca_layer_z_order_ = 1; |
| 258 | 319 |
| 259 // Use the same concept of 'now' for the entire function. The duration of | 320 // Use the same concept of 'now' for the entire function. The duration of |
| 260 // this function only affect the result if this function lasts across a vsync | 321 // this function only affect the result if this function lasts across a vsync |
| 261 // boundary, in which case smooth animation is out the window anyway. | 322 // boundary, in which case smooth animation is out the window anyway. |
| 262 const base::TimeTicks now = base::TimeTicks::Now(); | 323 const base::TimeTicks now = base::TimeTicks::Now(); |
| 263 | 324 |
| 264 // Decide if the frame should be drawn immediately, or if we should wait until | 325 // Decide if the frame should be drawn immediately, or if we should wait until |
| 265 // its work finishes before drawing immediately. | 326 // its work finishes before drawing immediately. |
| 266 bool display_immediately = false; | 327 bool display_immediately = false; |
| 267 if (vsync_parameters_valid_ && | 328 if (vsync_parameters_valid_ && |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 | 424 |
| 364 CheckGLErrors("before deleting active fence"); | 425 CheckGLErrors("before deleting active fence"); |
| 365 swap->gl_fence.reset(); | 426 swap->gl_fence.reset(); |
| 366 CheckGLErrors("while deleting active fence"); | 427 CheckGLErrors("while deleting active fence"); |
| 367 } | 428 } |
| 368 | 429 |
| 369 // Update the plane lists. | 430 // Update the plane lists. |
| 370 { | 431 { |
| 371 // Sort the input planes by z-index, and remove any overlays from the | 432 // Sort the input planes by z-index, and remove any overlays from the |
| 372 // damage rect. | 433 // damage rect. |
| 373 gfx::RectF dip_damage_rect = ConvertRectToDIPF( | 434 gfx::RectF pixel_damage_rect = gfx::RectF(swap->pixel_damage_rect); |
| 374 swap->scale_factor, swap->pixel_damage_rect); | |
| 375 std::sort(swap->overlay_planes.begin(), swap->overlay_planes.end(), | 435 std::sort(swap->overlay_planes.begin(), swap->overlay_planes.end(), |
| 376 OverlayPlane::Compare); | 436 OverlayPlane::Compare); |
| 377 for (auto& plane : swap->overlay_planes) | 437 for (auto& plane : swap->overlay_planes) |
| 378 dip_damage_rect.Subtract(plane->dip_frame_rect); | 438 pixel_damage_rect.Subtract(plane->pixel_frame_rect); |
| 379 | 439 |
| 380 ScopedCAActionDisabler disabler; | 440 ScopedCAActionDisabler disabler; |
| 381 UpdateRootAndPartialDamagePlanes(swap->root_plane, dip_damage_rect); | 441 UpdateRootAndPartialDamagePlanes(swap->root_plane, pixel_damage_rect); |
| 382 UpdateOverlayPlanes(swap->overlay_planes); | 442 UpdateOverlayPlanes(swap->overlay_planes); |
| 383 UpdateCALayerTree(); | 443 UpdateCALayerTree(); |
| 384 swap->overlay_planes.clear(); | 444 swap->overlay_planes.clear(); |
| 385 } | 445 } |
| 386 | 446 |
| 387 // Update the latency info to reflect the swap time. | 447 // Update the latency info to reflect the swap time. |
| 388 base::TimeTicks swap_time = base::TimeTicks::Now(); | 448 base::TimeTicks swap_time = base::TimeTicks::Now(); |
| 389 for (auto latency_info : swap->latency_info) { | 449 for (auto latency_info : swap->latency_info) { |
| 390 latency_info.AddLatencyNumberWithTimestamp( | 450 latency_info.AddLatencyNumberWithTimestamp( |
| 391 ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, 0, swap_time, 1); | 451 ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, 0, swap_time, 1); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 428 } | 488 } |
| 429 | 489 |
| 430 // Destroy any of the previous |current_overlay_planes_| that we couldn't | 490 // Destroy any of the previous |current_overlay_planes_| that we couldn't |
| 431 // cannibalize. | 491 // cannibalize. |
| 432 for (auto& old_plane : old_overlay_planes) | 492 for (auto& old_plane : old_overlay_planes) |
| 433 old_plane->Destroy(); | 493 old_plane->Destroy(); |
| 434 } | 494 } |
| 435 | 495 |
| 436 void ImageTransportSurfaceOverlayMac::UpdateRootAndPartialDamagePlanes( | 496 void ImageTransportSurfaceOverlayMac::UpdateRootAndPartialDamagePlanes( |
| 437 const linked_ptr<OverlayPlane>& new_root_plane, | 497 const linked_ptr<OverlayPlane>& new_root_plane, |
| 438 const gfx::RectF& dip_damage_rect) { | 498 const gfx::RectF& pixel_damage_rect) { |
| 439 std::list<linked_ptr<OverlayPlane>> old_partial_damage_planes; | 499 std::list<linked_ptr<OverlayPlane>> old_partial_damage_planes; |
| 440 old_partial_damage_planes.swap(current_partial_damage_planes_); | 500 old_partial_damage_planes.swap(current_partial_damage_planes_); |
| 441 linked_ptr<OverlayPlane> plane_for_swap; | 501 linked_ptr<OverlayPlane> plane_for_swap; |
| 442 | 502 |
| 443 // If there is no new root plane, destroy the old one. | 503 // If there is no new root plane, destroy the old one. |
| 444 if (!new_root_plane.get()) { | 504 if (!new_root_plane.get()) { |
| 445 for (auto& old_plane : old_partial_damage_planes) | 505 for (auto& old_plane : old_partial_damage_planes) |
| 446 old_plane->Destroy(); | 506 old_plane->Destroy(); |
| 447 if (current_root_plane_.get()) | 507 if (current_root_plane_.get()) |
| 448 current_root_plane_->Destroy(); | 508 current_root_plane_->Destroy(); |
| 449 current_root_plane_.reset(); | 509 current_root_plane_.reset(); |
| 450 return; | 510 return; |
| 451 } | 511 } |
| 452 | 512 |
| 453 // If the frame's size changed, if we haven't updated the root layer, if | 513 // If the frame's size changed, if we haven't updated the root layer, if |
| 454 // we have full damage, or if we don't support remote layers, then use the | 514 // we have full damage, or if we don't support remote layers, then use the |
| 455 // root layer directly. | 515 // root layer directly. |
| 456 if (!use_remote_layer_api_ || !current_root_plane_.get() || | 516 if (!use_remote_layer_api_ || !current_root_plane_.get() || |
| 457 current_root_plane_->dip_frame_rect != new_root_plane->dip_frame_rect || | 517 current_root_plane_->pixel_frame_rect != |
| 458 dip_damage_rect == new_root_plane->dip_frame_rect) { | 518 new_root_plane->pixel_frame_rect || |
| 519 pixel_damage_rect == new_root_plane->pixel_frame_rect) { |
| 459 plane_for_swap = new_root_plane; | 520 plane_for_swap = new_root_plane; |
| 460 } | 521 } |
| 461 | 522 |
| 462 // Walk though the existing partial damage layers and see if there is one that | 523 // Walk though the existing partial damage layers and see if there is one that |
| 463 // is appropriate to re-use. | 524 // is appropriate to re-use. |
| 464 if (!plane_for_swap.get() && !dip_damage_rect.IsEmpty()) { | 525 if (!plane_for_swap.get() && !pixel_damage_rect.IsEmpty()) { |
| 465 gfx::RectF plane_to_reuse_dip_enlarged_rect; | 526 gfx::RectF plane_to_reuse_dip_enlarged_rect; |
| 466 | 527 |
| 467 // Find the last partial damage plane to re-use the CALayer from. Grow the | 528 // Find the last partial damage plane to re-use the CALayer from. Grow the |
| 468 // new rect for this layer to include this damage, and all nearby partial | 529 // new rect for this layer to include this damage, and all nearby partial |
| 469 // damage layers. | 530 // damage layers. |
| 470 linked_ptr<OverlayPlane> plane_to_reuse; | 531 linked_ptr<OverlayPlane> plane_to_reuse; |
| 471 for (auto& old_plane : old_partial_damage_planes) { | 532 for (auto& old_plane : old_partial_damage_planes) { |
| 472 gfx::RectF dip_enlarged_rect = old_plane->dip_frame_rect; | 533 gfx::RectF dip_enlarged_rect = old_plane->pixel_frame_rect; |
| 473 dip_enlarged_rect.Union(dip_damage_rect); | 534 dip_enlarged_rect.Union(pixel_damage_rect); |
| 474 | 535 |
| 475 // Compute the fraction of the pixels that would not be updated by this | 536 // Compute the fraction of the pixels that would not be updated by this |
| 476 // swap. If it is too big, try another layer. | 537 // swap. If it is too big, try another layer. |
| 477 float waste_fraction = dip_enlarged_rect.size().GetArea() * 1.f / | 538 float waste_fraction = dip_enlarged_rect.size().GetArea() * 1.f / |
| 478 dip_damage_rect.size().GetArea(); | 539 pixel_damage_rect.size().GetArea(); |
| 479 if (waste_fraction > kMaximumPartialDamageWasteFraction) | 540 if (waste_fraction > kMaximumPartialDamageWasteFraction) |
| 480 continue; | 541 continue; |
| 481 | 542 |
| 482 plane_to_reuse = old_plane; | 543 plane_to_reuse = old_plane; |
| 483 plane_to_reuse_dip_enlarged_rect.Union(dip_enlarged_rect); | 544 plane_to_reuse_dip_enlarged_rect.Union(dip_enlarged_rect); |
| 484 } | 545 } |
| 485 | 546 |
| 486 if (plane_to_reuse.get()) { | 547 if (plane_to_reuse.get()) { |
| 487 gfx::RectF enlarged_contents_rect = plane_to_reuse_dip_enlarged_rect; | 548 gfx::RectF enlarged_contents_rect = plane_to_reuse_dip_enlarged_rect; |
| 488 enlarged_contents_rect.Scale( | 549 enlarged_contents_rect.Scale( |
| 489 1. / new_root_plane->dip_frame_rect.width(), | 550 1. / new_root_plane->pixel_frame_rect.width(), |
| 490 1. / new_root_plane->dip_frame_rect.height()); | 551 1. / new_root_plane->pixel_frame_rect.height()); |
| 491 | 552 |
| 492 plane_for_swap = linked_ptr<OverlayPlane>(new OverlayPlane( | 553 plane_for_swap = OverlayPlane::CreateWithFrameRect( |
| 493 0, new_root_plane->io_surface_id, new_root_plane->io_surface, | 554 0, new_root_plane->io_surface_id, new_root_plane->io_surface, |
| 494 plane_to_reuse_dip_enlarged_rect, enlarged_contents_rect)); | 555 plane_to_reuse_dip_enlarged_rect, enlarged_contents_rect); |
| 495 | 556 |
| 496 plane_for_swap->TakeCALayerFrom(plane_to_reuse.get()); | 557 plane_for_swap->TakeCALayerFrom(plane_to_reuse.get()); |
| 497 if (plane_to_reuse != old_partial_damage_planes.back()) | 558 if (plane_to_reuse != old_partial_damage_planes.back()) |
| 498 [plane_for_swap->ca_layer removeFromSuperlayer]; | 559 [plane_for_swap->ca_layer removeFromSuperlayer]; |
| 499 } | 560 } |
| 500 } | 561 } |
| 501 | 562 |
| 502 // If we haven't found an appropriate layer to re-use, create a new one, if | 563 // If we haven't found an appropriate layer to re-use, create a new one, if |
| 503 // we haven't already created too many. | 564 // we haven't already created too many. |
| 504 if (!plane_for_swap.get() && !dip_damage_rect.IsEmpty() && | 565 if (!plane_for_swap.get() && !pixel_damage_rect.IsEmpty() && |
| 505 old_partial_damage_planes.size() < kMaximumPartialDamageLayers) { | 566 old_partial_damage_planes.size() < kMaximumPartialDamageLayers) { |
| 506 gfx::RectF contents_rect = gfx::RectF(dip_damage_rect); | 567 gfx::RectF contents_rect = gfx::RectF(pixel_damage_rect); |
| 507 contents_rect.Scale(1. / new_root_plane->dip_frame_rect.width(), | 568 contents_rect.Scale(1. / new_root_plane->pixel_frame_rect.width(), |
| 508 1. / new_root_plane->dip_frame_rect.height()); | 569 1. / new_root_plane->pixel_frame_rect.height()); |
| 509 plane_for_swap = linked_ptr<OverlayPlane>(new OverlayPlane( | 570 plane_for_swap = OverlayPlane::CreateWithFrameRect( |
| 510 0, new_root_plane->io_surface_id, new_root_plane->io_surface, | 571 0, new_root_plane->io_surface_id, new_root_plane->io_surface, |
| 511 dip_damage_rect, contents_rect)); | 572 pixel_damage_rect, contents_rect); |
| 512 } | 573 } |
| 513 | 574 |
| 514 // And if we still don't have a layer, use the root layer. | 575 // And if we still don't have a layer, use the root layer. |
| 515 if (!plane_for_swap.get() && !dip_damage_rect.IsEmpty()) | 576 if (!plane_for_swap.get() && !pixel_damage_rect.IsEmpty()) |
| 516 plane_for_swap = new_root_plane; | 577 plane_for_swap = new_root_plane; |
| 517 | 578 |
| 518 // Walk all old partial damage planes. Remove anything that is now completely | 579 // Walk all old partial damage planes. Remove anything that is now completely |
| 519 // covered, and move everything else into the new | 580 // covered, and move everything else into the new |
| 520 // |current_partial_damage_planes_|. | 581 // |current_partial_damage_planes_|. |
| 521 for (auto& old_plane : old_partial_damage_planes) { | 582 for (auto& old_plane : old_partial_damage_planes) { |
| 522 // Intersect the planes' frames with the new root plane to ensure that | 583 // Intersect the planes' frames with the new root plane to ensure that |
| 523 // they don't get kept alive inappropriately. | 584 // they don't get kept alive inappropriately. |
| 524 gfx::RectF old_plane_frame_rect = old_plane->dip_frame_rect; | 585 gfx::RectF old_plane_frame_rect = old_plane->pixel_frame_rect; |
| 525 old_plane_frame_rect.Intersect(new_root_plane->dip_frame_rect); | 586 old_plane_frame_rect.Intersect(new_root_plane->pixel_frame_rect); |
| 526 | 587 |
| 527 if (plane_for_swap.get() && | 588 if (plane_for_swap.get() && |
| 528 plane_for_swap->dip_frame_rect.Contains(old_plane_frame_rect)) { | 589 plane_for_swap->pixel_frame_rect.Contains(old_plane_frame_rect)) { |
| 529 old_plane->Destroy(); | 590 old_plane->Destroy(); |
| 530 } else { | 591 } else { |
| 531 DCHECK(old_plane->ca_layer); | 592 DCHECK(old_plane->ca_layer); |
| 532 current_partial_damage_planes_.push_back(old_plane); | 593 current_partial_damage_planes_.push_back(old_plane); |
| 533 } | 594 } |
| 534 } | 595 } |
| 535 | 596 |
| 536 // Finally, add the new swap's plane at the back of the list, if it exists. | 597 // Finally, add the new swap's plane at the back of the list, if it exists. |
| 537 if (plane_for_swap == new_root_plane) { | 598 if (plane_for_swap == new_root_plane) { |
| 538 if (current_root_plane_.get()) { | 599 if (current_root_plane_.get()) { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 581 } | 642 } |
| 582 } | 643 } |
| 583 | 644 |
| 584 // Update CALayer contents, frames, and borders. | 645 // Update CALayer contents, frames, and borders. |
| 585 if (current_root_plane_.get()) | 646 if (current_root_plane_.get()) |
| 586 current_root_plane_->UpdateProperties(); | 647 current_root_plane_->UpdateProperties(); |
| 587 for (auto& plane : current_partial_damage_planes_) | 648 for (auto& plane : current_partial_damage_planes_) |
| 588 plane->UpdateProperties(); | 649 plane->UpdateProperties(); |
| 589 for (auto& plane : current_overlay_planes_) | 650 for (auto& plane : current_overlay_planes_) |
| 590 plane->UpdateProperties(); | 651 plane->UpdateProperties(); |
| 652 [ca_root_layer_ setTransform:CATransform3DMakeScale(1 / scale_factor_, |
| 653 1 / scale_factor_, 1)]; |
| 591 | 654 |
| 592 DCHECK_EQ( | 655 DCHECK_EQ( |
| 593 static_cast<size_t>([[ca_root_layer_ sublayers] count]), | 656 static_cast<size_t>([[ca_root_layer_ sublayers] count]), |
| 594 current_partial_damage_planes_.size() + current_overlay_planes_.size()); | 657 current_partial_damage_planes_.size() + current_overlay_planes_.size()); |
| 595 } | 658 } |
| 596 | 659 |
| 597 void ImageTransportSurfaceOverlayMac::DisplayAndClearAllPendingSwaps() { | 660 void ImageTransportSurfaceOverlayMac::DisplayAndClearAllPendingSwaps() { |
| 598 TRACE_EVENT0("gpu", | 661 TRACE_EVENT0("gpu", |
| 599 "ImageTransportSurfaceOverlayMac::DisplayAndClearAllPendingSwaps"); | 662 "ImageTransportSurfaceOverlayMac::DisplayAndClearAllPendingSwaps"); |
| 600 while (!pending_swaps_.empty()) | 663 while (!pending_swaps_.empty()) |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 667 DisplayAndClearAllPendingSwaps(); | 730 DisplayAndClearAllPendingSwaps(); |
| 668 last_swap_time_ = base::TimeTicks(); | 731 last_swap_time_ = base::TimeTicks(); |
| 669 } | 732 } |
| 670 return true; | 733 return true; |
| 671 } | 734 } |
| 672 | 735 |
| 673 bool ImageTransportSurfaceOverlayMac::ScheduleOverlayPlane( | 736 bool ImageTransportSurfaceOverlayMac::ScheduleOverlayPlane( |
| 674 int z_order, | 737 int z_order, |
| 675 gfx::OverlayTransform transform, | 738 gfx::OverlayTransform transform, |
| 676 gl::GLImage* image, | 739 gl::GLImage* image, |
| 677 const gfx::Rect& bounds_rect, | 740 const gfx::Rect& pixel_frame_rect, |
| 678 const gfx::RectF& crop_rect) { | 741 const gfx::RectF& crop_rect) { |
| 679 DCHECK_EQ(transform, gfx::OVERLAY_TRANSFORM_NONE); | 742 DCHECK_EQ(transform, gfx::OVERLAY_TRANSFORM_NONE); |
| 680 if (transform != gfx::OVERLAY_TRANSFORM_NONE) | 743 if (transform != gfx::OVERLAY_TRANSFORM_NONE) |
| 681 return false; | 744 return false; |
| 682 | 745 |
| 683 linked_ptr<OverlayPlane> plane(new OverlayPlane( | 746 linked_ptr<OverlayPlane> plane = OverlayPlane::CreateWithFrameRect( |
| 684 z_order, static_cast<gl::GLImageIOSurface*>(image)->io_surface_id().id, | 747 z_order, static_cast<gl::GLImageIOSurface*>(image)->io_surface_id().id, |
| 685 static_cast<gl::GLImageIOSurface*>(image)->io_surface(), | 748 static_cast<gl::GLImageIOSurface*>(image)->io_surface(), |
| 686 ConvertRectToDIPF(scale_factor_, bounds_rect), crop_rect)); | 749 gfx::RectF(pixel_frame_rect), crop_rect); |
| 687 if (z_order == 0) | 750 if (z_order == 0) |
| 688 pending_root_plane_ = plane; | 751 pending_root_plane_ = plane; |
| 689 else | 752 else |
| 690 pending_overlay_planes_.push_back(plane); | 753 pending_overlay_planes_.push_back(plane); |
| 691 | 754 |
| 692 return true; | 755 return true; |
| 693 } | 756 } |
| 694 | 757 |
| 758 bool ImageTransportSurfaceOverlayMac::ScheduleCALayer( |
| 759 gl::GLImage* contents_image, |
| 760 const gfx::RectF& contents_rect, |
| 761 float opacity, |
| 762 unsigned background_color, |
| 763 const gfx::SizeF& bounds_size, |
| 764 const gfx::Transform& transform) { |
| 765 // Extract the IOSurface, if this layer is not just a solid color. |
| 766 int io_surface_id = 0; |
| 767 base::ScopedCFTypeRef<IOSurfaceRef> io_surface; |
| 768 if (contents_image) { |
| 769 io_surface_id = |
| 770 static_cast<gl::GLImageIOSurface*>(contents_image)->io_surface_id().id; |
| 771 io_surface = |
| 772 static_cast<gl::GLImageIOSurface*>(contents_image)->io_surface(); |
| 773 } |
| 774 |
| 775 // Convert the RGBA SkColor to an sRGB CGColorRef. |
| 776 CGFloat rgba_color_components[4] = { |
| 777 SkColorGetR(background_color) / 255., |
| 778 SkColorGetG(background_color) / 255., |
| 779 SkColorGetB(background_color) / 255., |
| 780 SkColorGetA(background_color) / 255., |
| 781 }; |
| 782 base::ScopedCFTypeRef<CGColorRef> srgb_background_color(CGColorCreate( |
| 783 CGColorSpaceCreateWithName(kCGColorSpaceSRGB), rgba_color_components)); |
| 784 |
| 785 pending_overlay_planes_.push_back(OverlayPlane::CreateWithTransform( |
| 786 next_ca_layer_z_order_++, io_surface_id, io_surface, contents_rect, |
| 787 opacity, srgb_background_color, bounds_size, transform)); |
| 788 return true; |
| 789 } |
| 790 |
| 695 bool ImageTransportSurfaceOverlayMac::IsSurfaceless() const { | 791 bool ImageTransportSurfaceOverlayMac::IsSurfaceless() const { |
| 696 return true; | 792 return true; |
| 697 } | 793 } |
| 698 | 794 |
| 699 void ImageTransportSurfaceOverlayMac::OnBufferPresented( | 795 void ImageTransportSurfaceOverlayMac::OnBufferPresented( |
| 700 const AcceleratedSurfaceMsg_BufferPresented_Params& params) { | 796 const AcceleratedSurfaceMsg_BufferPresented_Params& params) { |
| 701 vsync_timebase_ = params.vsync_timebase; | 797 vsync_timebase_ = params.vsync_timebase; |
| 702 vsync_interval_ = params.vsync_interval; | 798 vsync_interval_ = params.vsync_interval; |
| 703 vsync_parameters_valid_ = (vsync_interval_ != base::TimeDelta()); | 799 vsync_parameters_valid_ = (vsync_interval_ != base::TimeDelta()); |
| 704 | 800 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 755 // Compute the previous vsync time. | 851 // Compute the previous vsync time. |
| 756 base::TimeTicks previous_vsync = | 852 base::TimeTicks previous_vsync = |
| 757 vsync_interval_ * ((from - vsync_timebase_) / vsync_interval_) + | 853 vsync_interval_ * ((from - vsync_timebase_) / vsync_interval_) + |
| 758 vsync_timebase_; | 854 vsync_timebase_; |
| 759 | 855 |
| 760 // Return |interval_fraction| through the next vsync. | 856 // Return |interval_fraction| through the next vsync. |
| 761 return previous_vsync + (1 + interval_fraction) * vsync_interval_; | 857 return previous_vsync + (1 + interval_fraction) * vsync_interval_; |
| 762 } | 858 } |
| 763 | 859 |
| 764 } // namespace content | 860 } // namespace content |
| OLD | NEW |