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