diff options
author | ccameron@chromium.org <ccameron@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-31 03:03:46 +0000 |
---|---|---|
committer | ccameron@chromium.org <ccameron@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-31 03:03:46 +0000 |
commit | d48e6e247a99da0329cb3b1baa4533a1ffdec49f (patch) | |
tree | 9272ff470f1bafafc167fdffb2e389a74efd473d /content | |
parent | fb2ddb947151db7e531c7f7d7beb21eca07ebe10 (diff) | |
download | chromium_src-d48e6e247a99da0329cb3b1baa4533a1ffdec49f.zip chromium_src-d48e6e247a99da0329cb3b1baa4533a1ffdec49f.tar.gz chromium_src-d48e6e247a99da0329cb3b1baa4533a1ffdec49f.tar.bz2 |
Fix flickering when transitioning from composited to non-composited.
Consider a RenderWidgetHostViewMac which is in compositing mode and has
AllowOverlappingViews set. This is effected by
making the NSOpenGLContext context be below the window (by setting
NSOpenGLCPSurfaceOrder to -1) and making the window transparent
(fillRecting it to clearColor).
When transition from compositing mode to software mode, the OpenGL
context is unbound from the view, and then the window is painted with
the rendered contents.
What was going wrong in this bug is that the window is being repainted
from clearColor to the new contents after the OpenGL context which was
underneath it is removed. The effect is that for a few frames, only the
transparent window was there.
Prevent this flicker by leaving the GL context bound to the view, even
after switching back to software mode. This is not a substantial change
to the previous behavior. In both cases the IOSurface and its texture
are freed. In both cases the NSOpenGLContext is not destroyed. In both
cases there are code paths that leaves the NSOpenGLContext current to
the view through destruction.
Note that this fixes this one instance of flickering. There may be
others, but they are much less visible than this.
BUG=154531
TBR=thakis@chromium.org,kbr@chromium.org
TEST=Note that these are different instructions than in M28!!
TEST=Run Chrome with --disable-force-compositing-mode and
--show-composited-layer-borders. Go to
https://www.khronos.org/registry/webgl/conformance-suites/1.0.1/webgl-conformance-tests.html
Open the find bar by pressing command-f, and leave it open through
the rest of the test. Now click the "run" button next to attribs. You
should see the blue compositing grid clicker on the page as the results
come in, but there should be no transparent flickering. This is intermittent,
so press the run button a few times.
TEST=With the same browser set-up, go to gmail and open an email
thread. Now open the find bar by pressing command-f. There should be
no blue compositor grid visible. Now, click Reply on an email. There should
now be a blue compositor grid (and you should see gold boxes around the
various UI elements). Click on Discard. The grid should go away, but there
should be no transparent flickering.
NOTRY=true
Review URL: https://chromiumcodereview.appspot.com/19695016
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@214529 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r-- | content/browser/renderer_host/render_widget_host_view_mac.h | 7 | ||||
-rw-r--r-- | content/browser/renderer_host/render_widget_host_view_mac.mm | 37 |
2 files changed, 35 insertions, 9 deletions
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.h b/content/browser/renderer_host/render_widget_host_view_mac.h index af8106c..6cbe6dc 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.h +++ b/content/browser/renderer_host/render_widget_host_view_mac.h @@ -463,7 +463,12 @@ class RenderWidgetHostViewMac : public RenderWidgetHostViewBase, bool CreateCompositedIOSurface(); bool CreateCompositedIOSurfaceLayer(); - void DestroyCompositedIOSurfaceAndLayer(); + enum DestroyContextBehavior { + kLeaveContextBoundToView, + kDestroyContext, + }; + void DestroyCompositedIOSurfaceAndLayer(DestroyContextBehavior + destroy_context_behavior); // Unbind the GL context (if any) that is bound to |cocoa_view_|. void ClearBoundContextDrawable(); diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm index a7338b5..099e688 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm @@ -428,7 +428,7 @@ RenderWidgetHostViewMac::~RenderWidgetHostViewMac() { UnlockMouse(); // Make sure that the layer doesn't reach into the now-invalid object. - DestroyCompositedIOSurfaceAndLayer(); + DestroyCompositedIOSurfaceAndLayer(kDestroyContext); software_layer_.reset(); // We are owned by RenderWidgetHostViewCocoa, so if we go away before the @@ -551,7 +551,8 @@ bool RenderWidgetHostViewMac::CreateCompositedIOSurfaceLayer() { (compositing_iosurface_layer_ || !use_core_animation_); } -void RenderWidgetHostViewMac::DestroyCompositedIOSurfaceAndLayer() { +void RenderWidgetHostViewMac::DestroyCompositedIOSurfaceAndLayer( + DestroyContextBehavior destroy_context_behavior) { ScopedCAActionDisabler disabler; compositing_iosurface_.reset(); @@ -561,8 +562,17 @@ void RenderWidgetHostViewMac::DestroyCompositedIOSurfaceAndLayer() { [compositing_iosurface_layer_ disableCompositing]; compositing_iosurface_layer_.reset(); } - ClearBoundContextDrawable(); - compositing_iosurface_context_ = NULL; + switch (destroy_context_behavior) { + case kLeaveContextBoundToView: + break; + case kDestroyContext: + ClearBoundContextDrawable(); + compositing_iosurface_context_ = NULL; + break; + default: + NOTREACHED(); + break; + } } void RenderWidgetHostViewMac::ClearBoundContextDrawable() { @@ -1414,7 +1424,7 @@ bool RenderWidgetHostViewMac::DrawIOSurfaceWithoutCoreAnimation() { void RenderWidgetHostViewMac::GotAcceleratedCompositingError() { AckPendingSwapBuffers(); - DestroyCompositedIOSurfaceAndLayer(); + DestroyCompositedIOSurfaceAndLayer(kDestroyContext); // The existing GL contexts may be in a bad state, so don't re-use any of the // existing ones anymore, rather, allocate new ones. CompositingIOSurfaceContext::MarkExistingContextsAsNotShareable(); @@ -1616,7 +1626,7 @@ void RenderWidgetHostViewMac::AcceleratedSurfaceSuspend() { } void RenderWidgetHostViewMac::AcceleratedSurfaceRelease() { - DestroyCompositedIOSurfaceAndLayer(); + DestroyCompositedIOSurfaceAndLayer(kDestroyContext); } bool RenderWidgetHostViewMac::HasAcceleratedSurface( @@ -1744,8 +1754,19 @@ void RenderWidgetHostViewMac::GotSoftwareFrame() { AckPendingSwapBuffers(); - // Forget IOSurface since we are drawing a software frame now. - DestroyCompositedIOSurfaceAndLayer(); + // If overlapping views are allowed, then don't unbind the context + // from the view (that is, don't call clearDrawble -- just delete the + // texture and IOSurface). Rather, let it sit behind the software frame + // that will be put up in front. This will prevent transparent + // flashes. + // http://crbug.com/154531 + // Also note that it is necessary that clearDrawable be called if + // overlapping views are not allowed, e.g, for content shell. + // http://crbug.com/178408 + if (allow_overlapping_views_) + DestroyCompositedIOSurfaceAndLayer(kLeaveContextBoundToView); + else + DestroyCompositedIOSurfaceAndLayer(kDestroyContext); } } |