Page/layer flashes after GPU-accelerated CSS transition
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 16 Nov 2011 21:54:54 +0000 (21:54 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 16 Nov 2011 21:54:54 +0000 (21:54 +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-16
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@100500 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 62317474329aa71485c106972e5ee6bc477b6f24..8cd16bb4760d8179168da03075daaab51ff22722 100644 (file)
@@ -1,3 +1,25 @@
+2011-11-16  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-16  Alexandre Elias  <aelias@google.com>
 
         [chromium] Add null pointer check in setDeviceScaleFactor
index c18ed02510e4042919cfeb710cdbc0aaa07b443f..bc9f000c222668af8a7a6da754d2d60c6b180bc3 100644 (file)
@@ -174,6 +174,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)
 {
 }
 
@@ -275,8 +276,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.
@@ -352,6 +352,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..350af62c8c4dbbea39748f5414856100c224f698 100644 (file)
@@ -292,5 +292,50 @@ 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;
+};
+
+class FakeDrawableCCLayerImpl: public CCLayerImpl {
+public:
+    FakeDrawableCCLayerImpl() : CCLayerImpl(0) { }
+    virtual void draw(LayerRendererChromium* renderer) { }
+};
+
+// 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 = adoptRef(new FakeDrawableCCLayerImpl());
+    root->setAnchorPoint(FloatPoint(0, 0));
+    root->setBounds(IntSize(10, 10));
+    root->setDrawsContent(true);
+    m_hostImpl->setRootLayer(root);
+    EXPECT_FALSE(reshapeTracker->reshapeCalled());
+
+    m_hostImpl->drawLayers();
+    EXPECT_TRUE(reshapeTracker->reshapeCalled());
+}
+
 
 } // namespace