[chromium] Fix CCLayerTreeHostTest
authorjamesr@google.com <jamesr@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 16 Sep 2011 18:43:37 +0000 (18:43 +0000)
committerjamesr@google.com <jamesr@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 16 Sep 2011 18:43:37 +0000 (18:43 +0000)
https://bugs.webkit.org/show_bug.cgi?id=67418

Source/WebCore:

This is a minimal set of changes to get CCLayerTreeHostTest
compiling, running and passing with USE_THREADED_COMPOSITING
enabled.

Patch by Iain Merrick <husky@google.com> on 2011-09-16
Reviewed by James Robinson.

* platform/graphics/chromium/ContentLayerChromium.cpp:
(WebCore::ContentLayerChromium::createTextureUpdater):
* platform/graphics/chromium/LayerRendererChromium.cpp:
(WebCore::LayerRendererChromium::LayerRendererChromium):
* platform/graphics/chromium/cc/CCLayerTreeHost.cpp:
(WebCore::CCLayerTreeHost::createLayerTreeHostImpl):
* platform/graphics/chromium/cc/CCLayerTreeHost.h:
* platform/graphics/chromium/cc/CCLayerTreeHostImpl.h:
* platform/graphics/chromium/cc/CCThreadProxy.cpp:
(WebCore::CCThreadProxy::context):
(WebCore::CCThreadProxy::beginFrameAndCommitOnCCThread):
(WebCore::CCThreadProxy::setNeedsCommitAndRedrawOnCCThread):
(WebCore::CCThreadProxy::setNeedsRedrawOnCCThread):

Source/WebKit/chromium:

Fixes needed to compile and link with USE_THREADED_COMPOSITING
enabled, and to pass the basic unit test.

Patch by Iain Merrick <husky@google.com> on 2011-09-16
Reviewed by James Robinson.

* src/GraphicsContext3DChromium.cpp:
(WebCore::GraphicsContext3DPrivate::GraphicsContext3DPrivate):
(WebCore::GraphicsContext3DPrivate::platformLayer):
* src/GraphicsContext3DPrivate.h:
* tests/CCLayerTreeHostTest.cpp:
(TestHooks::beginCommitOnCCThread):
(TestHooks::commitCompleteOnCCThread):
(TestHooks::drawLayersOnCCThread):
(MockLayerTreeHostImpl::MockLayerTreeHostImpl):
(MockLayerTreeHostImpl::beginCommit):
(MockLayerTreeHostImpl::commitComplete):
(MockLayerTreeHostImpl::drawLayers):
(MockLayerTreeHost::MockLayerTreeHost):
(MockLayerTreeHost::createLayerTreeHostImpl):
(CompositorMockWebGraphicsContext3D::makeContextCurrent):
(CompositorMockWebGraphicsContext3D::createProgram):
(CompositorMockWebGraphicsContext3D::createShader):
(CompositorMockWebGraphicsContext3D::getShaderiv):
(CompositorMockWebGraphicsContext3D::getProgramiv):
(MockLayerTreeHostClient::MockLayerTreeHostClient):
(MockLayerTreeHostClient::animateAndLayout):
(MockLayerTreeHostClient::createCompositorThread):
(MockLayerTreeHostClient::createLayerTreeHostContext3D):
(MockLayerTreeHostClient::createRootLayerPainter):
(MockLayerTreeHostClient::didRecreateGraphicsContext):
(CCLayerTreeHostTest::postSetNeedsCommitToMainThread):
(CCLayerTreeHostTest::postSetNeedsRedrawToMainThread):
(CCLayerTreeHostTest::onEndTest):
(CCLayerTreeHostTest::dispatchSetNeedsCommit):
(CCLayerTreeHostTest::dispatchSetNeedsRedraw):
(CCLayerTreeHostTest::runTest):
(CCLayerTreeHostTest::doBeginTest):
(CCLayerTreeHostTestShortlived2::beginTest):
(CCLayerTreeHostTestShortlived3::beginTest):
(CCLayerTreeHostTestCommitingWithContinuousRedraw::beginTest):
(CCLayerTreeHostTestCommitingWithContinuousRedraw::commitCompleteOnCCThread):
(CCLayerTreeHostTestCommitingWithContinuousRedraw::drawLayersOnCCThread):
(CCLayerTreeHostTestSetNeedsCommit1::beginTest):
(CCLayerTreeHostTestSetNeedsCommit1::drawLayersOnCCThread):
(CCLayerTreeHostTestSetNeedsCommit1::commitCompleteOnCCThread):
(CCLayerTreeHostTestSetNeedsCommit2::beginTest):
(CCLayerTreeHostTestSetNeedsCommit2::drawLayersOnCCThread):
(CCLayerTreeHostTestSetNeedsCommit2::commitCompleteOnCCThread):
(CCLayerTreeHostTestSetNeedsRedraw::beginTest):
(CCLayerTreeHostTestSetNeedsRedraw::drawLayersOnCCThread):
(CCLayerTreeHostTestSetNeedsRedraw::commitCompleteOnCCThread):

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

Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp
Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h
Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h
Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp

