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

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: Rebase 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') | ui/gfx/geometry/rect_f.h » ('j') | 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 2e6911ce06aac51b1525d1522cc5f4edf936d62c..8f222c5062086ba1d1a60a68c263a58b151c61b9 100644
--- a/content/common/gpu/image_transport_surface_overlay_mac.mm
+++ b/content/common/gpu/image_transport_surface_overlay_mac.mm
@@ -64,6 +64,10 @@ class ImageTransportSurfaceOverlayMac::PendingSwap {
float scale_factor;
std::vector<ui::LatencyInfo> latency_info;
+ // If true, the partial damage rect for the frame.
+ bool use_partial_damage;
+ gfx::Rect pixel_partial_damage_rect;
+
// The IOSurface with new content for this swap.
base::ScopedCFTypeRef<IOSurfaceRef> io_surface;
@@ -105,6 +109,9 @@ bool ImageTransportSurfaceOverlayMac::Initialize() {
[layer_ setGeometryFlipped:YES];
[layer_ setOpaque:YES];
[ca_context_ setLayer:layer_];
+
+ partial_damage_layer_.reset([[CALayer alloc] init]);
+ [partial_damage_layer_ setOpaque:YES];
return true;
}
@@ -180,6 +187,36 @@ gfx::SwapResult ImageTransportSurfaceOverlayMac::SwapBuffersInternal(
new_swap->latest_allowed_draw_time = now;
}
+ // Determine if this will be a full or partial damage, and compute the rects
+ // for the damage.
+ {
+ // 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.
+ const double kMaximumFractionOfFullDamage = 0.85;
+ double fraction_of_full_damage =
+ 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.
+ const 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) {
+ new_swap->use_partial_damage = true;
+ new_swap->pixel_partial_damage_rect =
+ accumulated_partial_damage_pixel_rect_;
+ } else {
+ new_swap->use_partial_damage = false;
+ accumulated_partial_damage_pixel_rect_ = gfx::Rect();
+ }
+ }
+
pending_swaps_.push_back(new_swap);
PostCheckPendingSwapsCallbackIfNeeded(now);
return gfx::SwapResult::SWAP_ACK;
@@ -246,12 +283,44 @@ void ImageTransportSurfaceOverlayMac::DisplayFirstPendingSwapImmediately() {
ScopedCAActionDisabler disabler;
id new_contents = static_cast<id>(swap->io_surface.get());
- [layer_ setContents:new_contents];
-
- CGRect new_frame = gfx::ConvertRectToDIP(
- swap->scale_factor, gfx::Rect(swap->pixel_size)).ToCGRect();
- if (!CGRectEqualToRect([layer_ frame], new_frame))
- [layer_ setFrame:new_frame];
+ if (swap->use_partial_damage) {
+ if (![partial_damage_layer_ superlayer])
+ [layer_ addSublayer:partial_damage_layer_];
+ [partial_damage_layer_ setContents:new_contents];
+
+ CGRect new_frame = gfx::ConvertRectToDIP(
+ swap->scale_factor, swap->pixel_partial_damage_rect).ToCGRect();
+ if (!CGRectEqualToRect([partial_damage_layer_ frame], new_frame))
+ [partial_damage_layer_ setFrame:new_frame];
+
+ gfx::RectF contents_rect =
+ gfx::RectF(swap->pixel_partial_damage_rect);
+ contents_rect.Scale(
+ 1. / swap->pixel_size.width(), 1. / swap->pixel_size.height());
+ CGRect cg_contents_rect = CGRectMake(
+ contents_rect.x(), contents_rect.y(),
+ contents_rect.width(), contents_rect.height());
+ [partial_damage_layer_ setContentsRect:cg_contents_rect];
+ } else {
+ // Remove the partial damage layer.
+ 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.
+ if ([layer_ contents] == new_contents)
+ [layer_ setContentsChanged];
+ else
+ [layer_ setContents:new_contents];
+
+ CGRect new_frame = gfx::ConvertRectToDIP(
+ swap->scale_factor, gfx::Rect(swap->pixel_size)).ToCGRect();
+ if (!CGRectEqualToRect([layer_ frame], new_frame))
+ [layer_ setFrame:new_frame];
+ }
}
// Send acknowledgement to the browser.
« no previous file with comments | « content/common/gpu/image_transport_surface_overlay_mac.h ('k') | ui/gfx/geometry/rect_f.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698