Title: [103264] trunk/Source
Revision
103264
Author
commit-qu...@webkit.org
Date
2011-12-19 13:45:43 -0800 (Mon, 19 Dec 2011)

Log Message

[chromium] Accelerated canvas broken in threaded compositing mode
https://bugs.webkit.org/show_bug.cgi?id=72738

We were flushing the Skia canvas in updateCompositorResources, which
is illegal as it runs on the wrong thread. Moved to paintContentsIfDirty
instead. For correct rendering on the compositor thread, we make a copy
of the canvas texture in updateCompositorResources.

Removed m_textureId and pushPropertiesTo from CanvasLayerChromium, as
it's no longer common between Canvas2DLayerChromium and
WebGLLayerChromium. WebGL changes do not change functionality.

Patch by Iain Merrick <hu...@google.com> on 2011-12-19
Reviewed by James Robinson.

Source/WebCore:

* platform/graphics/chromium/Canvas2DLayerChromium.cpp:
(WebCore::Canvas2DLayerChromium::create):
(WebCore::Canvas2DLayerChromium::Canvas2DLayerChromium):
(WebCore::Canvas2DLayerChromium::~Canvas2DLayerChromium):
(WebCore::Canvas2DLayerChromium::setTextureId):
(WebCore::Canvas2DLayerChromium::contentChanged):
(WebCore::Canvas2DLayerChromium::drawsContent):
(WebCore::Canvas2DLayerChromium::paintContentsIfDirty):
(WebCore::Canvas2DLayerChromium::setLayerTreeHost):
(WebCore::Canvas2DLayerChromium::setTextureManager):
(WebCore::Canvas2DLayerChromium::updateCompositorResources):
(WebCore::Canvas2DLayerChromium::pushPropertiesTo):
(WebCore::Canvas2DLayerChromium::unreserveContentsTexture):
(WebCore::Canvas2DLayerChromium::cleanupResources):
* platform/graphics/chromium/Canvas2DLayerChromium.h:
* platform/graphics/chromium/CanvasLayerChromium.cpp:
(WebCore::CanvasLayerChromium::CanvasLayerChromium):
* platform/graphics/chromium/CanvasLayerChromium.h:
* platform/graphics/chromium/WebGLLayerChromium.cpp:
(WebCore::WebGLLayerChromium::WebGLLayerChromium):
(WebCore::WebGLLayerChromium::pushPropertiesTo):
* platform/graphics/chromium/WebGLLayerChromium.h:
(WebCore::WebGLLayerChromium::textureId):
(WebCore::WebGLLayerChromium::setTextureId):
* platform/graphics/chromium/cc/CCCanvasLayerImpl.h:
(WebCore::CCCanvasLayerImpl::textureId):
* platform/graphics/skia/ImageBufferSkia.cpp:
(WebCore::createAcceleratedCanvas):

Source/WebKit/chromium:

* WebKit.gypi:
* tests/Canvas2DLayerChromiumTest.cpp: Added.
(WebCore::Canvas2DLayerChromiumTest::setTextureManager):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (103263 => 103264)


