[chromium] Hook WebCompositor interface for input events up to the compositor proper
authorjamesr@google.com <jamesr@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 5 Oct 2011 18:46:10 +0000 (18:46 +0000)
committerjamesr@google.com <jamesr@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 5 Oct 2011 18:46:10 +0000 (18:46 +0000)
https://bugs.webkit.org/show_bug.cgi?id=69394

Reviewed by Darin Fisher.

Source/WebCore:

This wires up WebCompositorImpl to the compositor itself so we can handle input events as scrolls on the
compositor thread, although it doesn't actually wire up any input events to actual scrolling. The way this
works:

- CCThreadProxy owns an adapter that implements the CCScrollController interface
- CCThreadProxy owns a CCInputHandler, which is implemented by WebKit::WebCompositorImpl, that has a pointer to
the adapter
- CCLayerTreeHost has an identifier (an int) for its WebKit::WebCompositorImpl that's initialized in
initializeLayerRenderer. This identifier is exposed to its owner (WebKit::WebViewImpl) so the embedder can wire
up the threading logic behind the scenes.

This is just plumbing, no change in behavior.

* WebCore.gypi:
* platform/graphics/chromium/cc/CCInputHandler.h: Added.
(WebCore::CCInputHandler::~CCInputHandler):
(WebCore::CCInputHandler::CCInputHandler):
* platform/graphics/chromium/cc/CCLayerTreeHost.cpp:
(WebCore::CCLayerTreeHost::CCLayerTreeHost):
(WebCore::CCLayerTreeHost::initialize):
* platform/graphics/chromium/cc/CCLayerTreeHost.h:
(WebCore::CCLayerTreeHost::compositorIdentifier):
* platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp:
(WebCore::CCLayerTreeHostImpl::scrollRootLayer):
* platform/graphics/chromium/cc/CCLayerTreeHostImpl.h:
* platform/graphics/chromium/cc/CCProxy.h:
* platform/graphics/chromium/cc/CCScrollController.h: Added.
(WebCore::CCScrollController::CCScrollController):
(WebCore::CCScrollController::~CCScrollController):
* platform/graphics/chromium/cc/CCSingleThreadProxy.cpp:
(WebCore::CCSingleThreadProxy::CCSingleThreadProxy):
* platform/graphics/chromium/cc/CCSingleThreadProxy.h:
(WebCore::CCSingleThreadProxy::compositorIdentifier):
* platform/graphics/chromium/cc/CCThreadProxy.cpp:
(WebCore::CCThreadProxyScrollControllerAdapter::create):
(WebCore::CCThreadProxyScrollControllerAdapter::~CCThreadProxyScrollControllerAdapter):
(WebCore::CCThreadProxyScrollControllerAdapter::scrollRootLayer):
(WebCore::CCThreadProxyScrollControllerAdapter::CCThreadProxyScrollControllerAdapter):
(WebCore::CCThreadProxy::CCThreadProxy):
(WebCore::CCThreadProxy::initializeLayerRenderer):
(WebCore::CCThreadProxy::compositorIdentifier):
(WebCore::CCThreadProxy::beginFrameAndCommit):
(WebCore::CCThreadProxy::initializeLayerRendererOnCCThread):
(WebCore::CCThreadProxy::layerTreeHostClosedOnCCThread):
* platform/graphics/chromium/cc/CCThreadProxy.h:

Source/WebKit/chromium:

This teaches WebCompositorImpl about WebCore::CCInputHandler, which WebCompositorImpl implements, and
CCScrollController, which WebCompositorImpl will use in the future to do actual scrolling. One thing that is a
bit unusual here is WebCore::CCInputHandler::create() which is defined in WebCompositorImpl.cpp.  This is
because we need a WebKit object (WebKit::WebCompositorImpl) to be owned by a WebCore object (WebCore::CCThreadProxy).
The WebCore side only needs to know about the interface, CCInputHandler, but the actual implementation has to
live in WebKit in order to know about the concrete type.

* src/WebCompositorImpl.cpp:
(WebCore::CCInputHandler::create):
(WebKit::WebCompositor::fromIdentifier):
(WebKit::WebCompositorImpl::fromIdentifier):
(WebKit::WebCompositorImpl::WebCompositorImpl):
(WebKit::WebCompositorImpl::~WebCompositorImpl):
(WebKit::WebCompositorImpl::setClient):
(WebKit::WebCompositorImpl::handleInputEvent):
(WebKit::WebCompositorImpl::identifier):
* src/WebCompositorImpl.h:
(WebKit::WebCompositorImpl::create):
* src/WebViewImpl.cpp:
(WebKit::WebViewImpl::setIsAcceleratedCompositingActive):
* src/WebViewImpl.h:
* tests/WebCompositorImplTest.cpp:

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

