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

Unified Diff: content/common/gpu/image_transport_surface_overlay_mac.mm

Issue 1271123002: Mac: Enable partial swap (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 4 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/common/gpu/image_transport_surface_overlay_mac.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/common/gpu/image_transport_surface_overlay_mac.mm
diff --git a/content/common/gpu/image_transport_surface_overlay_mac.mm b/content/common/gpu/image_transport_surface_overlay_mac.mm
index c9fbe56e67e952a2bbe859d677470fcb4f024d04..b9ac795cc772bd9d51c0ef334567edeba8acbaea 100644
--- a/content/common/gpu/image_transport_surface_overlay_mac.mm
+++ b/content/common/gpu/image_transport_surface_overlay_mac.mm
@@ -24,6 +24,10 @@
} \
} while (0)
+@interface CALayer(Private)
+-(void) setContentsChanged;
Andre 2015/08/05 17:59:30 - (void)set...
ccameron 2015/08/06 18:55:18 Done.
+@end
+
namespace content {
ImageTransportSurfaceOverlayMac::ImageTransportSurfaceOverlayMac(
@@ -48,6 +52,7 @@ bool ImageTransportSurfaceOverlayMac::Initialize() {
[[CAContext contextWithCGSConnection:connection_id options:@{}] retain]);
layer_.reset([[CALayer alloc] init]);
[layer_ setGeometryFlipped:YES];
+ partial_damage_layer_.reset([[CALayer alloc] init]);
[ca_context_ setLayer:layer_];
return true;
@@ -93,9 +98,39 @@ gfx::SwapResult ImageTransportSurfaceOverlayMac::SwapBuffersInternal(
LOG_GL_ERRORS("while flushing frame");
}
- this_swap.dip_size = gfx::ConvertSizeToDIP(scale_factor_, pixel_size_);
- pending_swaps_.push_back(this_swap);
+ // Determine if this will be a full or partial damage, and compute the rects
+ // for the damage.
+ {
+ this_swap.dip_size = gfx::ConvertSizeToDIP(scale_factor_, pixel_size_);
+
+ // Grow the partial damage rect to include the new damage.
+ accumulated_partial_damage_pixel_rect_.Union(pixel_damage_rect);
+ // Compute the fraction of the full layer that has been damaged. If this
+ // fraction is very large (>85%), just damage the full layer, and don't
+ // bother with the partial layer.
+ double kMaximumFractionOfFullDamage = 0.85;
Andre 2015/08/05 17:59:30 nit: const
ccameron 2015/08/06 18:55:18 Done.
+ double fraction_of_full_damage =
Andre 2015/08/05 17:59:30 nit: const
ccameron 2015/08/06 18:55:18 Done.
+ accumulated_partial_damage_pixel_rect_.size().GetArea() /
+ static_cast<double>(pixel_size_.GetArea());
+ // Compute the fraction of the accumulated partial damage rect that has been
+ // damaged. If this gets too small (<75%), just re-damage the full window,
+ // so we can re-create a smaller partial damage layer next frame.
+ double kMinimumFractionOfPartialDamage = 0.75;
+ double fraction_of_partial_damage =
+ pixel_damage_rect.size().GetArea() / static_cast<double>(
+ accumulated_partial_damage_pixel_rect_.size().GetArea());
+ if (fraction_of_full_damage < kMaximumFractionOfFullDamage &&
+ fraction_of_partial_damage > kMinimumFractionOfPartialDamage) {
+ this_swap.use_partial_damage = true;
+ this_swap.dip_partial_damage_rect = gfx::ConvertRectToDIP(
+ scale_factor_, accumulated_partial_damage_pixel_rect_);
+ } else {
+ this_swap.use_partial_damage = false;
+ accumulated_partial_damage_pixel_rect_ = gfx::Rect();
+ }
+ }
+ pending_swaps_.push_back(this_swap);
PostCheckAndDisplayPendingSwaps();
return gfx::SwapResult::SWAP_ACK;
}
@@ -131,9 +166,39 @@ void ImageTransportSurfaceOverlayMac::CheckAndDisplayPendingSwaps(
TRACE_EVENT1("gpu", "ImageTransportSurfaceOverlayMac::setContents",
"surface", this_swap.io_surface.get());
ScopedCAActionDisabler disabler;
- id new_contents = static_cast<id>(this_swap.io_surface.get());
- [layer_ setContents:new_contents];
- [layer_ setFrame:gfx::Rect(this_swap.dip_size).ToCGRect()];
+ if (this_swap.use_partial_damage) {
+ if (![partial_damage_layer_ superlayer])
+ [layer_ addSublayer:partial_damage_layer_];
+
+ [partial_damage_layer_
+ setContents:static_cast<id>(this_swap.io_surface.get())];
+ [partial_damage_layer_
+ setFrame:this_swap.dip_partial_damage_rect.ToCGRect()];
+ gfx::RectF content_bounds_rect =
+ gfx::RectF(this_swap.dip_partial_damage_rect);
+ content_bounds_rect.Scale(
+ 1. / this_swap.dip_size.width(), 1. / this_swap.dip_size.height());
+ [partial_damage_layer_ setContentsRect:CGRectMake(
+ content_bounds_rect.x(),
+ content_bounds_rect.y(),
+ content_bounds_rect.width(),
+ content_bounds_rect.height())];
Andre 2015/08/05 17:59:30 How about something like: CGRect damage_rect = thi
ccameron 2015/08/06 18:55:18 Actually, gfx::RectF should have a ToCGRect functi
+ } else {
+ if ([partial_damage_layer_ superlayer]) {
+ [partial_damage_layer_ removeFromSuperlayer];
+ [partial_damage_layer_ setContents:nil];
+ }
+
+ // Note that calling setContents with the same IOSurface twice will result
+ // in the screen not being updated, even if the IOSurface's content has
+ // changed. Avoid this by calling setContentsChanged.
+ id new_contents = static_cast<id>(this_swap.io_surface.get());
+ if ([layer_ contents] == new_contents)
+ [layer_ setContentsChanged];
+ else
+ [layer_ setContents:static_cast<id>(this_swap.io_surface.get())];
Andre 2015/08/05 17:59:30 setContents:new_contents
ccameron 2015/08/06 18:55:18 Done.
+ [layer_ setFrame:gfx::Rect(this_swap.dip_size).ToCGRect()];
+ }
}
// Remove this swap from the queue.
@@ -252,7 +317,7 @@ void ImageTransportSurfaceOverlayMac::WakeUpGpu() {}
ImageTransportSurfaceOverlayMac::PendingSwap::PendingSwap()
- : fence(0) {
+ : fence(0), use_partial_damage(false) {
}
ImageTransportSurfaceOverlayMac::PendingSwap::~PendingSwap() {
« no previous file with comments | « content/common/gpu/image_transport_surface_overlay_mac.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698