--- trunk/Source/WebCore/ChangeLog	2011-12-19 21:42:16 UTC (rev 103263)
+++ trunk/Source/WebCore/ChangeLog	2011-12-19 21:45:43 UTC (rev 103264)
@@ -1,3 +1,48 @@
+2011-12-19  Iain Merrick  <hu...@google.com>
+
+        [chromium] Accelerated canvas broken in threaded compositing mode
+        https://bugs.webkit.org/show_bug.cgi?id=72738
+
+        We were flushing the Skia canvas in updateCompositorResources, which
+        is illegal as it runs on the wrong thread. Moved to paintContentsIfDirty
+        instead. For correct rendering on the compositor thread, we make a copy
+        of the canvas texture in updateCompositorResources.
+
+        Removed m_textureId and pushPropertiesTo from CanvasLayerChromium, as
+        it's no longer common between Canvas2DLayerChromium and
+        WebGLLayerChromium. WebGL changes do not change functionality.
+
+        Reviewed by James Robinson.
+
+        * platform/graphics/chromium/Canvas2DLayerChromium.cpp:
+        (WebCore::Canvas2DLayerChromium::create):
+        (WebCore::Canvas2DLayerChromium::Canvas2DLayerChromium):
+        (WebCore::Canvas2DLayerChromium::~Canvas2DLayerChromium):
+        (WebCore::Canvas2DLayerChromium::setTextureId):
+        (WebCore::Canvas2DLayerChromium::contentChanged):
+        (WebCore::Canvas2DLayerChromium::drawsContent):
+        (WebCore::Canvas2DLayerChromium::paintContentsIfDirty):
+        (WebCore::Canvas2DLayerChromium::setLayerTreeHost):
+        (WebCore::Canvas2DLayerChromium::setTextureManager):
+        (WebCore::Canvas2DLayerChromium::updateCompositorResources):
+        (WebCore::Canvas2DLayerChromium::pushPropertiesTo):
+        (WebCore::Canvas2DLayerChromium::unreserveContentsTexture):
+        (WebCore::Canvas2DLayerChromium::cleanupResources):
+        * platform/graphics/chromium/Canvas2DLayerChromium.h:
+        * platform/graphics/chromium/CanvasLayerChromium.cpp:
+        (WebCore::CanvasLayerChromium::CanvasLayerChromium):
+        * platform/graphics/chromium/CanvasLayerChromium.h:
+        * platform/graphics/chromium/WebGLLayerChromium.cpp:
+        (WebCore::WebGLLayerChromium::WebGLLayerChromium):
+        (WebCore::WebGLLayerChromium::pushPropertiesTo):
+        * platform/graphics/chromium/WebGLLayerChromium.h:
+        (WebCore::WebGLLayerChromium::textureId):
+        (WebCore::WebGLLayerChromium::setTextureId):
+        * platform/graphics/chromium/cc/CCCanvasLayerImpl.h:
+        (WebCore::CCCanvasLayerImpl::textureId):
+        * platform/graphics/skia/ImageBufferSkia.cpp:
+        (WebCore::createAcceleratedCanvas):
+
 2011-12-19  Mike Reed  <r...@google.com>
 
         [skia] cache typeface in FontPlatformData

Modified: trunk/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp (103263 => 103264)


--- trunk/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp	2011-12-19 21:42:16 UTC (rev 103263)
+++ trunk/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp	2011-12-19 21:45:43 UTC (rev 103264)
@@ -34,9 +34,12 @@
 
 #include "Canvas2DLayerChromium.h"
 
+#include "cc/CCCanvasLayerImpl.h"
+#include "cc/CCLayerTreeHost.h"
+#include "cc/CCTextureUpdater.h"
 #include "Extensions3DChromium.h"
 #include "GraphicsContext3D.h"
-#include "cc/CCLayerTreeHost.h"
+#include "LayerRendererChromium.h" // For the GLC() macro
 
 #if USE(SKIA)
 #include "GrContext.h"
