Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(157)

Side by Side Diff: content/common/gpu/image_transport_surface_overlay_mac.mm

Issue 1409193007: gpu: Add CHROMIUM_schedule_ca_layer (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Incorporate review feedback Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698