Page/layer flashes after GPU-accelerated CSS transition
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 15 Nov 2011 23:07:48 +0000 (23:07 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 15 Nov 2011 23:07:48 +0000 (23:07 +0000)
https://bugs.webkit.org/show_bug.cgi?id=72343

LayerRendererChromium was resizing the window to 1x1 at initialization.
In some cases, there is no drawLayers before switching back to
software rendering. This left the window resized to 1x1 and the
following software paints would therefore not be visible. This change
moves the reshape call into drawLayers so that it will only be called
if rendering will occur.

Patch by John Bates <jbates@google.com> on 2011-11-15
Reviewed by James Robinson.

New test: CCLayerTreeHostImplTest.reshapeNotCalledUntilDraw.

* platform/graphics/chromium/LayerRendererChromium.cpp:
(WebCore::LayerRendererChromium::viewportChanged):
(WebCore::LayerRendererChromium::doViewportChanged):
(WebCore::LayerRendererChromium::drawLayersInternal):
* platform/graphics/chromium/LayerRendererChromium.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@100340 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h
Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp

index dd4c66eff0fb2a399cc31f9122ad85a484a633e6..2400c11485f5b8ec58a771191b3cdf29b21c2cfc 100644 (file)
@@ -1,3 +1,25 @@
+2011-11-15  John Bates  <jbates@google.com>
+
+        Page/layer flashes after GPU-accelerated CSS transition
+        https://bugs.webkit.org/show_bug.cgi?id=72343
+
+        LayerRendererChromium was resizing the window to 1x1 at initialization.
+        In some cases, there is no drawLayers before switching back to
+        software rendering. This left the window resized to 1x1 and the
+        following software paints would therefore not be visible. This change
+        moves the reshape call into drawLayers so that it will only be called
+        if rendering will occur.
+
+        Reviewed by James Robinson.
+
+        New test: CCLayerTreeHostImplTest.reshapeNotCalledUntilDraw.
+
+        * platform/graphics/chromium/LayerRendererChromium.cpp:
+        (WebCore::LayerRendererChromium::viewportChanged):
+        (WebCore::LayerRendererChromium::doViewportChanged):
+        (WebCore::LayerRendererChromium::drawLayersInternal):
+        * platform/graphics/chromium/LayerRendererChromium.h:
+
 2011-11-15  Julien Chaffraix  <jchaffraix@webkit.org>
 
         Add the needed plumbing to parse display: -webkit-grid
index 134bb052c278f0d38a4f196afabe0e9d949908e7..9a4ae58ce29b53844d8e0c466b8371ed6aee824a 100644 (file)
@@ -175,6 +175,7 @@ LayerRendererChromium::LayerRendererChromium(CCLayerTreeHostImpl* owner,
     , m_context(context)
     , m_defaultRenderSurface(0)
     , m_sharedGeometryQuad(FloatRect(-0.5f, -0.5f, 1.0f, 1.0f))
+    , m_isViewportChanged(false)
 {
 }
 
@@ -276,8 +277,7 @@ void LayerRendererChromium::releaseRenderSurfaceTextures()
 
 void LayerRendererChromium::viewportChanged()
 {
-    if (m_context)
-        m_context->reshape(std::max(1, viewportWidth()), std::max(1, viewportHeight()));
+    m_isViewportChanged = true;
 
     // Reset the current render surface to force an update of the viewport and
     // projection matrix next time useRenderSurface is called.
@@ -353,6 +353,14 @@ void LayerRendererChromium::drawLayersInternal()
         return;
 
     TRACE_EVENT("LayerRendererChromium::drawLayers", this, 0);
+    if (m_isViewportChanged) {
+        // Only reshape when we know we are going to draw. Otherwise, the reshape
+        // can leave the window at the wrong size if we never draw and the proper
+        // viewport size is never set.
+        m_isViewportChanged = false;
+        m_context->reshape(viewportWidth(), viewportHeight());
+    }
+
     CCLayerImpl* rootDrawLayer = rootLayer();
     makeContextCurrent();
 
index f9a831c81f2cc6cc84bd75bb82f481242349a984..174c8844025393b6a56dd8f6b15ba05662c54887 100644 (file)
@@ -231,6 +231,8 @@ private:
     CCLayerSorter m_layerSorter;
 
     FloatQuad m_sharedGeometryQuad;
+
+    bool m_isViewportChanged;
 };
 
 // Setting DEBUG_GL_CALLS to 1 will call glGetError() after almost every GL
index 44813e5709bf2d15b6d1533a9b52e56c29cdedb7..04da559b9a264b8810ba68f9a778b5ab72a77b58 100644 (file)
@@ -292,5 +292,45 @@ TEST_F(CCLayerTreeHostImplTest, blendingOffWhenDrawingOpaqueLayers)
     EXPECT_TRUE(layer2->drawn());
 }
 
+class ReshapeTrackerContext: public MockWebGraphicsContext3D {
+public:
+    ReshapeTrackerContext() : m_reshapeCalled(false) { }
+
+    virtual bool initialize(Attributes, WebView*, bool renderDirectlyToWebView) { return true; }
+
+    virtual void reshape(int width, int height)
+    {
+        m_reshapeCalled = true;
+    }
+
+    bool reshapeCalled() const { return m_reshapeCalled; }
+
+private:
+    bool m_reshapeCalled;
+};
+
+// Only reshape when we know we are going to draw. Otherwise, the reshape
+// can leave the window at the wrong size if we never draw and the proper
+// viewport size is never set.
+TEST_F(CCLayerTreeHostImplTest, reshapeNotCalledUntilDraw)
+{
+    GraphicsContext3D::Attributes attrs;
+    ReshapeTrackerContext* reshapeTracker = new ReshapeTrackerContext();
+    RefPtr<GraphicsContext3D> context = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(reshapeTracker), attrs, 0, GraphicsContext3D::RenderDirectlyToHostWindow, GraphicsContext3DPrivate::ForUseOnThisThread);
+    m_hostImpl->initializeLayerRenderer(context);
+    m_hostImpl->setViewport(IntSize(10, 10));
+
+    RefPtr<CCLayerImpl> root = CCLayerImpl::create(0);
+    root->setAnchorPoint(FloatPoint(0, 0));
+    root->setBounds(IntSize(10, 10));
+    root->setDrawsContent(true);
+    root->setBackgroundColor(Color(1, 1, 1, 1));
+    m_hostImpl->setRootLayer(root);
+    EXPECT_FALSE(reshapeTracker->reshapeCalled());
+
+    m_hostImpl->drawLayers();
+    EXPECT_TRUE(reshapeTracker->reshapeCalled());
+}
+
 
 } // namespace