@@ -44,52 +47,118 @@
 
 namespace WebCore {
 
-PassRefPtr<Canvas2DLayerChromium> Canvas2DLayerChromium::create(GraphicsContext3D* context)
+PassRefPtr<Canvas2DLayerChromium> Canvas2DLayerChromium::create(GraphicsContext3D* context, const IntSize& size)
 {
-    return adoptRef(new Canvas2DLayerChromium(context));
+    return adoptRef(new Canvas2DLayerChromium(context, size));
 }
 
-Canvas2DLayerChromium::Canvas2DLayerChromium(GraphicsContext3D* context)
+Canvas2DLayerChromium::Canvas2DLayerChromium(GraphicsContext3D* context, const IntSize& size)
     : CanvasLayerChromium(0)
     , m_context(context)
+    , m_size(size)
+    , m_backTextureId(0)
+    , m_fbo(0)
 {
+    GLC(m_context, m_fbo = m_context->createFramebuffer());
 }
 
 Canvas2DLayerChromium::~Canvas2DLayerChromium()
 {
+    GLC(m_context, m_context->deleteFramebuffer(m_fbo));
 }
 
+void Canvas2DLayerChromium::setTextureId(unsigned textureId)
+{
+    m_backTextureId = textureId;
+    setNeedsCommit();
+}
+
+void Canvas2DLayerChromium::contentChanged()
+{
+    if (layerTreeHost())
+        layerTreeHost()->startRateLimiter(m_context);
+
+    setNeedsDisplay();
+}
+
 bool Canvas2DLayerChromium::drawsContent() const
 {
-    return m_textureId && (m_context
-            && (m_context->getExtensions()->getGraphicsResetStatusARB() == GraphicsContext3D::NO_ERROR));
+    return m_backTextureId && !m_size.isEmpty()
+        && m_context && (m_context->getExtensions()->getGraphicsResetStatusARB() == GraphicsContext3D::NO_ERROR);
 }
 
-void Canvas2DLayerChromium::updateCompositorResources(GraphicsContext3D*, CCTextureUpdater&)
+void Canvas2DLayerChromium::paintContentsIfDirty()
 {
-    if (!m_needsDisplay || !drawsContent())
+    if (!drawsContent())
         return;
 
-    if (m_context) {
+    m_frontTexture->reserve(m_size, GraphicsContext3D::RGBA);
+
+    if (!needsDisplay())
+        return;
+
+    m_needsDisplay = false;
+
+    bool success = m_context->makeContextCurrent();
+    ASSERT_UNUSED(success, success);
+
 #if USE(SKIA)
-        GrContext* grContext = m_context->grContext();
-        if (grContext) {
-            m_context->makeContextCurrent();
-            grContext->flush();
-        }
+    GrContext* grContext = m_context->grContext();
+    if (grContext)
+        grContext->flush();
 #endif
-        m_context->flush();
-    }
 
-    m_updateRect = FloatRect(FloatPoint(), bounds());
-    m_needsDisplay = false;
+    m_context->flush();
 }
 
-void Canvas2DLayerChromium::contentChanged()
+void Canvas2DLayerChromium::setLayerTreeHost(CCLayerTreeHost* host)
 {
-    if (layerTreeHost())
-        layerTreeHost()->startRateLimiter(m_context);
+    if (layerTreeHost() != host)
+        setTextureManager(host ? host->contentsTextureManager() : 0);
+
+    CanvasLayerChromium::setLayerTreeHost(host);
 }
 
+void Canvas2DLayerChromium::setTextureManager(TextureManager* textureManager)
+{
+    if (textureManager)
+        m_frontTexture = ManagedTexture::create(textureManager);
+    else
+        m_frontTexture.clear();
 }
+
+void Canvas2DLayerChromium::updateCompositorResources(GraphicsContext3D* context, CCTextureUpdater& updater)
+{
+    if (!m_backTextureId || !m_frontTexture->isValid(m_size, GraphicsContext3D::RGBA))
+        return;
+
+    m_frontTexture->bindTexture(context, updater.allocator());
+
+    GLC(context, context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo));
+    GLC(context, context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, m_backTextureId, 0));
+    GLC(context, context->copyTexImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, 0, 0, m_size.width(), m_size.height(), 0));
+    GLC(context, context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0));
+    GLC(context, context->flush());
+}
+
+void Canvas2DLayerChromium::pushPropertiesTo(CCLayerImpl* layer)
+{
+    CanvasLayerChromium::pushPropertiesTo(layer);
+
+    CCCanvasLayerImpl* canvasLayer = static_cast<CCCanvasLayerImpl*>(layer);
+    canvasLayer->setTextureId(m_frontTexture->textureId());
+}
+
+void Canvas2DLayerChromium::unreserveContentsTexture()
+{
+    m_frontTexture->unreserve();
+}
+
+void Canvas2DLayerChromium::cleanupResources()
+{
+    m_frontTexture.clear();
+}
+
+}
+
 #endif // USE(ACCELERATED_COMPOSITING)

Modified: trunk/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h (103263 => 103264)


--- trunk/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h	2011-12-19 21:42:16 UTC (rev 103263)
+++ trunk/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h	2011-12-19 21:45:43 UTC (rev 103264)
@@ -35,6 +35,7 @@
 #if USE(ACCELERATED_COMPOSITING)
 
 #include "CanvasLayerChromium.h"