index 57bda4f..333ebae 100644 (file)
@@ -1,3 +1,28 @@
+2011-09-16  Iain Merrick  <husky@google.com>
+
+        [chromium] Fix CCLayerTreeHostTest
+        https://bugs.webkit.org/show_bug.cgi?id=67418
+
+        This is a minimal set of changes to get CCLayerTreeHostTest
+        compiling, running and passing with USE_THREADED_COMPOSITING
+        enabled.
+
+        Reviewed by James Robinson.
+
+        * platform/graphics/chromium/ContentLayerChromium.cpp:
+        (WebCore::ContentLayerChromium::createTextureUpdater):
+        * platform/graphics/chromium/LayerRendererChromium.cpp:
+        (WebCore::LayerRendererChromium::LayerRendererChromium):
+        * platform/graphics/chromium/cc/CCLayerTreeHost.cpp:
+        (WebCore::CCLayerTreeHost::createLayerTreeHostImpl):
+        * platform/graphics/chromium/cc/CCLayerTreeHost.h:
+        * platform/graphics/chromium/cc/CCLayerTreeHostImpl.h:
+        * platform/graphics/chromium/cc/CCThreadProxy.cpp:
+        (WebCore::CCThreadProxy::context):
+        (WebCore::CCThreadProxy::beginFrameAndCommitOnCCThread):
+        (WebCore::CCThreadProxy::setNeedsCommitAndRedrawOnCCThread):
+        (WebCore::CCThreadProxy::setNeedsRedrawOnCCThread):
+
 2011-09-16  Sheriff Bot  <webkit.review.bot@gmail.com>
 
         Unreviewed, rolling out r95227.
index 05e3166..0f42aa9 100644 (file)
@@ -120,6 +120,7 @@ bool ContentLayerChromium::drawsContent() const
 
 void ContentLayerChromium::createTextureUpdater(const CCLayerTreeHost* host)
 {
+#if !USE(THREADED_COMPOSITING)
 #if USE(SKIA)
     // Note that host->skiaContext() will crash if called while in threaded
     // mode. This thus depends on CCLayerTreeHost::initialize turning off
@@ -129,6 +130,7 @@ void ContentLayerChromium::createTextureUpdater(const CCLayerTreeHost* host)
         return;
     }
 #endif // SKIA
+#endif // !THREADED_COMPOSITING
 
     m_textureUpdater = LayerTextureUpdaterBitmap::create(ContentLayerPainter::create(m_delegate), host->layerRendererCapabilities().usingMapSub);
 }
