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

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

Issue 636003002: Clean up GPU back-pressure with remote CALayers (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: O(1) more compile issue Created 6 years, 2 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
Index: content/common/gpu/image_transport_surface_calayer_mac.mm
diff --git a/content/common/gpu/image_transport_surface_calayer_mac.mm b/content/common/gpu/image_transport_surface_calayer_mac.mm
index 7531297ece8d113cb366b8fbc4a922d835efcde4..37354607502d3de3dd67f1832110acf6ec7212e7 100644
--- a/content/common/gpu/image_transport_surface_calayer_mac.mm
+++ b/content/common/gpu/image_transport_surface_calayer_mac.mm
@@ -90,11 +90,12 @@ CALayerStorageProvider::CALayerStorageProvider(
: transport_surface_(transport_surface),
gpu_vsync_disabled_(CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableGpuVsync)),
+ throttling_disabled_(false),
has_pending_draw_(false),
can_draw_returned_false_count_(0),
fbo_texture_(0),
fbo_scale_factor_(1),
- weak_factory_(this) {}
+ pending_draw_weak_factory_(this) {}
CALayerStorageProvider::~CALayerStorageProvider() {
}
@@ -141,20 +142,15 @@ bool CALayerStorageProvider::AllocateColorBufferStorage(
}
void CALayerStorageProvider::FreeColorBufferStorage() {
- // We shouldn't be asked to free a texture when we still have yet to draw it.
- DCHECK(!has_pending_draw_);
- has_pending_draw_ = false;
- can_draw_returned_false_count_ = 0;
-
// Note that |context_| still holds a reference to |layer_|, and will until
// a new frame is swapped in.
- [layer_ displayIfNeeded];
[layer_ resetStorageProvider];
layer_.reset();
share_group_context_.reset();
fbo_texture_ = 0;
fbo_pixel_size_ = gfx::Size();
+ can_draw_returned_false_count_ = 0;
}
void CALayerStorageProvider::SwapBuffers(
@@ -185,37 +181,41 @@ void CALayerStorageProvider::SwapBuffers(
[context_ setLayer:layer_];
}
- // Tell CoreAnimation to draw our frame. We will send the IPC to the browser
- // when CoreAnimation has drawn our frame.
- if (gpu_vsync_disabled_) {
- DrawWithVsyncDisabled();
+ // Tell CoreAnimation to draw our frame.
+ if (gpu_vsync_disabled_ || throttling_disabled_) {
+ DrawImmediatelyAndUnblockBrowser();
} else {
if (![layer_ isAsynchronous])
[layer_ setAsynchronous:YES];
+
+ // If CoreAnimation doesn't end up drawing our frame, un-block the browser
+ // after a timeout of 1/6th of a second has passed.
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&CALayerStorageProvider::DrawImmediatelyAndUnblockBrowser,
+ pending_draw_weak_factory_.GetWeakPtr()),
+ base::TimeDelta::FromSeconds(1) / 6);
}
}
-void CALayerStorageProvider::DrawWithVsyncDisabled() {
- DCHECK(has_pending_draw_);
+void CALayerStorageProvider::DrawImmediatelyAndUnblockBrowser() {
+ CHECK(has_pending_draw_);
+ if ([layer_ isAsynchronous])
+ [layer_ setAsynchronous:NO];
[layer_ setNeedsDisplay];
+ [layer_ displayIfNeeded];
- // Sometimes, setNeedsDisplay calls are dropped on the floor. Make this not
- // hang the renderer by re-issuing the call if the draw has not yet
- // happened.
- if (has_pending_draw_) {
- // Delay sending another draw immediately to avoid starving the run loop.
- base::MessageLoop::current()->PostDelayedTask(
- FROM_HERE,
- base::Bind(&CALayerStorageProvider::DrawWithVsyncDisabled,
- weak_factory_.GetWeakPtr()),
- base::TimeDelta::FromMilliseconds(5));
- }
+ // Sometimes, the setNeedsDisplay+displayIfNeeded pairs have no effect. This
+ // can happen if the NSView that this layer is attached to isn't in the
+ // window hierarchy (e.g, tab capture of a backgrounded tab). In this case,
+ // the frame will never be seen, so drop it.
+ UnblockBrowserIfNeeded();
}
void CALayerStorageProvider::WillWriteToBackbuffer() {
- // TODO(ccameron): The browser may need to continue issuing swaps even when
- // they do not draw. In these cases it is necessary to either double-buffer
- // the resulting texture, or to drop frames.
+ // The browser will always throttle itself so that there is no pending draw
+ // when this output surface is written to.
+ DCHECK(!has_pending_draw_);
}
void CALayerStorageProvider::DiscardBackbuffer() {
@@ -228,7 +228,9 @@ void CALayerStorageProvider::DiscardBackbuffer() {
context_.reset();
}
-void CALayerStorageProvider::SwapBuffersAckedByBrowser() {
+void CALayerStorageProvider::SwapBuffersAckedByBrowser(
+ bool disable_throttling) {
+ throttling_disabled_ = disable_throttling;
}
CGLContextObj CALayerStorageProvider::LayerShareGroupContext() {
@@ -290,20 +292,19 @@ void CALayerStorageProvider::LayerDoDraw() {
glDisable(GL_TEXTURE_RECTANGLE_ARB);
// Allow forward progress in the context now that the swap is complete.
- DCHECK(has_pending_draw_);
- SendPendingSwapToBrowserAfterFrameDrawn();
+ UnblockBrowserIfNeeded();
}
void CALayerStorageProvider::LayerResetStorageProvider() {
// If we are providing back-pressure by waiting for a draw, that draw will
// now never come, so release the pressure now.
- SendPendingSwapToBrowserAfterFrameDrawn();
+ UnblockBrowserIfNeeded();
}
-void CALayerStorageProvider::SendPendingSwapToBrowserAfterFrameDrawn() {
+void CALayerStorageProvider::UnblockBrowserIfNeeded() {
if (!has_pending_draw_)
return;
- weak_factory_.InvalidateWeakPtrs();
+ pending_draw_weak_factory_.InvalidateWeakPtrs();
has_pending_draw_ = false;
transport_surface_->SendSwapBuffers(
SurfaceHandleFromCAContextID([context_ contextId]),
« no previous file with comments | « content/common/gpu/image_transport_surface_calayer_mac.h ('k') | content/common/gpu/image_transport_surface_fbo_mac.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698