+#include "ManagedTexture.h"
 
 namespace WebCore {
 
@@ -43,16 +44,34 @@
 // A layer containing an accelerated 2d canvas
 class Canvas2DLayerChromium : public CanvasLayerChromium {
 public:
-    static PassRefPtr<Canvas2DLayerChromium> create(GraphicsContext3D*);
+    static PassRefPtr<Canvas2DLayerChromium> create(GraphicsContext3D*, const IntSize&);
     virtual ~Canvas2DLayerChromium();
+
+    void setTextureId(unsigned);
+
+    virtual void contentChanged();
+
     virtual bool drawsContent() const;
+    virtual void paintContentsIfDirty();
+
+    virtual void setLayerTreeHost(CCLayerTreeHost*);
     virtual void updateCompositorResources(GraphicsContext3D*, CCTextureUpdater&);
+    virtual void pushPropertiesTo(CCLayerImpl*);
+    virtual void unreserveContentsTexture();
+    virtual void cleanupResources();
 
-    virtual void contentChanged();
+private:
+    Canvas2DLayerChromium(GraphicsContext3D*, const IntSize&);
 
-private:
-    explicit Canvas2DLayerChromium(GraphicsContext3D*);
+    // Visible for testing so we can bypass setLayerTreeHost.
+    friend class Canvas2DLayerChromiumTest;
+    void setTextureManager(TextureManager*);
+
     GraphicsContext3D* m_context;
+    IntSize m_size;
+    unsigned m_backTextureId;
+    Platform3DObject m_fbo;
+    OwnPtr<ManagedTexture> m_frontTexture;
 };
 
 }

Modified: trunk/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp (103263 => 103264)


--- trunk/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp	2011-12-19 21:42:16 UTC (rev 103263)
+++ trunk/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp	2011-12-19 21:45:43 UTC (rev 103264)
@@ -42,30 +42,13 @@
 
 CanvasLayerChromium::CanvasLayerChromium(CCLayerDelegate* delegate)
     : LayerChromium(delegate)
-    , m_hasAlpha(true)
-    , m_premultipliedAlpha(true)
-    , m_textureId(0)
 {
 }
 
-CanvasLayerChromium::~CanvasLayerChromium()
-{
-}
-
 PassRefPtr<CCLayerImpl> CanvasLayerChromium::createCCLayerImpl()
 {
     return CCCanvasLayerImpl::create(m_layerId);
 }
 
-void CanvasLayerChromium::pushPropertiesTo(CCLayerImpl* layer)
-{
-    LayerChromium::pushPropertiesTo(layer);
-
-    CCCanvasLayerImpl* canvasLayer = static_cast<CCCanvasLayerImpl*>(layer);
-    canvasLayer->setTextureId(textureId());
-    canvasLayer->setHasAlpha(m_hasAlpha);
-    canvasLayer->setPremultipliedAlpha(m_premultipliedAlpha);
 }
-
-}
 #endif // USE(ACCELERATED_COMPOSITING)

Modified: trunk/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.h (103263 => 103264)


--- trunk/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.h	2011-12-19 21:42:16 UTC (rev 103263)
+++ trunk/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.h	2011-12-19 21:45:43 UTC (rev 103264)
@@ -41,20 +41,10 @@
 // Base class for WebGL and accelerated 2d canvases.
 class CanvasLayerChromium : public LayerChromium {
 public:
-    virtual ~CanvasLayerChromium();
-
     virtual PassRefPtr<CCLayerImpl> createCCLayerImpl();
 
-    virtual void pushPropertiesTo(CCLayerImpl*);
-    unsigned textureId() const { return m_textureId; }
-    void setTextureId(unsigned textureId) { m_textureId = textureId; }
-
 protected:
     explicit CanvasLayerChromium(CCLayerDelegate*);
-
-    bool m_hasAlpha;
-    bool m_premultipliedAlpha;
-    unsigned m_textureId;
 };
 
 }

Modified: trunk/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp (103263 => 103264)