index f3ba0c5..7afcb73 100644 (file)
@@ -148,6 +148,7 @@ LayerRendererChromium::LayerRendererChromium(CCLayerTreeHostImpl* owner,
     , m_currentRenderSurface(0)
     , m_offscreenFramebufferId(0)
     , m_zoomAnimatorScale(1)
+    , m_contentsTextureMemoryUseBytes(0)
     , m_context(context)
     , m_defaultRenderSurface(0)
     , m_sharedGeometryQuad(FloatRect(-0.5f, -0.5f, 1.0f, 1.0f))
index b523f77..fee2956 100644 (file)
@@ -99,7 +99,7 @@ public:
     void commitTo(CCLayerTreeHostImpl*);
     PassOwnPtr<CCThread> createCompositorThread();
     PassRefPtr<GraphicsContext3D> createLayerTreeHostContext3D();
-    PassOwnPtr<CCLayerTreeHostImpl> createLayerTreeHostImpl();
+    virtual PassOwnPtr<CCLayerTreeHostImpl> createLayerTreeHostImpl();
     void didRecreateGraphicsContext(bool success);
 #if !USE(THREADED_COMPOSITING)
     void scheduleComposite();
@@ -154,6 +154,7 @@ public:
 
 protected:
     CCLayerTreeHost(CCLayerTreeHostClient*, PassRefPtr<LayerChromium> rootLayer, const CCSettings&);
+    bool initialize();
 
 private:
     typedef Vector<RefPtr<LayerChromium> > LayerList;
@@ -164,8 +165,6 @@ private:
     void updateCompositorResources(LayerChromium*, GraphicsContext3D*);
     void clearPendingUpdate();
 
-    bool initialize();
-
     bool m_animating;
 
     CCLayerTreeHostClient* m_client;
index c752e00..a37e9f3 100644 (file)
@@ -46,13 +46,13 @@ public:
     static PassOwnPtr<CCLayerTreeHostImpl> create(const CCSettings&);
     virtual ~CCLayerTreeHostImpl();
 
+    // Virtual for testing
     virtual void beginCommit();
     virtual void commitComplete();
+    virtual void drawLayers();
 
     GraphicsContext3D* context();
 
-    void drawLayers();
-
     void finishAllRendering();
     int frameNumber() const { return m_frameNumber; }
 
index 12b5b36..9a84da6 100644 (file)
@@ -84,7 +84,6 @@ bool CCThreadProxy::compositeAndReadback(void *pixels, const IntRect& rect)
 
 GraphicsContext3D* CCThreadProxy::context()
 {
-    ASSERT_NOT_REACHED();
     return 0;
 }
 
@@ -186,8 +185,8 @@ void CCThreadProxy::beginFrameAndCommitOnCCThread()
 {
     TRACE_EVENT("CCThreadProxy::beginFrameAndCommitOnCCThread", this, 0);
     ASSERT(isImplThread());
-    ASSERT_NOT_REACHED();
-    // FIXME: call beginFrameAndCommit on main thread
+    // TEMP HACK so we can exercise this code in unit tests.
+    CCMainThread::postTask(createMainThreadTask(this, &CCThreadProxy::beginFrameAndCommit, 0.0));
 }
 
 void CCThreadProxy::beginFrameAndCommit(double frameBeginTime)
@@ -247,13 +246,15 @@ void CCThreadProxy::setNeedsCommitAndRedrawOnCCThread()
     TRACE_EVENT("CCThreadProxy::setNeedsCommitAndRedrawOnCCThread", this, 0);
     ASSERT(isImplThread());
     ASSERT(m_layerTreeHostImpl);
-    ASSERT_NOT_REACHED();
+    // TEMP HACK so we can exercise this code in unit tests.
+    CCMainThread::postTask(createMainThreadTask(this, &CCThreadProxy::beginFrameAndCommit, 0.0));
 }
 
 void CCThreadProxy::setNeedsRedrawOnCCThread()
 {
     TRACE_EVENT("CCThreadProxy::setNeedsRedrawOnCCThread", this, 0);
-    ASSERT_NOT_REACHED();
+    // TEMP HACK so we can exercise this code in unit tests.
+    drawLayersOnCCThread();
 }
 
 void CCThreadProxy::initializeImplOnCCThread(CCCompletionEvent* completion)
@@ -284,4 +285,4 @@ void CCThreadProxy::layerTreeHostClosedOnCCThread(CCCompletionEvent* completion)
     completion->signal();
 }
 
-}
+} // namespace WebCore
index 649dd3a..a1208e6 100644 (file)
@@ -1,3 +1,60 @@
+2011-09-16  Iain Merrick  <husky@google.com>
+
+        [chromium] Fix CCLayerTreeHostTest
+        https://bugs.webkit.org/show_bug.cgi?id=67418
+
+        Fixes needed to compile and link with USE_THREADED_COMPOSITING
+        enabled, and to pass the basic unit test.
+
+        Reviewed by James Robinson.
+
+        * src/GraphicsContext3DChromium.cpp:
+        (WebCore::GraphicsContext3DPrivate::GraphicsContext3DPrivate):
+        (WebCore::GraphicsContext3DPrivate::platformLayer):
+        * src/GraphicsContext3DPrivate.h:
+        * tests/CCLayerTreeHostTest.cpp:
+        (TestHooks::beginCommitOnCCThread):
+        (TestHooks::commitCompleteOnCCThread):
+        (TestHooks::drawLayersOnCCThread):
+        (MockLayerTreeHostImpl::MockLayerTreeHostImpl):
+        (MockLayerTreeHostImpl::beginCommit):
+        (MockLayerTreeHostImpl::commitComplete):
+        (MockLayerTreeHostImpl::drawLayers):
+        (MockLayerTreeHost::MockLayerTreeHost):
+        (MockLayerTreeHost::createLayerTreeHostImpl):
+        (CompositorMockWebGraphicsContext3D::makeContextCurrent):
+        (CompositorMockWebGraphicsContext3D::createProgram):
+        (CompositorMockWebGraphicsContext3D::createShader):
+        (CompositorMockWebGraphicsContext3D::getShaderiv):
+        (CompositorMockWebGraphicsContext3D::getProgramiv):
+        (MockLayerTreeHostClient::MockLayerTreeHostClient):
+        (MockLayerTreeHostClient::animateAndLayout):
+        (MockLayerTreeHostClient::createCompositorThread):
+        (MockLayerTreeHostClient::createLayerTreeHostContext3D):
+        (MockLayerTreeHostClient::createRootLayerPainter):
+        (MockLayerTreeHostClient::didRecreateGraphicsContext):
+        (CCLayerTreeHostTest::postSetNeedsCommitToMainThread):
+        (CCLayerTreeHostTest::postSetNeedsRedrawToMainThread):
+        (CCLayerTreeHostTest::onEndTest):
+        (CCLayerTreeHostTest::dispatchSetNeedsCommit):
+        (CCLayerTreeHostTest::dispatchSetNeedsRedraw):
+        (CCLayerTreeHostTest::runTest):
+        (CCLayerTreeHostTest::doBeginTest):
+        (CCLayerTreeHostTestShortlived2::beginTest):
+        (CCLayerTreeHostTestShortlived3::beginTest):
+        (CCLayerTreeHostTestCommitingWithContinuousRedraw::beginTest):
+        (CCLayerTreeHostTestCommitingWithContinuousRedraw::commitCompleteOnCCThread):
+        (CCLayerTreeHostTestCommitingWithContinuousRedraw::drawLayersOnCCThread):
+        (CCLayerTreeHostTestSetNeedsCommit1::beginTest):
+        (CCLayerTreeHostTestSetNeedsCommit1::drawLayersOnCCThread):
+        (CCLayerTreeHostTestSetNeedsCommit1::commitCompleteOnCCThread):
+        (CCLayerTreeHostTestSetNeedsCommit2::beginTest):
+        (CCLayerTreeHostTestSetNeedsCommit2::drawLayersOnCCThread):
+        (CCLayerTreeHostTestSetNeedsCommit2::commitCompleteOnCCThread):
+        (CCLayerTreeHostTestSetNeedsRedraw::beginTest):
+        (CCLayerTreeHostTestSetNeedsRedraw::drawLayersOnCCThread):
+        (CCLayerTreeHostTestSetNeedsRedraw::commitCompleteOnCCThread):
+
 2011-09-16  Andrey Kosyakov  <caseq@chromium.org>
 
         Web Inspector: [Extensions API] support extensions for remote inspector front-end