18 files changed:
Source/WebCore/ChangeLog
Source/WebCore/WebCore.gypi
Source/WebCore/platform/graphics/chromium/cc/CCInputHandler.h [new file with mode: 0644]
Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp
Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h
Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp
Source/WebCore/platform/graphics/chromium/cc/CCProxy.h
Source/WebCore/platform/graphics/chromium/cc/CCScrollController.h [new file with mode: 0644]
Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.cpp
Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.h
Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp
Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.h
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/src/WebCompositorImpl.cpp
Source/WebKit/chromium/src/WebCompositorImpl.h
Source/WebKit/chromium/src/WebViewImpl.cpp
Source/WebKit/chromium/src/WebViewImpl.h
Source/WebKit/chromium/tests/WebCompositorImplTest.cpp

index 56277ed..bce0052 100644 (file)
@@ -1,3 +1,56 @@
+2011-10-05  James Robinson  <jamesr@chromium.org>
+
+        [chromium] Hook WebCompositor interface for input events up to the compositor proper
+        https://bugs.webkit.org/show_bug.cgi?id=69394
+
+        Reviewed by Darin Fisher.
+
+        This wires up WebCompositorImpl to the compositor itself so we can handle input events as scrolls on the
+        compositor thread, although it doesn't actually wire up any input events to actual scrolling. The way this
+        works:
+
+        - CCThreadProxy owns an adapter that implements the CCScrollController interface
+        - CCThreadProxy owns a CCInputHandler, which is implemented by WebKit::WebCompositorImpl, that has a pointer to
+        the adapter
+        - CCLayerTreeHost has an identifier (an int) for its WebKit::WebCompositorImpl that's initialized in
+        initializeLayerRenderer. This identifier is exposed to its owner (WebKit::WebViewImpl) so the embedder can wire
+        up the threading logic behind the scenes.
+
+        This is just plumbing, no change in behavior.
+
+        * WebCore.gypi:
+        * platform/graphics/chromium/cc/CCInputHandler.h: Added.
+        (WebCore::CCInputHandler::~CCInputHandler):
+        (WebCore::CCInputHandler::CCInputHandler):
+        * platform/graphics/chromium/cc/CCLayerTreeHost.cpp:
+        (WebCore::CCLayerTreeHost::CCLayerTreeHost):
+        (WebCore::CCLayerTreeHost::initialize):
+        * platform/graphics/chromium/cc/CCLayerTreeHost.h:
+        (WebCore::CCLayerTreeHost::compositorIdentifier):
+        * platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp:
+        (WebCore::CCLayerTreeHostImpl::scrollRootLayer):
+        * platform/graphics/chromium/cc/CCLayerTreeHostImpl.h:
+        * platform/graphics/chromium/cc/CCProxy.h:
+        * platform/graphics/chromium/cc/CCScrollController.h: Added.
+        (WebCore::CCScrollController::CCScrollController):
+        (WebCore::CCScrollController::~CCScrollController):
+        * platform/graphics/chromium/cc/CCSingleThreadProxy.cpp:
+        (WebCore::CCSingleThreadProxy::CCSingleThreadProxy):
+        * platform/graphics/chromium/cc/CCSingleThreadProxy.h:
+        (WebCore::CCSingleThreadProxy::compositorIdentifier):
+        * platform/graphics/chromium/cc/CCThreadProxy.cpp:
+        (WebCore::CCThreadProxyScrollControllerAdapter::create):
+        (WebCore::CCThreadProxyScrollControllerAdapter::~CCThreadProxyScrollControllerAdapter):
+        (WebCore::CCThreadProxyScrollControllerAdapter::scrollRootLayer):
+        (WebCore::CCThreadProxyScrollControllerAdapter::CCThreadProxyScrollControllerAdapter):
+        (WebCore::CCThreadProxy::CCThreadProxy):
+        (WebCore::CCThreadProxy::initializeLayerRenderer):
+        (WebCore::CCThreadProxy::compositorIdentifier):
+        (WebCore::CCThreadProxy::beginFrameAndCommit):
+        (WebCore::CCThreadProxy::initializeLayerRendererOnCCThread):
+        (WebCore::CCThreadProxy::layerTreeHostClosedOnCCThread):
+        * platform/graphics/chromium/cc/CCThreadProxy.h:
+
 2011-10-05  Andreas Kling  <kling@webkit.org>
 
         Shrink OutlineValue.
