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

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 <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
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:CGPointMake(0, 0)];
Avi (use Gerrit) 2015/11/10 03:30:38 CGZeroPoint?
ccameron 2015/11/10 07:15:43 Done.
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)];
Avi (use Gerrit) 2015/11/10 03:30:38 You do CGColorGetConstantColor(kCGColorClear) repe
ccameron 2015/11/10 07:15:43 Yes, there's this, and I also CGColorSpaceCreateWi
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « content/common/gpu/image_transport_surface_overlay_mac.h ('k') | gpu/GLES2/extensions/CHROMIUM/CHROMIUM_schedule_ca_layer.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698