index d854806..ff4ffbe 100644 (file)
 
 #include "cc/CCLayerTreeHost.h"
 
-#include "GraphicsContext3D.h"
+#include "CCThreadImpl.h"
+#include "GraphicsContext3DPrivate.h"
+#include "LayerChromium.h"
+#include "LayerPainterChromium.h"
+#include "MockWebGraphicsContext3D.h"
+#include "TextureManager.h"
 #include "cc/CCLayerTreeHostImpl.h"
 #include "cc/CCMainThreadTask.h"
 #include "cc/CCThreadTask.h"
 #include <wtf/PassRefPtr.h>
 #include <wtf/Vector.h>
 
-
 using namespace WebCore;
+using namespace WebKit;
 using namespace WTF;
 
 namespace {
 
-class MockLayerTreeHost;
-class MockLayerTreeHostClient;
-class MockLayerTreeHostImpl;
-
-// The CCLayerTreeHostTest runs with the main loop running. It instantiates a single MockLayerTreeHost and associated
-// MockLayerTreeHostImpl/MockLayerTreeHostClient.
-//
-// beginTest() is called once the main message loop is running and the layer tree host is initialized.
-//
-// Key stages of the drawing loop, e.g. drawing or commiting, redirect to CCLayerTreeHostTest methods of similar names.
-// To track the commit process, override these functions.
-//
-// The test continues until someone calls endTest. endTest can be called on any thread, but be aware that
-// ending the test is an asynchronous process.
-class CCLayerTreeHostTest : public testing::Test {
+// Used by test stubs to notify the test when something interesting happens.
+class TestHooks {
 public:
-    CCLayerTreeHostTest()
-        : m_beginning(false)
-        , m_endWhenBeginReturns(false)
-        , m_running(false)
-        , m_timedOut(false) { }
-
-    virtual void afterTest() = 0;
-
-    virtual void beginTest() = 0;
-    virtual void animateAndLayout(MockLayerTreeHostClient* layerTreeHost, double frameBeginTime) { }
-    virtual void beginCommitOnCCThread(MockLayerTreeHostImpl* layerTreeHostImpl) { }
-    virtual void beginCommitOnMainThread(MockLayerTreeHost* layerTreeHost) { }
-    virtual void commitOnCCThread(MockLayerTreeHost* layerTreeHost, MockLayerTreeHostImpl* layerTreeHostImpl) { }
-    virtual void commitCompleteOnCCThread(MockLayerTreeHostImpl* layerTreeHostImpl) { }
-    virtual void commitCompleteOnMainThread(MockLayerTreeHost* layerTreeHost) { }
-    virtual void drawLayersAndPresentOnCCThread(MockLayerTreeHostImpl* layerTreeHostImpl) { }
-    virtual void updateLayers(MockLayerTreeHost* layerTreeHost) { }
-
-    void endTest();
-
-protected:
-    void doBeginTest();
+    virtual void beginCommitOnCCThread(CCLayerTreeHostImpl*) { }
+    virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl*) { }
+    virtual void drawLayersOnCCThread(CCLayerTreeHostImpl*) { }
+};
 
-    static void onBeginTest(void* self)
+// Adapts CCLayerTreeHostImpl for test. Runs real code, then invokes test hooks.
+class MockLayerTreeHostImpl : public CCLayerTreeHostImpl {
+public:
+    static PassOwnPtr<MockLayerTreeHostImpl> create(TestHooks* testHooks, const CCSettings& settings)
     {
-        static_cast<CCLayerTreeHostTest*>(self)->doBeginTest();
+        return adoptPtr(new MockLayerTreeHostImpl(testHooks, settings));
     }
 
-    void doEndTest()
+    virtual void beginCommit()
     {
+        CCLayerTreeHostImpl::beginCommit();
+        m_testHooks->beginCommitOnCCThread(this);
     }
 
-    static void onEndTest(void* self)
+    virtual void commitComplete()
     {
-        ASSERT(isMainThread());
-        CCLayerTreeHostTest* test = static_cast<CCLayerTreeHostTest*>(self);
-        test->m_layerTreeHost.clear();
-        test->m_client.clear();
-        webkit_support::QuitMessageLoop();
+        CCLayerTreeHostImpl::commitComplete();
+        m_testHooks->commitCompleteOnCCThread(this);
     }
 
-    void runTest()
+    virtual void drawLayers()
     {
-        webkit_support::PostDelayedTask(CCLayerTreeHostTest::onBeginTest, static_cast<void*>(this), 0);
-        webkit_support::PostDelayedTask(CCLayerTreeHostTest::testTimeout, static_cast<void*>(this), 5000);
-        webkit_support::RunMessageLoop();
-        m_running = false;
-        bool timedOut = m_timedOut; // Save whether we're timed out in case RunAllPendingMessages has the timeout.
-        webkit_support::RunAllPendingMessages();
-        if (timedOut) {
-            printf("Test timed out");
-            FAIL() << "Test timed out";
-            return;
-        }
-        afterTest();
+        CCLayerTreeHostImpl::drawLayers();
+        m_testHooks->drawLayersOnCCThread(this);
     }
 
-    static void testTimeout(void* self)
+private:
+    MockLayerTreeHostImpl(TestHooks* testHooks, const CCSettings& settings)
+        : CCLayerTreeHostImpl(settings)
+        , m_testHooks(testHooks)
     {
-        CCLayerTreeHostTest* test = static_cast<CCLayerTreeHostTest*>(self);
-        if (!test->m_running)
-            return;
-        test->m_timedOut = true;
-        test->endTest();
     }
 
-    Mutex m_tracesLock;
-    Vector<std::string> m_traces;
-
-    OwnPtr<MockLayerTreeHostClient> m_client;
-    RefPtr<MockLayerTreeHost> m_layerTreeHost;
-
-private:
-    bool m_beginning;
-    bool m_endWhenBeginReturns;
-    bool m_running;
-    bool m_timedOut;
+    TestHooks* m_testHooks;
 };
 
-class MockLayerTreeHostClient : public CCLayerTreeHostClient {
+// Adapts CCLayerTreeHost for test. Injects MockLayerTreeHostImpl.
+class MockLayerTreeHost : public CCLayerTreeHost {
 public:
-    MockLayerTreeHostClient(CCLayerTreeHostTest* test) : m_test(test) { }
-
-    virtual PassRefPtr<GraphicsContext3D> createLayerTreeHostContext3D()
+    static PassRefPtr<MockLayerTreeHost> create(TestHooks* testHooks, CCLayerTreeHostClient* client, PassRefPtr<LayerChromium> rootLayer, const CCSettings& settings)
     {
-        return adoptRef<GraphicsContext3D>(0);
+        return adoptRef(new MockLayerTreeHost(testHooks, client, rootLayer, settings));
     }
 
-    virtual void animateAndLayout(double frameBeginTime)
+    virtual PassOwnPtr<CCLayerTreeHostImpl> createLayerTreeHostImpl()
     {
-        m_test->animateAndLayout(this, frameBeginTime);
+        return MockLayerTreeHostImpl::create(m_testHooks, settings());
     }
 
-    virtual void updateLayers()
+private:
+    MockLayerTreeHost(TestHooks* testHooks, CCLayerTreeHostClient* client, PassRefPtr<LayerChromium> rootLayer, const CCSettings& settings)
+        : CCLayerTreeHost(client, rootLayer, settings)
+        , m_testHooks(testHooks)
     {
+        bool success = initialize();
+        ASSERT(success);
     }
 
-private:
-    CCLayerTreeHostTest* m_test;
+    TestHooks* m_testHooks;
 };
 
-class MockLayerTreeHostCommitter : public CCLayerTreeHostCommitter {
+// Test stub for WebGraphicsContext3D. Returns canned values needed for compositor initialization.
+class CompositorMockWebGraphicsContext3D : public MockWebGraphicsContext3D {
 public:
-    static PassOwnPtr<MockLayerTreeHostCommitter> create(CCLayerTreeHostTest* test)
+    static PassOwnPtr<CompositorMockWebGraphicsContext3D> create()
     {
-        return adoptPtr(new MockLayerTreeHostCommitter(test));
+        return adoptPtr(new CompositorMockWebGraphicsContext3D());
     }
 
-    virtual void commit(CCLayerTreeHost* host, CCLayerTreeHostImpl* hostImpl)
-    {
-        CCLayerTreeHostCommitter::commit(host, hostImpl);
-        m_test->commitOnCCThread(reinterpret_cast<MockLayerTreeHost*>(host), reinterpret_cast<MockLayerTreeHostImpl*>(hostImpl));
-    }
+    virtual bool makeContextCurrent() { return true; }
+    virtual WebGLId createProgram() { return 1; }
+    virtual WebGLId createShader(WGC3Denum) { return 1; }
+    virtual void getShaderiv(WebGLId, WGC3Denum, WGC3Dint* value) { *value = 1; }
+    virtual void getProgramiv(WebGLId, WGC3Denum, WGC3Dint* value) { *value = 1; }
 
 private:
-    MockLayerTreeHostCommitter(CCLayerTreeHostTest* test) : m_test(test) { }
-    CCLayerTreeHostTest* m_test;
+    CompositorMockWebGraphicsContext3D() { }
 };
 
-class MockLayerTreeHostImpl : public CCLayerTreeHostImpl {
+// Implementation of CCLayerTreeHost callback interface.
+class MockLayerTreeHostClient : public CCLayerTreeHostClient {
 public:
-    static PassOwnPtr<MockLayerTreeHostImpl> create(CCLayerTreeHostImplClient* client, CCLayerTreeHostTest* test)
+    static PassOwnPtr<MockLayerTreeHostClient> create(TestHooks* testHooks)
     {
-        return adoptPtr(new MockLayerTreeHostImpl(client, test));
+        return adoptPtr(new MockLayerTreeHostClient(testHooks));
     }
 
-    virtual void beginCommit()
+    virtual void animateAndLayout(double frameBeginTime)
     {
-        CCLayerTreeHostImpl::beginCommit();
-        m_test->beginCommitOnCCThread(this);
     }
 
-    virtual void commitComplete()
+    virtual PassOwnPtr<CCThread> createCompositorThread()
     {
-        CCLayerTreeHostImpl::commitComplete();
-        m_test->commitCompleteOnCCThread(this);
+        return CCThreadImpl::create();
     }
 
-    virtual void drawLayersAndPresent()
+    virtual PassRefPtr<GraphicsContext3D> createLayerTreeHostContext3D()
     {
-        m_test->drawLayersAndPresentOnCCThread(this);
+        OwnPtr<WebGraphicsContext3D> mock = CompositorMockWebGraphicsContext3D::create();
+        GraphicsContext3D::Attributes attrs;
+        RefPtr<GraphicsContext3D> context = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(mock.release(), attrs, 0, GraphicsContext3D::RenderDirectlyToHostWindow, GraphicsContext3DPrivate::ForUseOnAnotherThread);
+        return context;
     }
 
-private:
-    MockLayerTreeHostImpl(CCLayerTreeHostImplClient* client, CCLayerTreeHostTest* test)
-            : CCLayerTreeHostImpl(client)
-            , m_test(test)
+    virtual PassOwnPtr<LayerPainterChromium> createRootLayerPainter()
     {
+        return nullptr;
     }
 
-    CCLayerTreeHostTest* m_test;
+    virtual void didRecreateGraphicsContext(bool)
+    {
+    }
+
+private:
+    explicit MockLayerTreeHostClient(TestHooks* testHooks) : m_testHooks(testHooks) { }
+
+    TestHooks* m_testHooks;
 };
 
-class MockLayerTreeHostImplProxy : public CCLayerTreeHostImplProxy {
+// The CCLayerTreeHostTest runs with the main loop running. It instantiates a single MockLayerTreeHost and associated
+// MockLayerTreeHostImpl/MockLayerTreeHostClient.
+//
+// beginTest() is called once the main message loop is running and the layer tree host is initialized.
+//
+// Key stages of the drawing loop, e.g. drawing or commiting, redirect to CCLayerTreeHostTest methods of similar names.
+// To track the commit process, override these functions.
+//
+// The test continues until someone calls endTest. endTest can be called on any thread, but be aware that
+// ending the test is an asynchronous process.
+class CCLayerTreeHostTest : public testing::Test, TestHooks {
 public:
-    static PassOwnPtr<MockLayerTreeHostImplProxy> create(CCLayerTreeHost* host, CCLayerTreeHostTest* test)
+    virtual void afterTest() = 0;
+    virtual void beginTest() = 0;
+
+    void endTest();
+
+    void postSetNeedsCommitToMainThread()
     {
-        return adoptPtr(new MockLayerTreeHostImplProxy(host, test));
+        callOnMainThread(CCLayerTreeHostTest::dispatchSetNeedsCommit, this);
     }
 
-    PassOwnPtr<CCLayerTreeHostImpl> createLayerTreeHostImpl()
+    void postSetNeedsRedrawToMainThread()
     {
-        return MockLayerTreeHostImpl::create(this, m_test);
+        callOnMainThread(CCLayerTreeHostTest::dispatchSetNeedsRedraw, this);
     }
 
-private:
-    MockLayerTreeHostImplProxy(CCLayerTreeHost* host, CCLayerTreeHostTest* test)
-        : CCLayerTreeHostImplProxy(host)
-        , m_test(test) { }
+protected:
+    CCLayerTreeHostTest()
+        : m_beginning(false)
+        , m_endWhenBeginReturns(false)
+        , m_running(false)
+        , m_timedOut(false) { }
 
-    CCLayerTreeHostTest* m_test;
-};
+    void doBeginTest();
 
-class MockLayerTreeHost : public CCLayerTreeHost {
-public:
-    MockLayerTreeHost(CCLayerTreeHostClient* client, CCLayerTreeHostTest* test)
-        : CCLayerTreeHost(client)
-        , m_test(test) { }
+    static void onBeginTest(void* self)
+    {
+        static_cast<CCLayerTreeHostTest*>(self)->doBeginTest();
+    }
 
-    virtual PassOwnPtr<CCLayerTreeHostImplProxy> createLayerTreeHostImplProxy()
+    static void onEndTest(void* self)
     {
-        OwnPtr<CCLayerTreeHostImplProxy> proxy = MockLayerTreeHostImplProxy::create(this, m_test);
-        proxy->start();
-        return proxy.release();
+        ASSERT(isMainThread());
+        webkit_support::QuitMessageLoop();
+        CCLayerTreeHostTest* test = static_cast<CCLayerTreeHostTest*>(self);
+        ASSERT(test);
+        test->m_layerTreeHost.clear();
     }
 
-    virtual void updateLayers()
+    static void dispatchSetNeedsCommit(void* self)
     {
-        m_test->updateLayers(this);
+      ASSERT(isMainThread());
+      CCLayerTreeHostTest* test = static_cast<CCLayerTreeHostTest*>(self);
+      ASSERT(test);
+      if (test->m_layerTreeHost)
+          test->m_layerTreeHost->setNeedsCommitAndRedraw();
     }
 
-    virtual PassOwnPtr<CCLayerTreeHostCommitter> createLayerTreeHostCommitter()
+    static void dispatchSetNeedsRedraw(void* self)
     {
-        return MockLayerTreeHostCommitter::create(m_test);
+      ASSERT(isMainThread());
+      CCLayerTreeHostTest* test = static_cast<CCLayerTreeHostTest*>(self);
+      ASSERT(test);
+      if (test->m_layerTreeHost)
+          test->m_layerTreeHost->setNeedsRedraw();
     }
 
-    virtual void beginCommit()
+    void runTest()
     {
-        CCLayerTreeHost::beginCommit();
-        m_test->beginCommitOnMainThread(this);
+        webkit_support::PostDelayedTask(CCLayerTreeHostTest::onBeginTest, static_cast<void*>(this), 0);
+        webkit_support::PostDelayedTask(CCLayerTreeHostTest::testTimeout, static_cast<void*>(this), 5000);
+        webkit_support::RunMessageLoop();
+        m_running = false;
+        bool timedOut = m_timedOut; // Save whether we're timed out in case RunAllPendingMessages has the timeout.
+        webkit_support::RunAllPendingMessages();
+        ASSERT(!m_layerTreeHost.get());
+        m_client.clear();
+        if (timedOut) {
+            FAIL() << "Test timed out";
+            return;
+        }
+        afterTest();
     }
 
-    virtual void commitComplete()
+    static void testTimeout(void* self)
     {
-        m_test->commitCompleteOnMainThread(this);
-        CCLayerTreeHost::commitComplete();
+        CCLayerTreeHostTest* test = static_cast<CCLayerTreeHostTest*>(self);
+        if (!test->m_running)
+            return;
+        test->m_timedOut = true;
+        test->endTest();
     }
 
+    OwnPtr<MockLayerTreeHostClient> m_client;
+    RefPtr<CCLayerTreeHost> m_layerTreeHost;
+
 private:
-    CCLayerTreeHostTest* m_test;
+    bool m_beginning;
+    bool m_endWhenBeginReturns;
+    bool m_running;
+    bool m_timedOut;
 };
 
 void CCLayerTreeHostTest::doBeginTest()
 {
+    ASSERT(isMainThread());
     ASSERT(!m_running);
     m_running = true;
-    m_client = adoptPtr(new MockLayerTreeHostClient(this));
-    m_layerTreeHost = adoptRef(new MockLayerTreeHost(m_client.get(), this));
-    m_layerTreeHost->init();
+    m_client = MockLayerTreeHostClient::create(this);
+
+    CCSettings settings;
+    settings.enableCompositorThread = true;
+    RefPtr<LayerChromium> rootLayer;
+    m_layerTreeHost = MockLayerTreeHost::create(this, m_client.get(), rootLayer, settings);
+    ASSERT(m_layerTreeHost);
+
     m_beginning = true;
     beginTest();
     m_beginning = false;
@@ -327,7 +341,7 @@ public:
 
     virtual void beginTest()
     {
-        m_layerTreeHost->setNeedsCommitAndRedraw();
+        postSetNeedsCommitToMainThread();
         endTest();
     }
 
@@ -347,7 +361,7 @@ public:
 
     virtual void beginTest()
     {
-        m_layerTreeHost->setNeedsRedraw();
+        postSetNeedsRedrawToMainThread();
         endTest();
     }
 
@@ -371,23 +385,23 @@ public:
 
     virtual void beginTest()
     {
-        m_layerTreeHost->setNeedsCommitAndRedraw();
+        postSetNeedsCommitToMainThread();
         endTest();
     }
 
-    virtual void commitCompleteOnCCThread(MockLayerTreeHostImpl* layerTreeHostImpl)
+    virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl*)
     {
         m_numCompleteCommits++;
         if (m_numCompleteCommits == 2)
             endTest();
     }
 
-    virtual void drawLayersAndPresentOnCCThread(MockLayerTreeHostImpl* layerTreeHostImpl)
+    virtual void drawLayersOnCCThread(CCLayerTreeHostImpl*)
     {
         if (m_numDraws == 1)
-            layerTreeHostImpl->setNeedsCommitAndRedraw();
+          postSetNeedsCommitToMainThread();
         m_numDraws++;
-        layerTreeHostImpl->setNeedsRedraw();
+        postSetNeedsRedrawToMainThread();
     }
 
     virtual void afterTest()
@@ -415,18 +429,18 @@ public:
 
     virtual void beginTest()
     {
-        m_layerTreeHost->setNeedsCommitAndRedraw();
-        m_layerTreeHost->setNeedsCommitAndRedraw();
+        postSetNeedsCommitToMainThread();
+        postSetNeedsCommitToMainThread();
     }
 
-    virtual void drawLayersAndPresentOnCCThread(MockLayerTreeHostImpl* layerTreeHostImpl)
+    virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl)
     {
         m_numDraws++;
-        if (!layerTreeHostImpl->sourceFrameNumber())
+        if (!impl->sourceFrameNumber())
             endTest();
     }
 
-    virtual void commitOnCCThread(MockLayerTreeHost* layerTreeHost, MockLayerTreeHostImpl* impl)
+    virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl*)
     {
         m_numCommits++;
     }
@@ -458,18 +472,18 @@ public:
 
     virtual void beginTest()
     {
-        m_layerTreeHost->setNeedsCommitAndRedraw();
+        postSetNeedsCommitToMainThread();
     }
 
-    virtual void drawLayersAndPresentOnCCThread(MockLayerTreeHostImpl* layerTreeHostImpl)
+    virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl)
     {
-        if (!layerTreeHostImpl->sourceFrameNumber())
-            layerTreeHostImpl->setNeedsCommitAndRedraw();
-        else if (layerTreeHostImpl->sourceFrameNumber() == 1)
+        if (!impl->sourceFrameNumber())
+            postSetNeedsCommitToMainThread();
+        else if (impl->sourceFrameNumber() == 1)
             endTest();
     }
 
-    virtual void commitOnCCThread(MockLayerTreeHost* layerTreeHost, MockLayerTreeHostImpl* impl)
+    virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl*)
     {
         m_numCommits++;
     }
@@ -501,19 +515,20 @@ public:
 
     virtual void beginTest()
     {
+        postSetNeedsCommitToMainThread();
     }
 
-    virtual void drawLayersAndPresentOnCCThread(MockLayerTreeHostImpl* impl)
+    virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl)
     {
         EXPECT_EQ(0, impl->sourceFrameNumber());
         if (!m_numDraws)
-            impl->setNeedsRedraw(); // redraw again to verify that the second redraw doesnt commit.
+            postSetNeedsRedrawToMainThread(); // Redraw again to verify that the second redraw doesn't commit.
         else
             endTest();
         m_numDraws++;
     }
 
-    virtual void commitOnCCThread(MockLayerTreeHost* layerTreeHost, MockLayerTreeHostImpl* impl)
+    virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl*)
     {
         m_numCommits++;
     }