index 5f39fe8..0b2faf0 100644 (file)
             'platform/graphics/chromium/cc/CCCanvasLayerImpl.h',
             'platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp',
             'platform/graphics/chromium/cc/CCHeadsUpDisplay.h',
+            'platform/graphics/chromium/cc/CCInputHandler.h',
             'platform/graphics/chromium/cc/CCLayerImpl.cpp',
             'platform/graphics/chromium/cc/CCLayerImpl.h',
             'platform/graphics/chromium/cc/CCLayerQuad.cpp',
             'platform/graphics/chromium/cc/CCTiledLayerImpl.h',
             'platform/graphics/chromium/cc/CCVideoLayerImpl.cpp',
             'platform/graphics/chromium/cc/CCVideoLayerImpl.h',
+            'platform/graphics/chromium/cc/CCScrollController.h',
             'platform/graphics/cocoa/FontPlatformDataCocoa.mm',
             'platform/graphics/efl/FontEfl.cpp',
             'platform/graphics/efl/IconEfl.cpp',
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCInputHandler.h b/Source/WebCore/platform/graphics/chromium/cc/CCInputHandler.h
new file mode 100644 (file)
index 0000000..efc40eb
--- /dev/null
@@ -0,0 +1,48 @@
+/* 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.
+ */
+
+#ifndef CCInputHandler_h
+#define CCInputHandler_h
+
+#include <wtf/Noncopyable.h>
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+class CCScrollController;
+
+class CCInputHandler {
+    WTF_MAKE_NONCOPYABLE(CCInputHandler);
+public:
+    static PassOwnPtr<CCInputHandler> create(CCScrollController*);
+    virtual ~CCInputHandler() { }
+
+    virtual int identifier() const = 0;
+
+protected:
+    CCInputHandler() { }
+};
+
+}
+
+#endif
index 7f3bb3e..ff7f40c 100644 (file)
@@ -48,7 +48,8 @@ PassRefPtr<CCLayerTreeHost> CCLayerTreeHost::create(CCLayerTreeHostClient* clien
 }
 
 CCLayerTreeHost::CCLayerTreeHost(CCLayerTreeHostClient* client, PassRefPtr<LayerChromium> rootLayer, const CCSettings& settings)
-    : m_animating(false)
+    : m_compositorIdentifier(-1)
+    , m_animating(false)
     , m_client(client)
     , m_frameNumber(0)
     , m_rootLayer(rootLayer)
@@ -76,6 +77,8 @@ bool CCLayerTreeHost::initialize()
     if (!m_proxy->initializeLayerRenderer())
         return false;
 
+    m_compositorIdentifier = m_proxy->compositorIdentifier();
+
     // Update m_settings based on capabilities that we got back from the renderer.
     m_settings.acceleratePainting = m_proxy->layerRendererCapabilities().usingAcceleratedPainting;
 
index 4774aeb..bdcb8f4 100644 (file)
@@ -113,6 +113,8 @@ public:
 
     CCLayerTreeHostClient* client() { return m_client; }
 
+    int compositorIdentifier() const { return m_compositorIdentifier; }
+
 #if !USE(THREADED_COMPOSITING)
     void composite();
 #endif
@@ -166,6 +168,8 @@ private:
     void updateCompositorResources(LayerChromium*, GraphicsContext3D*, TextureAllocator*);
     void clearPendingUpdate();
 
+    int m_compositorIdentifier;
+
     bool m_animating;
 
     CCLayerTreeHostClient* m_client;
