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