--- trunk/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp	2011-12-19 21:42:16 UTC (rev 103263)
+++ trunk/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp	2011-12-19 21:45:43 UTC (rev 103264)
@@ -49,6 +49,9 @@
 
 WebGLLayerChromium::WebGLLayerChromium(CCLayerDelegate* delegate)
     : CanvasLayerChromium(delegate)
+    , m_hasAlpha(true)
+    , m_premultipliedAlpha(true)
+    , m_textureId(0)
     , m_textureChanged(true)
     , m_textureUpdated(false)
     , m_drawingBuffer(0)
@@ -95,6 +98,16 @@
     }
 }
 
+void WebGLLayerChromium::pushPropertiesTo(CCLayerImpl* layer)
+{
+    CanvasLayerChromium::pushPropertiesTo(layer);
+
+    CCCanvasLayerImpl* canvasLayer = static_cast<CCCanvasLayerImpl*>(layer);
+    canvasLayer->setTextureId(m_textureId);
+    canvasLayer->setHasAlpha(m_hasAlpha);
+    canvasLayer->setPremultipliedAlpha(m_premultipliedAlpha);
+}
+
 bool WebGLLayerChromium::paintRenderedResultsToCanvas(ImageBuffer* imageBuffer)
 {
     if (m_textureUpdated || !layerRendererContext() || !drawsContent())

Modified: trunk/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h (103263 => 103264)


--- trunk/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h	2011-12-19 21:42:16 UTC (rev 103263)
+++ trunk/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h	2011-12-19 21:45:43 UTC (rev 103264)
@@ -49,8 +49,12 @@
 
     virtual ~WebGLLayerChromium();
 
+    unsigned textureId() const { return m_textureId; }
+    void setTextureId(unsigned textureId) { m_textureId = textureId; }
+
     virtual bool drawsContent() const;
     virtual void updateCompositorResources(GraphicsContext3D*, CCTextureUpdater&);
+    virtual void pushPropertiesTo(CCLayerImpl*);
     virtual void contentChanged();
     bool paintRenderedResultsToCanvas(ImageBuffer*);
 
@@ -64,6 +68,9 @@
 
     GraphicsContext3D* layerRendererContext();
 
+    bool m_hasAlpha;
+    bool m_premultipliedAlpha;
+    unsigned m_textureId;
     bool m_textureChanged;
     bool m_textureUpdated;
 

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.h (103263 => 103264)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.h	2011-12-19 21:42:16 UTC (rev 103263)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCCanvasLayerImpl.h	2011-12-19 21:45:43 UTC (rev 103264)
@@ -46,6 +46,7 @@
 
     virtual void dumpLayerProperties(TextStream&, int indent) const;
 
+    unsigned textureId() const { return m_textureId; }
     void setTextureId(unsigned id) { m_textureId = id; }
     void setHasAlpha(bool hasAlpha) { m_hasAlpha = hasAlpha; }
     void setPremultipliedAlpha(bool premultipliedAlpha) { m_premultipliedAlpha = premultipliedAlpha; }

Modified: trunk/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp (103263 => 103264)


--- trunk/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp	2011-12-19 21:42:16 UTC (rev 103263)
+++ trunk/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp	2011-12-19 21:45:43 UTC (rev 103264)
@@ -87,7 +87,7 @@
     canvas->setDevice(new SkGpuDevice(gr, texture.get()))->unref();
     data->m_platformContext.setGraphicsContext3D(context3D);
 #if USE(ACCELERATED_COMPOSITING)
-    data->m_platformLayer = Canvas2DLayerChromium::create(context3D);
+    data->m_platformLayer = Canvas2DLayerChromium::create(context3D, size);
     data->m_platformLayer->setTextureId(texture.get()->getTextureHandle());
 #endif
     return canvas;

Modified: trunk/Source/WebKit/chromium/ChangeLog (103263 => 103264)


--- trunk/Source/WebKit/chromium/ChangeLog	2011-12-19 21:42:16 UTC (rev 103263)
+++ trunk/Source/WebKit/chromium/ChangeLog	2011-12-19 21:45:43 UTC (rev 103264)
@@ -1,3 +1,23 @@
+2011-12-19  Iain Merrick  <hu...@google.com>
+
+        [chromium] Accelerated canvas broken in threaded compositing mode
+        https://bugs.webkit.org/show_bug.cgi?id=72738
+
+        We were flushing the Skia canvas in updateCompositorResources, which
+        is illegal as it runs on the wrong thread. Moved to paintContentsIfDirty
+        instead. For correct rendering on the compositor thread, we make a copy
+        of the canvas texture in updateCompositorResources.
+
+        Removed m_textureId and pushPropertiesTo from CanvasLayerChromium, as
+        it's no longer common between Canvas2DLayerChromium and
+        WebGLLayerChromium. WebGL changes do not change functionality.
+
+        Reviewed by James Robinson.
+
+        * WebKit.gypi:
+        * tests/Canvas2DLayerChromiumTest.cpp: Added.
+        (WebCore::Canvas2DLayerChromiumTest::setTextureManager):
+
 2011-12-19  Ryosuke Niwa  <rn...@webkit.org>
 
         Chromium DEPS from 114686 to 115012.

Modified: trunk/Source/WebKit/chromium/WebKit.gypi (103263 => 103264)


--- trunk/Source/WebKit/chromium/WebKit.gypi	2011-12-19 21:42:16 UTC (rev 103263)
+++ trunk/Source/WebKit/chromium/WebKit.gypi	2011-12-19 21:45:43 UTC (rev 103264)
@@ -54,6 +54,7 @@
         'webkit_unittest_files': [
             'tests/ArenaTestHelpers.h',
             'tests/AssociatedURLLoaderTest.cpp',
+            'tests/Canvas2DLayerChromiumTest.cpp',
             'tests/CCDamageTrackerTest.cpp',
             'tests/CCDelayBasedTimeSourceTest.cpp',
             'tests/CCFrameRateControllerTest.cpp',

Added: trunk/Source/WebKit/chromium/tests/Canvas2DLayerChromiumTest.cpp (0 => 103264)


--- trunk/Source/WebKit/chromium/tests/Canvas2DLayerChromiumTest.cpp	                        (rev 0)
+++ trunk/Source/WebKit/chromium/tests/Canvas2DLayerChromiumTest.cpp	2011-12-19 21:45:43 UTC (rev 103264)
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "Canvas2DLayerChromium.h"
+
+#include "GraphicsContext3DPrivate.h"
+#include "MockWebGraphicsContext3D.h"
+#include "TextureManager.h"
+#include "cc/CCCanvasLayerImpl.h"
+#include "cc/CCSingleThreadProxy.h"
+#include "cc/CCTextureUpdater.h"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <wtf/RefPtr.h>
+
+using namespace WebCore;
+using namespace WebKit;
+using namespace testing;
+
+namespace WebCore {
+
+class Canvas2DLayerChromiumTest : public Test {
+protected:
+    // This indirection is needed because individual tests aren't friends of Canvas2DLayerChromium.
+    void setTextureManager(Canvas2DLayerChromium* layer, TextureManager* manager)
+    {
+        layer->setTextureManager(manager);
+    }
+};
+
+}
+
+namespace {
+
+class MockCanvasContext : public MockWebGraphicsContext3D {
+public:
+    MOCK_METHOD0(createFramebuffer, WebGLId());
+    MOCK_METHOD0(createTexture, WebGLId());
+
+    MOCK_METHOD2(bindFramebuffer, void(WGC3Denum, WebGLId));
+    MOCK_METHOD5(framebufferTexture2D, void(WGC3Denum, WGC3Denum, WGC3Denum, WebGLId, WGC3Dint));
+
+    MOCK_METHOD2(bindTexture, void(WGC3Denum, WebGLId));
+    MOCK_METHOD8(copyTexImage2D, void(WGC3Denum, WGC3Dint, WGC3Denum, WGC3Dint, WGC3Dint, WGC3Dsizei, WGC3Dsizei, WGC3Dint));
+
+    MOCK_METHOD1(deleteFramebuffer, void(WebGLId));
+    MOCK_METHOD1(deleteTexture, void(WebGLId));
+};
+
+class MockTextureAllocator : public TextureAllocator {
+public:
+    MOCK_METHOD2(createTexture, unsigned(const IntSize&, GC3Denum));
+    MOCK_METHOD3(deleteTexture, void(unsigned, const IntSize&, GC3Denum));
+};
+
+TEST_F(Canvas2DLayerChromiumTest, testFullLifecycle)
+{
+    GraphicsContext3D::Attributes attrs;
+
+    RefPtr<GraphicsContext3D> mainContext = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new MockCanvasContext()), attrs, 0, GraphicsContext3D::RenderDirectlyToHostWindow, GraphicsContext3DPrivate::ForUseOnThisThread);
+    RefPtr<GraphicsContext3D> implContext = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new MockCanvasContext()), attrs, 0, GraphicsContext3D::RenderDirectlyToHostWindow, GraphicsContext3DPrivate::ForUseOnThisThread);
+
+    MockCanvasContext& mainMock = *static_cast<MockCanvasContext*>(GraphicsContext3DPrivate::extractWebGraphicsContext3D(mainContext.get()));
+    MockCanvasContext& implMock = *static_cast<MockCanvasContext*>(GraphicsContext3DPrivate::extractWebGraphicsContext3D(implContext.get()));
+
+    MockTextureAllocator allocatorMock;
+    CCTextureUpdater updater(&allocatorMock);
+
+    const IntSize size(300, 150);
+    const size_t maxTextureSize = size.width() * size.height() * 4;
+    OwnPtr<TextureManager> textureManager = TextureManager::create(maxTextureSize, maxTextureSize, maxTextureSize);
+
+    const WebGLId backTextureId = 1;
+    const WebGLId frontTextureId = 2;
+    const WebGLId fboId = 3;
+    {
+        InSequence sequence;
+
+        // Setup Canvas2DLayerChromium (on the main thread).
+        EXPECT_CALL(mainMock, createFramebuffer())
+            .WillOnce(Return(fboId));
+
+        // Create texture and do the copy (on the impl thread).
+        EXPECT_CALL(allocatorMock, createTexture(size, GraphicsContext3D::RGBA))
+            .WillOnce(Return(frontTextureId));
+        EXPECT_CALL(implMock, bindTexture(GraphicsContext3D::TEXTURE_2D, frontTextureId));
+        EXPECT_CALL(implMock, bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, fboId));
+        EXPECT_CALL(implMock, framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, backTextureId, 0));
+        EXPECT_CALL(implMock, copyTexImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, 0, 0, 300, 150, 0));
+        EXPECT_CALL(implMock, bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0));
+
+        // Teardown Canvas2DLayerChromium.
+        EXPECT_CALL(mainMock, deleteFramebuffer(fboId));
+
+        // Teardown TextureManager.
+        EXPECT_CALL(allocatorMock, deleteTexture(frontTextureId, size, GraphicsContext3D::RGBA));
+    }
+
+    RefPtr<Canvas2DLayerChromium> canvas = Canvas2DLayerChromium::create(mainContext.get(), size);
+    setTextureManager(canvas.get(), textureManager.get());
+    canvas->setBounds(IntSize(600, 300));
+    canvas->setTextureId(backTextureId);
+
+    canvas->contentChanged();
+    EXPECT_TRUE(canvas->needsDisplay());
+    canvas->paintContentsIfDirty();
+    EXPECT_FALSE(canvas->needsDisplay());
+    {
+        DebugScopedSetImplThread scopedImplThread;
+
+        RefPtr<CCLayerImpl> layerImpl = canvas->createCCLayerImpl();
+        EXPECT_EQ(0u, static_cast<CCCanvasLayerImpl*>(layerImpl.get())->textureId());
+
+        canvas->updateCompositorResources(implContext.get(), updater);
+        canvas->pushPropertiesTo(layerImpl.get());
+
+        EXPECT_EQ(frontTextureId, static_cast<CCCanvasLayerImpl*>(layerImpl.get())->textureId());
+    }
+    canvas.clear();
+    textureManager->reduceMemoryToLimit(0);
+    textureManager->deleteEvictedTextures(&allocatorMock);
+}
+
+} // namespace
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to