index 71568a5..a339908 100644 (file)
@@ -161,6 +161,7 @@ void CCLayerTreeHostImpl::setZoomAnimatorTransform(const TransformationMatrix& z
 
 void CCLayerTreeHostImpl::scrollRootLayer(const IntSize& scrollDelta)
 {
+    TRACE_EVENT("CCLayerTreeHostImpl::scrollRootLayer", this, 0);
     if (!m_rootLayerImpl || !m_rootLayerImpl->scrollable())
         return;
 
index a860319..dfb77b3 100644 (file)
@@ -60,6 +60,8 @@ public:
 
     virtual bool initializeLayerRenderer() = 0;
 
+    virtual int compositorIdentifier() const = 0;
+
     virtual const LayerRendererCapabilities& layerRendererCapabilities() const = 0;
 
     virtual void setNeedsCommit() = 0;
diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCScrollController.h b/Source/WebCore/platform/graphics/chromium/cc/CCScrollController.h
new file mode 100644 (file)
index 0000000..bcd2f5f
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+#ifndef CCScrollController_h
+#define CCScrollController_h
+
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+class IntSize;
+
+class CCScrollController {
+    WTF_MAKE_NONCOPYABLE(CCScrollController);
+public:
+    virtual void scrollRootLayer(const IntSize&) = 0;
+
+protected:
+    CCScrollController() { }
+    virtual ~CCScrollController() { }
+};
+
+}
+
+#endif
index db0a0de..40908d8 100644 (file)
@@ -31,6 +31,7 @@
 #include "TraceEvent.h"
 #include "cc/CCLayerTreeHost.h"
 #include "cc/CCMainThreadTask.h"
+#include "cc/CCScrollController.h"
 #include <wtf/CurrentTime.h>
 
 using namespace WTF;
@@ -44,6 +45,7 @@ PassOwnPtr<CCProxy> CCSingleThreadProxy::create(CCLayerTreeHost* layerTreeHost)
 
 CCSingleThreadProxy::CCSingleThreadProxy(CCLayerTreeHost* layerTreeHost)
     : m_layerTreeHost(layerTreeHost)
+    , m_compositorIdentifier(-1)
     , m_numFailedRecreateAttempts(0)
     , m_graphicsContextLost(false)
     , m_timesRecreateShouldFail(0)
index d99361e..c618d46 100644 (file)
@@ -45,6 +45,7 @@ public:
     virtual void finishAllRendering();
     virtual bool isStarted() const;
     virtual bool initializeLayerRenderer();
+    virtual int compositorIdentifier() const { return m_compositorIdentifier; }
     virtual const LayerRendererCapabilities& layerRendererCapabilities() const;
     virtual void loseCompositorContext(int numTimes);
     virtual void setNeedsCommit();
@@ -66,6 +67,7 @@ private:
 
     // Accessed on main thread only.
     CCLayerTreeHost* m_layerTreeHost;
+    int m_compositorIdentifier;
 
     // Used on the CCThread, but checked on main thread during initialization/shutdown.
     OwnPtr<CCLayerTreeHostImpl> m_layerTreeHostImpl;
index a6f9898..9ee164a 100644 (file)
 
 #include "GraphicsContext3D.h"
 #include "TraceEvent.h"
+#include "cc/CCInputHandler.h"
 #include "cc/CCLayerTreeHost.h"
 #include "cc/CCMainThreadTask.h"
 #include "cc/CCScheduler.h"
+#include "cc/CCScrollController.h"
 #include "cc/CCThreadTask.h"
 #include <wtf/CurrentTime.h>
 #include <wtf/MainThread.h>
@@ -76,6 +78,30 @@ private:
     CCThreadProxy* m_proxy;
 };
 
+class CCThreadProxyScrollControllerAdapter : public CCScrollController {
+public:
+    static PassOwnPtr<CCThreadProxyScrollControllerAdapter> create(CCThreadProxy* proxy)
+    {
+        return adoptPtr(new CCThreadProxyScrollControllerAdapter(proxy));
+    }
+    virtual ~CCThreadProxyScrollControllerAdapter() { }
+
+    virtual void scrollRootLayer(const IntSize& offset)
+    {
+        m_proxy->m_layerTreeHostImpl->scrollRootLayer(offset);
+        m_proxy->setNeedsRedrawOnCCThread();
+        m_proxy->setNeedsCommitOnCCThread();
+    }
+
+private:
+    explicit CCThreadProxyScrollControllerAdapter(CCThreadProxy* proxy)
+    {
+        m_proxy = proxy;
+    }
+
+    CCThreadProxy* m_proxy;
+};
+
 PassOwnPtr<CCProxy> CCThreadProxy::create(CCLayerTreeHost* layerTreeHost)
 {
     return adoptPtr(new CCThreadProxy(layerTreeHost));
@@ -84,6 +110,7 @@ PassOwnPtr<CCProxy> CCThreadProxy::create(CCLayerTreeHost* layerTreeHost)
 CCThreadProxy::CCThreadProxy(CCLayerTreeHost* layerTreeHost)
     : m_commitRequested(false)
     , m_layerTreeHost(layerTreeHost)
+    , m_compositorIdentifier(-1)
     , m_started(false)
     , m_lastExecutedBeginFrameAndCommitSequenceNumber(-1)
     , m_numBeginFrameAndCommitsIssuedOnCCThread(0)
@@ -184,7 +211,9 @@ bool CCThreadProxy::initializeLayerRenderer()
     bool initializeSucceeded = false;
     LayerRendererCapabilities capabilities;
     s_ccThread->postTask(createCCThreadTask(this, &CCThreadProxy::initializeLayerRendererOnCCThread,
-                                          AllowCrossThreadAccess(contextPtr), AllowCrossThreadAccess(&completion), AllowCrossThreadAccess(&initializeSucceeded), AllowCrossThreadAccess(&capabilities)));
+                                          AllowCrossThreadAccess(contextPtr), AllowCrossThreadAccess(&completion),
+                                          AllowCrossThreadAccess(&initializeSucceeded), AllowCrossThreadAccess(&capabilities),
+                                          AllowCrossThreadAccess(&m_compositorIdentifier)));
     completion.wait();
 
     if (initializeSucceeded)
