| 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> | 7 #include <CoreGraphics/CoreGraphics.h> |
| 8 #include <IOSurface/IOSurface.h> | 8 #include <IOSurface/IOSurface.h> |
| 9 #include <OpenGL/CGLRenderers.h> | 9 #include <OpenGL/CGLRenderers.h> |
| 10 #include <OpenGL/CGLTypes.h> | 10 #include <OpenGL/CGLTypes.h> |
| 11 #include <OpenGL/gl.h> | 11 #include <OpenGL/gl.h> |
| 12 #include <stddef.h> | 12 #include <stddef.h> |
| 13 | 13 |
| 14 #include <algorithm> | 14 #include <algorithm> |
| 15 | 15 |
| 16 // This type consistently causes problem on Mac, and needs to be dealt with | 16 // This type consistently causes problem on Mac, and needs to be dealt with |
| 17 // in a systemic way. | 17 // in a systemic way. |
| 18 // http://crbug.com/517208 | 18 // http://crbug.com/517208 |
| 19 #ifndef GL_OES_EGL_image | 19 #ifndef GL_OES_EGL_image |
| 20 typedef void* GLeglImageOES; | 20 typedef void* GLeglImageOES; |
| 21 #endif | 21 #endif |
| 22 | 22 |
| 23 #include "base/command_line.h" | |
| 24 #include "base/mac/scoped_cftyperef.h" | 23 #include "base/mac/scoped_cftyperef.h" |
| 25 #include "base/mac/sdk_forward_declarations.h" | 24 #include "content/common/gpu/ca_layer_partial_damage_tree_mac.h" |
| 26 #include "content/common/gpu/ca_layer_tree_mac.h" | 25 #include "content/common/gpu/ca_layer_tree_mac.h" |
| 27 #include "content/common/gpu/gpu_messages.h" | 26 #include "content/common/gpu/gpu_messages.h" |
| 28 #include "ui/accelerated_widget_mac/io_surface_context.h" | 27 #include "ui/accelerated_widget_mac/io_surface_context.h" |
| 29 #include "ui/base/cocoa/animation_utils.h" | 28 #include "ui/base/cocoa/animation_utils.h" |
| 30 #include "ui/base/cocoa/remote_layer_api.h" | 29 #include "ui/base/cocoa/remote_layer_api.h" |
| 31 #include "ui/base/ui_base_switches.h" | |
| 32 #include "ui/gfx/geometry/rect_conversions.h" | 30 #include "ui/gfx/geometry/rect_conversions.h" |
| 33 #include "ui/gfx/transform.h" | 31 #include "ui/gfx/transform.h" |
| 34 #include "ui/gl/gl_context.h" | 32 #include "ui/gl/gl_context.h" |
| 35 #include "ui/gl/gl_fence.h" | 33 #include "ui/gl/gl_fence.h" |
| 36 #include "ui/gl/gl_image_io_surface.h" | 34 #include "ui/gl/gl_image_io_surface.h" |
| 37 #include "ui/gl/gpu_switching_manager.h" | 35 #include "ui/gl/gpu_switching_manager.h" |
| 38 #include "ui/gl/scoped_api.h" | 36 #include "ui/gl/scoped_api.h" |
| 39 #include "ui/gl/scoped_cgl.h" | 37 #include "ui/gl/scoped_cgl.h" |
| 40 | 38 |
| 41 namespace { | 39 namespace { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 52 // the next frame. | 50 // the next frame. |
| 53 const double kVSyncIntervalFractionForDisplayCallback = 0.5; | 51 const double kVSyncIntervalFractionForDisplayCallback = 0.5; |
| 54 | 52 |
| 55 // If swaps arrive regularly and nearly at the vsync rate, then attempt to | 53 // If swaps arrive regularly and nearly at the vsync rate, then attempt to |
| 56 // make animation smooth (each frame is shown for one vsync interval) by sending | 54 // make animation smooth (each frame is shown for one vsync interval) by sending |
| 57 // them to the window server only when their GL work completes. If frames are | 55 // them to the window server only when their GL work completes. If frames are |
| 58 // not coming in with each vsync, then just throw them at the window server as | 56 // not coming in with each vsync, then just throw them at the window server as |
| 59 // they come. | 57 // they come. |
| 60 const double kMaximumVSyncsBetweenSwapsForSmoothAnimation = 1.5; | 58 const double kMaximumVSyncsBetweenSwapsForSmoothAnimation = 1.5; |
| 61 | 59 |
| 62 // When selecting a CALayer to re-use for partial damage, this is the maximum | |
| 63 // fraction of the merged layer's pixels that may be not-updated by the swap | |
| 64 // before we consider the CALayer to not be a good enough match, and create a | |
| 65 // new one. | |
| 66 const float kMaximumPartialDamageWasteFraction = 1.2f; | |
| 67 | |
| 68 // The maximum number of partial damage layers that may be created before we | |
| 69 // give up and remove them all (doing full damage in the process). | |
| 70 const size_t kMaximumPartialDamageLayers = 8; | |
| 71 | |
| 72 void CheckGLErrors(const char* msg) { | 60 void CheckGLErrors(const char* msg) { |
| 73 GLenum gl_error; | 61 GLenum gl_error; |
| 74 while ((gl_error = glGetError()) != GL_NO_ERROR) { | 62 while ((gl_error = glGetError()) != GL_NO_ERROR) { |
| 75 LOG(ERROR) << "OpenGL error hit " << msg << ": " << gl_error; | 63 LOG(ERROR) << "OpenGL error hit " << msg << ": " << gl_error; |
| 76 } | 64 } |
| 77 } | 65 } |
| 78 | 66 |
| 79 void IOSurfaceContextNoOp(scoped_refptr<ui::IOSurfaceContext>) { | 67 void IOSurfaceContextNoOp(scoped_refptr<ui::IOSurfaceContext>) { |
| 80 } | 68 } |
| 81 | 69 |
| 82 } // namespace | 70 } // namespace |
| 83 | 71 |
| 84 @interface CALayer(Private) | 72 @interface CALayer(Private) |
| 85 -(void)setContentsChanged; | 73 -(void)setContentsChanged; |
| 86 @end | 74 @end |
| 87 | 75 |
| 88 namespace content { | 76 namespace content { |
| 89 | 77 |
| 90 scoped_refptr<gfx::GLSurface> ImageTransportSurfaceCreateNativeSurface( | 78 scoped_refptr<gfx::GLSurface> ImageTransportSurfaceCreateNativeSurface( |
| 91 GpuChannelManager* manager, | 79 GpuChannelManager* manager, |
| 92 GpuCommandBufferStub* stub, | 80 GpuCommandBufferStub* stub, |
| 93 gfx::PluginWindowHandle handle) { | 81 gfx::PluginWindowHandle handle) { |
| 94 return new ImageTransportSurfaceOverlayMac(manager, stub, handle); | 82 return new ImageTransportSurfaceOverlayMac(manager, stub, handle); |
| 95 } | 83 } |
| 96 | 84 |
| 97 class CALayerPartialDamageTree { | |
| 98 public: | |
| 99 CALayerPartialDamageTree(bool allow_partial_swap, | |
| 100 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, | |
| 101 const gfx::Rect& pixel_frame_rect); | |
| 102 ~CALayerPartialDamageTree(); | |
| 103 | |
| 104 base::ScopedCFTypeRef<IOSurfaceRef> RootLayerIOSurface(); | |
| 105 void CommitCALayers(CALayer* superlayer, | |
| 106 scoped_ptr<CALayerPartialDamageTree> old_tree, | |
| 107 float scale_factor, | |
| 108 const gfx::Rect& pixel_damage_rect); | |
| 109 | |
| 110 private: | |
| 111 class OverlayPlane; | |
| 112 | |
| 113 void UpdateRootAndPartialDamagePlanes(CALayerPartialDamageTree* old_tree, | |
| 114 const gfx::RectF& pixel_damage_rect); | |
| 115 void UpdateRootAndPartialDamageCALayers(CALayer* superlayer, | |
| 116 float scale_factor); | |
| 117 | |
| 118 const bool allow_partial_swap_; | |
| 119 linked_ptr<OverlayPlane> root_plane_; | |
| 120 std::list<linked_ptr<OverlayPlane>> partial_damage_planes_; | |
| 121 }; | |
| 122 | |
| 123 class CALayerPartialDamageTree::OverlayPlane { | |
| 124 public: | |
| 125 static linked_ptr<OverlayPlane> CreateWithFrameRect( | |
| 126 int z_order, | |
| 127 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, | |
| 128 const gfx::RectF& pixel_frame_rect, | |
| 129 const gfx::RectF& contents_rect) { | |
| 130 gfx::Transform transform; | |
| 131 transform.Translate(pixel_frame_rect.x(), pixel_frame_rect.y()); | |
| 132 return linked_ptr<OverlayPlane>( | |
| 133 new OverlayPlane(z_order, io_surface, contents_rect, pixel_frame_rect)); | |
| 134 } | |
| 135 | |
| 136 ~OverlayPlane() { | |
| 137 [ca_layer setContents:nil]; | |
| 138 [ca_layer removeFromSuperlayer]; | |
| 139 ca_layer.reset(); | |
| 140 } | |
| 141 | |
| 142 const int z_order; | |
| 143 const base::ScopedCFTypeRef<IOSurfaceRef> io_surface; | |
| 144 const gfx::RectF contents_rect; | |
| 145 const gfx::RectF pixel_frame_rect; | |
| 146 bool layer_needs_update; | |
| 147 base::scoped_nsobject<CALayer> ca_layer; | |
| 148 | |
| 149 void TakeCALayerFrom(OverlayPlane* other_plane) { | |
| 150 ca_layer.swap(other_plane->ca_layer); | |
| 151 } | |
| 152 | |
| 153 void UpdateProperties(float scale_factor) { | |
| 154 if (layer_needs_update) { | |
| 155 [ca_layer setOpaque:YES]; | |
| 156 | |
| 157 id new_contents = static_cast<id>(io_surface.get()); | |
| 158 if ([ca_layer contents] == new_contents && z_order == 0) | |
| 159 [ca_layer setContentsChanged]; | |
| 160 else | |
| 161 [ca_layer setContents:new_contents]; | |
| 162 [ca_layer setContentsRect:contents_rect.ToCGRect()]; | |
| 163 | |
| 164 [ca_layer setAnchorPoint:CGPointZero]; | |
| 165 | |
| 166 if ([ca_layer respondsToSelector:(@selector(setContentsScale:))]) | |
| 167 [ca_layer setContentsScale:scale_factor]; | |
| 168 gfx::RectF dip_frame_rect = gfx::RectF(pixel_frame_rect); | |
| 169 dip_frame_rect.Scale(1 / scale_factor); | |
| 170 [ca_layer setBounds:CGRectMake(0, 0, dip_frame_rect.width(), | |
| 171 dip_frame_rect.height())]; | |
| 172 [ca_layer | |
| 173 setPosition:CGPointMake(dip_frame_rect.x(), dip_frame_rect.y())]; | |
| 174 } | |
| 175 static bool show_borders = | |
| 176 base::CommandLine::ForCurrentProcess()->HasSwitch( | |
| 177 switches::kShowMacOverlayBorders); | |
| 178 if (show_borders) { | |
| 179 base::ScopedCFTypeRef<CGColorRef> color; | |
| 180 if (!layer_needs_update) { | |
| 181 // Green represents contents that are unchanged across frames. | |
| 182 color.reset(CGColorCreateGenericRGB(0, 1, 0, 1)); | |
| 183 } else { | |
| 184 // Red represents damaged contents. | |
| 185 color.reset(CGColorCreateGenericRGB(1, 0, 0, 1)); | |
| 186 } | |
| 187 [ca_layer setBorderWidth:1]; | |
| 188 [ca_layer setBorderColor:color]; | |
| 189 } | |
| 190 layer_needs_update = false; | |
| 191 } | |
| 192 | |
| 193 private: | |
| 194 OverlayPlane(int z_order, | |
| 195 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, | |
| 196 const gfx::RectF& contents_rect, | |
| 197 const gfx::RectF& pixel_frame_rect) | |
| 198 : z_order(z_order), | |
| 199 io_surface(io_surface), | |
| 200 contents_rect(contents_rect), | |
| 201 pixel_frame_rect(pixel_frame_rect), | |
| 202 layer_needs_update(true) {} | |
| 203 }; | |
| 204 | |
| 205 class ImageTransportSurfaceOverlayMac::PendingSwap { | 85 class ImageTransportSurfaceOverlayMac::PendingSwap { |
| 206 public: | 86 public: |
| 207 PendingSwap() {} | 87 PendingSwap() {} |
| 208 ~PendingSwap() { DCHECK(!gl_fence); } | 88 ~PendingSwap() { DCHECK(!gl_fence); } |
| 209 | 89 |
| 210 gfx::Size pixel_size; | 90 gfx::Size pixel_size; |
| 211 float scale_factor; | 91 float scale_factor; |
| 212 gfx::Rect pixel_damage_rect; | 92 gfx::Rect pixel_damage_rect; |
| 213 | 93 |
| 214 scoped_ptr<CALayerPartialDamageTree> partial_damage_tree; | 94 scoped_ptr<CALayerPartialDamageTree> partial_damage_tree; |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 } | 314 } |
| 435 params.size = swap->pixel_size; | 315 params.size = swap->pixel_size; |
| 436 params.scale_factor = swap->scale_factor; | 316 params.scale_factor = swap->scale_factor; |
| 437 params.latency_info.swap(swap->latency_info); | 317 params.latency_info.swap(swap->latency_info); |
| 438 helper_->SendAcceleratedSurfaceBuffersSwapped(params); | 318 helper_->SendAcceleratedSurfaceBuffersSwapped(params); |
| 439 | 319 |
| 440 // Remove this from the queue, and reset any callback timers. | 320 // Remove this from the queue, and reset any callback timers. |
| 441 pending_swaps_.pop_front(); | 321 pending_swaps_.pop_front(); |
| 442 } | 322 } |
| 443 | 323 |
| 444 void CALayerPartialDamageTree::UpdateRootAndPartialDamagePlanes( | |
| 445 CALayerPartialDamageTree* old_tree, | |
| 446 const gfx::RectF& pixel_damage_rect) { | |
| 447 // This is the plane that will be updated this frame. It may be the root plane | |
| 448 // or a child plane. | |
| 449 linked_ptr<OverlayPlane> plane_for_swap; | |
| 450 | |
| 451 // If the frame's size changed, if we haven't updated the root layer, if | |
| 452 // we have full damage, or if we don't support remote layers, then use the | |
| 453 // root layer directly. | |
| 454 if (!allow_partial_swap_ || !old_tree || | |
| 455 old_tree->root_plane_->pixel_frame_rect != | |
| 456 root_plane_->pixel_frame_rect || | |
| 457 pixel_damage_rect == root_plane_->pixel_frame_rect) { | |
| 458 plane_for_swap = root_plane_; | |
| 459 } | |
| 460 | |
| 461 // Walk though the old tree's partial damage layers and see if there is one | |
| 462 // that is appropriate to re-use. | |
| 463 if (!plane_for_swap.get() && !pixel_damage_rect.IsEmpty()) { | |
| 464 gfx::RectF plane_to_reuse_dip_enlarged_rect; | |
| 465 | |
| 466 // Find the last partial damage plane to re-use the CALayer from. Grow the | |
| 467 // new rect for this layer to include this damage, and all nearby partial | |
| 468 // damage layers. | |
| 469 linked_ptr<OverlayPlane> plane_to_reuse; | |
| 470 for (auto& old_plane : old_tree->partial_damage_planes_) { | |
| 471 gfx::RectF dip_enlarged_rect = old_plane->pixel_frame_rect; | |
| 472 dip_enlarged_rect.Union(pixel_damage_rect); | |
| 473 | |
| 474 // Compute the fraction of the pixels that would not be updated by this | |
| 475 // swap. If it is too big, try another layer. | |
| 476 float waste_fraction = dip_enlarged_rect.size().GetArea() * 1.f / | |
| 477 pixel_damage_rect.size().GetArea(); | |
| 478 if (waste_fraction > kMaximumPartialDamageWasteFraction) | |
| 479 continue; | |
| 480 | |
| 481 plane_to_reuse = old_plane; | |
| 482 plane_to_reuse_dip_enlarged_rect.Union(dip_enlarged_rect); | |
| 483 } | |
| 484 | |
| 485 if (plane_to_reuse.get()) { | |
| 486 gfx::RectF enlarged_contents_rect = plane_to_reuse_dip_enlarged_rect; | |
| 487 enlarged_contents_rect.Scale(1. / root_plane_->pixel_frame_rect.width(), | |
| 488 1. / root_plane_->pixel_frame_rect.height()); | |
| 489 | |
| 490 plane_for_swap = OverlayPlane::CreateWithFrameRect( | |
| 491 0, root_plane_->io_surface, plane_to_reuse_dip_enlarged_rect, | |
| 492 enlarged_contents_rect); | |
| 493 | |
| 494 plane_for_swap->TakeCALayerFrom(plane_to_reuse.get()); | |
| 495 if (plane_to_reuse != old_tree->partial_damage_planes_.back()) | |
| 496 [plane_for_swap->ca_layer removeFromSuperlayer]; | |
| 497 } | |
| 498 } | |
| 499 | |
| 500 // If we haven't found an appropriate layer to re-use, create a new one, if | |
| 501 // we haven't already created too many. | |
| 502 if (!plane_for_swap.get() && !pixel_damage_rect.IsEmpty() && | |
| 503 old_tree->partial_damage_planes_.size() < kMaximumPartialDamageLayers) { | |
| 504 gfx::RectF contents_rect = gfx::RectF(pixel_damage_rect); | |
| 505 contents_rect.Scale(1. / root_plane_->pixel_frame_rect.width(), | |
| 506 1. / root_plane_->pixel_frame_rect.height()); | |
| 507 plane_for_swap = OverlayPlane::CreateWithFrameRect( | |
| 508 0, root_plane_->io_surface, pixel_damage_rect, contents_rect); | |
| 509 } | |
| 510 | |
| 511 // And if we still don't have a layer, use the root layer. | |
| 512 if (!plane_for_swap.get() && !pixel_damage_rect.IsEmpty()) | |
| 513 plane_for_swap = root_plane_; | |
| 514 | |
| 515 // Walk all old partial damage planes. Remove anything that is now completely | |
| 516 // covered, and move everything else into the new |partial_damage_planes_|. | |
| 517 if (old_tree) { | |
| 518 for (auto& old_plane : old_tree->partial_damage_planes_) { | |
| 519 // Intersect the planes' frames with the new root plane to ensure that | |
| 520 // they don't get kept alive inappropriately. | |
| 521 gfx::RectF old_plane_frame_rect = old_plane->pixel_frame_rect; | |
| 522 old_plane_frame_rect.Intersect(root_plane_->pixel_frame_rect); | |
| 523 | |
| 524 bool old_plane_covered_by_swap = false; | |
| 525 if (plane_for_swap.get() && | |
| 526 plane_for_swap->pixel_frame_rect.Contains(old_plane_frame_rect)) { | |
| 527 old_plane_covered_by_swap = true; | |
| 528 } | |
| 529 if (!old_plane_covered_by_swap) { | |
| 530 DCHECK(old_plane->ca_layer); | |
| 531 partial_damage_planes_.push_back(old_plane); | |
| 532 } | |
| 533 } | |
| 534 if (plane_for_swap != root_plane_) | |
| 535 root_plane_ = old_tree->root_plane_; | |
| 536 } | |
| 537 | |
| 538 // Finally, add the new swap's plane at the back of the list, if it exists. | |
| 539 if (plane_for_swap.get() && plane_for_swap != root_plane_) { | |
| 540 partial_damage_planes_.push_back(plane_for_swap); | |
| 541 } | |
| 542 } | |
| 543 | |
| 544 void CALayerPartialDamageTree::UpdateRootAndPartialDamageCALayers( | |
| 545 CALayer* superlayer, | |
| 546 float scale_factor) { | |
| 547 if (!allow_partial_swap_) { | |
| 548 DCHECK(partial_damage_planes_.empty()); | |
| 549 return; | |
| 550 } | |
| 551 | |
| 552 // Allocate and update CALayers for the backbuffer and partial damage layers. | |
| 553 if (!root_plane_->ca_layer) { | |
| 554 root_plane_->ca_layer.reset([[CALayer alloc] init]); | |
| 555 [superlayer setSublayers:nil]; | |
| 556 [superlayer addSublayer:root_plane_->ca_layer]; | |
| 557 } | |
| 558 for (auto& plane : partial_damage_planes_) { | |
| 559 if (!plane->ca_layer) { | |
| 560 DCHECK(plane == partial_damage_planes_.back()); | |
| 561 plane->ca_layer.reset([[CALayer alloc] init]); | |
| 562 } | |
| 563 if (![plane->ca_layer superlayer]) { | |
| 564 DCHECK(plane == partial_damage_planes_.back()); | |
| 565 [superlayer addSublayer:plane->ca_layer]; | |
| 566 } | |
| 567 } | |
| 568 root_plane_->UpdateProperties(scale_factor); | |
| 569 for (auto& plane : partial_damage_planes_) | |
| 570 plane->UpdateProperties(scale_factor); | |
| 571 } | |
| 572 | |
| 573 void ImageTransportSurfaceOverlayMac::DisplayAndClearAllPendingSwaps() { | 324 void ImageTransportSurfaceOverlayMac::DisplayAndClearAllPendingSwaps() { |
| 574 TRACE_EVENT0("gpu", | 325 TRACE_EVENT0("gpu", |
| 575 "ImageTransportSurfaceOverlayMac::DisplayAndClearAllPendingSwaps"); | 326 "ImageTransportSurfaceOverlayMac::DisplayAndClearAllPendingSwaps"); |
| 576 while (!pending_swaps_.empty()) | 327 while (!pending_swaps_.empty()) |
| 577 DisplayFirstPendingSwapImmediately(); | 328 DisplayFirstPendingSwapImmediately(); |
| 578 } | 329 } |
| 579 | 330 |
| 580 void ImageTransportSurfaceOverlayMac::CheckPendingSwapsCallback() { | 331 void ImageTransportSurfaceOverlayMac::CheckPendingSwapsCallback() { |
| 581 TRACE_EVENT0("gpu", | 332 TRACE_EVENT0("gpu", |
| 582 "ImageTransportSurfaceOverlayMac::CheckPendingSwapsCallback"); | 333 "ImageTransportSurfaceOverlayMac::CheckPendingSwapsCallback"); |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 758 | 509 |
| 759 // Compute the previous vsync time. | 510 // Compute the previous vsync time. |
| 760 base::TimeTicks previous_vsync = | 511 base::TimeTicks previous_vsync = |
| 761 vsync_interval_ * ((from - vsync_timebase_) / vsync_interval_) + | 512 vsync_interval_ * ((from - vsync_timebase_) / vsync_interval_) + |
| 762 vsync_timebase_; | 513 vsync_timebase_; |
| 763 | 514 |
| 764 // Return |interval_fraction| through the next vsync. | 515 // Return |interval_fraction| through the next vsync. |
| 765 return previous_vsync + (1 + interval_fraction) * vsync_interval_; | 516 return previous_vsync + (1 + interval_fraction) * vsync_interval_; |
| 766 } | 517 } |
| 767 | 518 |
| 768 CALayerPartialDamageTree::CALayerPartialDamageTree( | |
| 769 bool allow_partial_swap, | |
| 770 base::ScopedCFTypeRef<IOSurfaceRef> io_surface, | |
| 771 const gfx::Rect& pixel_frame_rect) | |
| 772 : allow_partial_swap_(allow_partial_swap) { | |
| 773 root_plane_ = OverlayPlane::CreateWithFrameRect( | |
| 774 0, io_surface, gfx::RectF(pixel_frame_rect), gfx::RectF(0, 0, 1, 1)); | |
| 775 } | |
| 776 | |
| 777 CALayerPartialDamageTree::~CALayerPartialDamageTree() {} | |
| 778 | |
| 779 base::ScopedCFTypeRef<IOSurfaceRef> | |
| 780 CALayerPartialDamageTree::RootLayerIOSurface() { | |
| 781 return root_plane_->io_surface; | |
| 782 } | |
| 783 | |
| 784 void CALayerPartialDamageTree::CommitCALayers( | |
| 785 CALayer* superlayer, | |
| 786 scoped_ptr<CALayerPartialDamageTree> old_tree, | |
| 787 float scale_factor, | |
| 788 const gfx::Rect& pixel_damage_rect) { | |
| 789 UpdateRootAndPartialDamagePlanes(old_tree.get(), | |
| 790 gfx::RectF(pixel_damage_rect)); | |
| 791 UpdateRootAndPartialDamageCALayers(superlayer, scale_factor); | |
| 792 } | |
| 793 | |
| 794 } // namespace content | 519 } // namespace content |
| OLD | NEW |