@@ -192,6 +221,12 @@ bool CCThreadProxy::initializeLayerRenderer()
     return initializeSucceeded;
 }
 
+int CCThreadProxy::compositorIdentifier() const
+{
+    ASSERT(isMainThread());
+    return m_compositorIdentifier;
+}
+
 const LayerRendererCapabilities& CCThreadProxy::layerRendererCapabilities() const
 {
     return m_layerRendererCapabilitiesMainThreadCopy;
@@ -328,8 +363,6 @@ void CCThreadProxy::beginFrameAndCommit(int sequenceNumber, double frameBeginTim
     }
     m_lastExecutedBeginFrameAndCommitSequenceNumber = sequenceNumber;
 
-    ASSERT(m_commitRequested);
-
     // FIXME: recreate the context if it was requested by the impl thread
     {
         TRACE_EVENT("CCLayerTreeHost::animateAndLayout", this, 0);
@@ -412,7 +445,7 @@ void CCThreadProxy::initializeImplOnCCThread(CCCompletionEvent* completion)
     completion->signal();
 }
 
-void CCThreadProxy::initializeLayerRendererOnCCThread(GraphicsContext3D* contextPtr, CCCompletionEvent* completion, bool* initializeSucceeded, LayerRendererCapabilities* capabilities)
+void CCThreadProxy::initializeLayerRendererOnCCThread(GraphicsContext3D* contextPtr, CCCompletionEvent* completion, bool* initializeSucceeded, LayerRendererCapabilities* capabilities, int* compositorIdentifier)
 {
     TRACE_EVENT("CCThreadProxy::initializeLayerRendererOnCCThread", this, 0);
     ASSERT(isImplThread());
@@ -420,6 +453,11 @@ void CCThreadProxy::initializeLayerRendererOnCCThread(GraphicsContext3D* context
     *initializeSucceeded = m_layerTreeHostImpl->initializeLayerRenderer(context);
     if (*initializeSucceeded)
         *capabilities = m_layerTreeHostImpl->layerRendererCapabilities();
+
+    m_scrollControllerAdapterOnCCThread = CCThreadProxyScrollControllerAdapter::create(this);
+    m_inputHandlerOnCCThread = CCInputHandler::create(m_scrollControllerAdapterOnCCThread.get());
+    *compositorIdentifier = m_inputHandlerOnCCThread->identifier();
+
     completion->signal();
 }
 
@@ -429,6 +467,8 @@ void CCThreadProxy::layerTreeHostClosedOnCCThread(CCCompletionEvent* completion)
     ASSERT(isImplThread());
     m_layerTreeHost->deleteContentsTexturesOnCCThread(m_layerTreeHostImpl->contentsTextureAllocator());
     m_layerTreeHostImpl.clear();
+    m_inputHandlerOnCCThread.clear();
+    m_scrollControllerAdapterOnCCThread.clear();
     completion->signal();
 }
 
index 32c9f6d..8bef682 100644 (file)
 
 namespace WebCore {
 
+class CCInputHandler;
 class CCLayerTreeHost;
 class CCScheduler;
 class CCThread;
 class CCThreadProxySchedulerClient;
+class CCThreadProxyScrollControllerAdapter;
 
 class CCThreadProxy : public CCProxy {
     friend class CCThreadProxySchedulerClient;
+    friend class CCThreadProxyScrollControllerAdapter;
 public:
     static void setThread(CCThread*);
 
@@ -53,6 +56,7 @@ public:
     virtual void finishAllRendering();
     virtual bool isStarted() const;
     virtual bool initializeLayerRenderer();
+    virtual int compositorIdentifier() const;
     virtual const LayerRendererCapabilities& layerRendererCapabilities() const;
     virtual void loseCompositorContext(int numTimes);
     virtual void setNeedsCommit();
@@ -76,7 +80,7 @@ private:
     void drawLayersAndReadbackOnCCThread(CCCompletionEvent*, bool* success, void* pixels, const IntRect&);
     void finishAllRenderingOnCCThread(CCCompletionEvent*);
     void initializeImplOnCCThread(CCCompletionEvent*);
-    void initializeLayerRendererOnCCThread(GraphicsContext3D*, CCCompletionEvent*, bool* initializeSucceeded, LayerRendererCapabilities*);
+    void initializeLayerRendererOnCCThread(GraphicsContext3D*, CCCompletionEvent*, bool* initializeSucceeded, LayerRendererCapabilities*, int* compositorIdentifier);
     void setNeedsCommitOnCCThread();
     void setNeedsRedrawOnCCThread();
     void setNeedsCommitThenRedrawOnCCThread();
@@ -86,6 +90,7 @@ private:
     bool m_commitRequested;
     bool m_redrawAfterCommit;
     CCLayerTreeHost* m_layerTreeHost;
+    int m_compositorIdentifier;
     LayerRendererCapabilities m_layerRendererCapabilitiesMainThreadCopy;
     bool m_started;
     int m_lastExecutedBeginFrameAndCommitSequenceNumber;
@@ -94,6 +99,9 @@ private:
     OwnPtr<CCLayerTreeHostImpl> m_layerTreeHostImpl;
     int m_numBeginFrameAndCommitsIssuedOnCCThread;
 
+    OwnPtr<CCInputHandler> m_inputHandlerOnCCThread;
+    OwnPtr<CCThreadProxyScrollControllerAdapter> m_scrollControllerAdapterOnCCThread;
+
     OwnPtr<CCScheduler> m_schedulerOnCCThread;
     OwnPtr<CCThreadProxySchedulerClient> m_schedulerClientOnCCThread;
 
index 7262eaa..0a66a8e 100644 (file)
@@ -1,3 +1,33 @@
+2011-10-05  James Robinson  <jamesr@chromium.org>
+
+        [chromium] Hook WebCompositor interface for input events up to the compositor proper
+        https://bugs.webkit.org/show_bug.cgi?id=69394
+
+        Reviewed by Darin Fisher.
+
+        This teaches WebCompositorImpl about WebCore::CCInputHandler, which WebCompositorImpl implements, and
+        CCScrollController, which WebCompositorImpl will use in the future to do actual scrolling. One thing that is a
+        bit unusual here is WebCore::CCInputHandler::create() which is defined in WebCompositorImpl.cpp.  This is
+        because we need a WebKit object (WebKit::WebCompositorImpl) to be owned by a WebCore object (WebCore::CCThreadProxy).
+        The WebCore side only needs to know about the interface, CCInputHandler, but the actual implementation has to
+        live in WebKit in order to know about the concrete type.
+
+        * src/WebCompositorImpl.cpp:
+        (WebCore::CCInputHandler::create):
+        (WebKit::WebCompositor::fromIdentifier):
+        (WebKit::WebCompositorImpl::fromIdentifier):
+        (WebKit::WebCompositorImpl::WebCompositorImpl):
+        (WebKit::WebCompositorImpl::~WebCompositorImpl):
+        (WebKit::WebCompositorImpl::setClient):
+        (WebKit::WebCompositorImpl::handleInputEvent):
+        (WebKit::WebCompositorImpl::identifier):
+        * src/WebCompositorImpl.h:
+        (WebKit::WebCompositorImpl::create):
+        * src/WebViewImpl.cpp:
+        (WebKit::WebViewImpl::setIsAcceleratedCompositingActive):
+        * src/WebViewImpl.h:
+        * tests/WebCompositorImplTest.cpp:
+
 2011-10-05  Anna Cavender  <annacc@chromium.org>
 
         Functions to make <track> enabled at runtime.
index 5f94b59..0286f19 100644 (file)
 #include "CCThreadImpl.h"
 #include "WebCompositorClient.h"
 #include "WebInputEvent.h"
+#include "cc/CCScrollController.h"
 #include "cc/CCThreadProxy.h"
 #include <wtf/ThreadingPrimitives.h>
 
 using namespace WebCore;
 
+namespace WebCore {
+
+PassOwnPtr<CCInputHandler> CCInputHandler::create(CCScrollController* scrollController)
+{
+    return WebKit::WebCompositorImpl::create(scrollController);
+}
+
+}
+
 namespace WebKit {
 
 void WebCompositor::setThread(WebThread* compositorThread)
@@ -43,27 +53,21 @@ void WebCompositor::setThread(WebThread* compositorThread)
     CCThreadProxy::setThread(CCThreadImpl::create(compositorThread).leakPtr());
 }
 
-int WebCompositorImpl::s_nextAvailableIdentifier = 1;
 
-// These data structures are always allocated from the main thread, but may
-// be accessed and mutated on the main or compositor thread.
-// s_compositors is deleted when it has no elements. s_compositorsLock is never
-// deleted.
+// These statics may only be accessed from the compositor thread.
+int WebCompositorImpl::s_nextAvailableIdentifier = 1;
 HashSet<WebCompositorImpl*>* WebCompositorImpl::s_compositors = 0;
-Mutex* WebCompositorImpl::s_compositorsLock = 0;
 
 WebCompositor* WebCompositor::fromIdentifier(int identifier)
 {
+    ASSERT(CCProxy::isImplThread());
     return WebCompositorImpl::fromIdentifier(identifier);
 }
 
 WebCompositor* WebCompositorImpl::fromIdentifier(int identifier)
 {
     ASSERT(CCProxy::isImplThread());
-    if (!s_compositorsLock)
-        return 0;
 
-    MutexLocker lock(*s_compositorsLock);
     if (!s_compositors)
         return 0;
 
@@ -74,14 +78,13 @@ WebCompositor* WebCompositorImpl::fromIdentifier(int identifier)
     return 0;
 }
 
-WebCompositorImpl::WebCompositorImpl()
+WebCompositorImpl::WebCompositorImpl(CCScrollController* scrollController)
     : m_client(0)
     , m_identifier(s_nextAvailableIdentifier++)
+    , m_scrollController(scrollController)
 {
-    ASSERT(CCProxy::isMainThread());
-    if (!s_compositorsLock)
-        s_compositorsLock = new Mutex;
-    MutexLocker lock(*s_compositorsLock);
+    ASSERT(CCProxy::isImplThread());
+
     if (!s_compositors)
         s_compositors = new HashSet<WebCompositorImpl*>;
     s_compositors->add(this);
@@ -89,11 +92,10 @@ WebCompositorImpl::WebCompositorImpl()
 
 WebCompositorImpl::~WebCompositorImpl()
 {
+    ASSERT(CCProxy::isImplThread());
     if (m_client)
         m_client->willShutdown();
 
-    ASSERT(s_compositorsLock);
-    MutexLocker lock(*s_compositorsLock);
     ASSERT(s_compositors);
     s_compositors->remove(this);
     if (!s_compositors->size()) {
@@ -105,16 +107,24 @@ WebCompositorImpl::~WebCompositorImpl()
 void WebCompositorImpl::setClient(WebCompositorClient* client)
 {
     ASSERT(CCProxy::isImplThread());
-    ASSERT(client);
+    // It's valid to set a new client if we've never had one or to clear the client, but it's not valid to change from having one client to a different one.
+    ASSERT(!m_client || !client);
     m_client = client;
 }
 
 void WebCompositorImpl::handleInputEvent(const WebInputEvent& event)
 {
     ASSERT(CCProxy::isImplThread());
-    // FIXME: Do something interesting with the event here.
+    ASSERT(m_client);
+    // FIXME: Do something interesting with this input event like inform our m_scrollController.
     m_client->didNotHandleInputEvent(true /* sendToWidget */);
 }
 
+int WebCompositorImpl::identifier() const
+{
+    ASSERT(CCProxy::isImplThread());
+    return m_identifier;
+}
+
 }
 
index ef19a45..f4e4e21 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "WebCompositor.h"
 
+#include "cc/CCInputHandler.h"
 #include <wtf/HashSet.h>
 #include <wtf/Noncopyable.h>
 #include <wtf/PassOwnPtr.h>
@@ -36,37 +37,42 @@ namespace WTF {
 class Mutex;
 }
 
+namespace WebCore {
+class CCScrollController;
+}
+
 namespace WebKit {
 
 class WebCompositorClient;
 
-class WebCompositorImpl : public WebCompositor {
+class WebCompositorImpl : public WebCompositor, public WebCore::CCInputHandler {
     WTF_MAKE_NONCOPYABLE(WebCompositorImpl);
 public:
     static WebCompositor* fromIdentifier(int identifier);
 
-    static PassOwnPtr<WebCompositorImpl> create()
+    static PassOwnPtr<WebCompositorImpl> create(WebCore::CCScrollController* scrollController)
     {
-        return adoptPtr(new WebCompositorImpl);
+        return adoptPtr(new WebCompositorImpl(scrollController));
     }
 
     virtual ~WebCompositorImpl();
 
+    // WebCompositor implementation
     virtual void setClient(WebCompositorClient*);
     virtual void handleInputEvent(const WebInputEvent&);
 
-    int identifier() const { return m_identifier; }
+    // WebCore::CCInputHandler implementation
+    virtual int identifier() const;
 
 private:
-    WebCompositorImpl();
+    explicit WebCompositorImpl(WebCore::CCScrollController*);
 
     WebCompositorClient* m_client;
     int m_identifier;
-
-    static HashSet<WebCompositorImpl*>* s_compositors;
-    static Mutex* s_compositorsLock;
+    WebCore::CCScrollController* m_scrollController;
 
     static int s_nextAvailableIdentifier;
+    static HashSet<WebCompositorImpl*>* s_compositors;
 };
 
 }
index 8951cab..e63740a 100644 (file)
@@ -2650,7 +2650,7 @@ void WebViewImpl::setIsAcceleratedCompositingActive(bool active)
         updateLayerTreeViewport();
 
         m_client->didActivateAcceleratedCompositing(true);
-        m_client->didActivateCompositor(m_webCompositorImpl->identifier());
+        m_client->didActivateCompositor(m_layerTreeHost->compositorIdentifier());
     } else {
         TRACE_EVENT("WebViewImpl::setIsAcceleratedCompositingActive(true)", this, 0);
 
@@ -2668,11 +2668,9 @@ void WebViewImpl::setIsAcceleratedCompositingActive(bool active)
         m_nonCompositedContentHost = NonCompositedContentHost::create(WebViewImplContentPainter::create(this));
         m_layerTreeHost = CCLayerTreeHost::create(this, m_nonCompositedContentHost->topLevelRootLayer()->platformLayer(), ccSettings);
         if (m_layerTreeHost) {
-            m_webCompositorImpl = WebCompositorImpl::create();
-            // FIXME: Hook the m_webCompositorImpl up with the CCLayerTreeHost somehow.
             updateLayerTreeViewport();
             m_client->didActivateAcceleratedCompositing(true);
-            m_client->didActivateCompositor(m_webCompositorImpl->identifier());
+            m_client->didActivateCompositor(m_layerTreeHost->compositorIdentifier());
             m_isAcceleratedCompositingActive = true;
             m_compositorCreationFailed = false;
             if (m_pageOverlay)
index 8fddb9d..b79e213 100644 (file)
@@ -576,7 +576,6 @@ private:
     WebCore::IntRect m_rootLayerScrollDamage;
     OwnPtr<WebCore::NonCompositedContentHost> m_nonCompositedContentHost;
     RefPtr<WebCore::CCLayerTreeHost> m_layerTreeHost;
-    OwnPtr<WebCompositorImpl> m_webCompositorImpl;
     WebCore::GraphicsLayer* m_rootGraphicsLayer;
     bool m_isAcceleratedCompositingActive;
     bool m_compositorCreationFailed;
index 7c436fa..a333369 100644 (file)
@@ -27,7 +27,7 @@
 
 #include "WebCompositorImpl.h"
 
-#include "cc/CCProxy.h"
+#include "cc/CCSingleThreadProxy.h"
 
 #include <gtest/gtest.h>
 #include <wtf/OwnPtr.h>
@@ -41,7 +41,7 @@ TEST(WebCompositorImpl, fromIdentifier)
 {
 #ifndef NDEBUG
     // WebCompositor APIs can only be called from the compositor thread.
-    WebCore::CCProxy::setImplThread(true);
+    WebCore::DebugScopedSetImplThread alwaysImplThread;
 #endif
 
     // Before creating any WebCompositors, lookups for any value should fail and not crash.
@@ -51,13 +51,7 @@ TEST(WebCompositorImpl, fromIdentifier)
 
     int compositorIdentifier = -1;
     {
-#ifndef NDEBUG
-        WebCore::CCProxy::setImplThread(false);
-#endif
-        OwnPtr<WebCompositorImpl> comp = WebCompositorImpl::create();
-#ifndef NDEBUG
-        WebCore::CCProxy::setImplThread(true);
-#endif
+        OwnPtr<WebCompositorImpl> comp = WebCompositorImpl::create(0);
         compositorIdentifier = comp->identifier();
         // The compositor we just created should be locatable.
         EXPECT_EQ(comp.get(), WebCompositor::fromIdentifier(compositorIdentifier));