[chromium] Add WebWidget API for accessing the current WebCompositor
authorjamesr@google.com <jamesr@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 3 Oct 2011 19:52:01 +0000 (19:52 +0000)
committerjamesr@google.com <jamesr@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 3 Oct 2011 19:52:01 +0000 (19:52 +0000)
https://bugs.webkit.org/show_bug.cgi?id=69181

Reviewed by Darin Fisher.

Add new WebWidgetClient::did(Activate|Deactivate)Compositor calls intended to replace
didActivateAccleratedCompositing(bool) so that the enable call can be parameterized.

Add a WebCompositor identifier parameter to didEnableAcceleratedCompositing that can be used on the compositor
thread to get access to a WebCompositor pointer.

* public/WebWidget.h:
(WebKit::WebWidget::compositor):
* src/WebViewImpl.cpp:
(WebKit::WebViewImpl::compositor):
(WebKit::WebViewImpl::setIsAcceleratedCompositingActive):
* src/WebViewImpl.h:

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

Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.h
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/WebKit.gypi
Source/WebKit/chromium/public/WebCompositor.h
Source/WebKit/chromium/public/WebWidgetClient.h
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/CCLayerTreeHostTest.cpp
Source/WebKit/chromium/tests/WebCompositorImplTest.cpp [new file with mode: 0644]

index eb74314..0231a92 100644 (file)
@@ -83,7 +83,6 @@ public:
     DebugScopedSetImplThread()
     {
 #if !ASSERT_DISABLED
-        ASSERT(CCProxy::isMainThread());
         CCProxy::setImplThread(true);
 #endif
     }
index 2169a77..ee8c5e7 100644 (file)
@@ -1,3 +1,23 @@
+2011-10-03  James Robinson  <jamesr@chromium.org>
+
+        [chromium] Add WebWidget API for accessing the current WebCompositor
+        https://bugs.webkit.org/show_bug.cgi?id=69181
+
+        Reviewed by Darin Fisher.
+
+        Add new WebWidgetClient::did(Activate|Deactivate)Compositor calls intended to replace
+        didActivateAccleratedCompositing(bool) so that the enable call can be parameterized.
+
+        Add a WebCompositor identifier parameter to didEnableAcceleratedCompositing that can be used on the compositor
+        thread to get access to a WebCompositor pointer.
+
+        * public/WebWidget.h:
+        (WebKit::WebWidget::compositor):
+        * src/WebViewImpl.cpp:
+        (WebKit::WebViewImpl::compositor):
+        (WebKit::WebViewImpl::setIsAcceleratedCompositingActive):
+        * src/WebViewImpl.h:
+
 2011-10-03  Sheriff Bot  <webkit.review.bot@gmail.com>
 
         Unreviewed, rolling out r96481.
index 147e428..d5be717 100644 (file)
@@ -76,6 +76,7 @@
             'tests/TreeSynchronizerTest.cpp',
             'tests/TreeTestHelpers.cpp',
             'tests/TreeTestHelpers.h',
+            'tests/WebCompositorImplTest.cpp',
             'tests/WebFrameTest.cpp',
             'tests/WebURLRequestTest.cpp',
         ],
index 7949b6a..79b8bc5 100644 (file)
@@ -40,6 +40,7 @@ class WebCompositor {
 public:
     // This must be called once with a non-null WebThread before any compositors attempt to initialize.
     WEBKIT_EXPORT static void setThread(WebThread*);
+    WEBKIT_EXPORT static WebCompositor* fromIdentifier(int);
 
     virtual void setClient(WebCompositorClient*) = 0;
     virtual void handleInputEvent(const WebInputEvent&) = 0;
index 60b4abf..76def11 100644 (file)
@@ -52,8 +52,15 @@ public:
     virtual void didScrollRect(int dx, int dy, const WebRect& clipRect) { }
 
     // Called when the compositor enables or disables.
+    // FIXME: Remove when all implementations switch over to didEnable.../didDisable...
     virtual void didActivateAcceleratedCompositing(bool active) { }
 
+    // Called when the compositor is enabled or disabled.
+    // The WebCompositor identifier can be used on the compositor thread to get access
+    // to the WebCompositor instance associated with this WebWidget.
+    virtual void didActivateCompositor(int compositorIdentifier) { }
+    virtual void didDeactivateCompositor() { }
+
     // Called when a call to WebWidget::composite is required
     virtual void scheduleComposite() { }
 
index b718eb4..f8935fc 100644 (file)
@@ -31,6 +31,7 @@
 #include "WebCompositorClient.h"
 #include "WebInputEvent.h"
 #include "cc/CCThreadProxy.h"
+#include <wtf/ThreadingPrimitives.h>
 
 using namespace WebCore;
 
@@ -42,23 +43,72 @@ 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.
+HashSet<WebCompositorImpl*>* WebCompositorImpl::s_compositors = 0;
+Mutex* WebCompositorImpl::s_compositorsLock = 0;
+
+WebCompositor* WebCompositor::fromIdentifier(int identifier)
+{
+    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;
+
+    for (HashSet<WebCompositorImpl*>::iterator it = s_compositors->begin(); it != s_compositors->end(); ++it) {
+        if ((*it)->identifier() == identifier)
+            return *it;
+    }
+    return 0;
+}
+
 WebCompositorImpl::WebCompositorImpl()
     : m_client(0)
+    , m_identifier(s_nextAvailableIdentifier++)
 {
+    ASSERT(CCProxy::isMainThread());
+    if (!s_compositorsLock)
+        s_compositorsLock = new Mutex;
+    MutexLocker lock(*s_compositorsLock);
+    if (!s_compositors)
+        s_compositors = new HashSet<WebCompositorImpl*>;
+    s_compositors->add(this);
 }
 
 WebCompositorImpl::~WebCompositorImpl()
 {
+    ASSERT(s_compositorsLock);
+    MutexLocker lock(*s_compositorsLock);
+    ASSERT(s_compositors);
+    s_compositors->remove(this);
+    if (!s_compositors->size()) {
+        delete s_compositors;
+        s_compositors = 0;
+    }
 }
 
 void WebCompositorImpl::setClient(WebCompositorClient* client)
 {
+    ASSERT(CCProxy::isImplThread());
     ASSERT(client);
     m_client = client;
 }
 
 void WebCompositorImpl::handleInputEvent(const WebInputEvent& event)
 {
+    ASSERT(CCProxy::isImplThread());
     // FIXME: Do something interesting with the event here.
     m_client->didHandleInputEvent(false);
 }
index 283af6f..ef19a45 100644 (file)
 #define WebCompositorImpl_h
 
 #include "WebCompositor.h"
+
+#include <wtf/HashSet.h>
 #include <wtf/Noncopyable.h>
 #include <wtf/PassOwnPtr.h>
 
+namespace WTF {
+class Mutex;
+}
+
 namespace WebKit {
 
 class WebCompositorClient;
@@ -37,6 +43,8 @@ class WebCompositorClient;
 class WebCompositorImpl : public WebCompositor {
     WTF_MAKE_NONCOPYABLE(WebCompositorImpl);
 public:
+    static WebCompositor* fromIdentifier(int identifier);
+
     static PassOwnPtr<WebCompositorImpl> create()
     {
         return adoptPtr(new WebCompositorImpl);
@@ -47,10 +55,18 @@ public:
     virtual void setClient(WebCompositorClient*);
     virtual void handleInputEvent(const WebInputEvent&);
 
+    int identifier() const { return m_identifier; }
+
 private:
     WebCompositorImpl();
 
     WebCompositorClient* m_client;
+    int m_identifier;
+
+    static HashSet<WebCompositorImpl*>* s_compositors;
+    static Mutex* s_compositorsLock;
+
+    static int s_nextAvailableIdentifier;
 };
 
 }
index b3b17ba..8a262b8 100644 (file)
 #include "Vector.h"
 #include "WebAccessibilityObject.h"
 #include "WebAutofillClient.h"
+#include "WebCompositorImpl.h"
 #include "WebDevToolsAgentImpl.h"
 #include "WebDevToolsAgentPrivate.h"
 #include "WebDragData.h"
@@ -2645,11 +2646,13 @@ void WebViewImpl::setIsAcceleratedCompositingActive(bool active)
         if (m_layerTreeHost)
             m_layerTreeHost->finishAllRendering();
         m_client->didActivateAcceleratedCompositing(false);
+        m_client->didDeactivateCompositor();
     } else if (m_layerTreeHost) {
         m_isAcceleratedCompositingActive = true;
         updateLayerTreeViewport();
 
         m_client->didActivateAcceleratedCompositing(true);
+        m_client->didActivateCompositor(m_webCompositorImpl->identifier());
     } else {
         TRACE_EVENT("WebViewImpl::setIsAcceleratedCompositingActive(true)", this, 0);
 
@@ -2667,8 +2670,11 @@ 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_isAcceleratedCompositingActive = true;
             m_compositorCreationFailed = false;
             if (m_pageOverlay)
@@ -2676,6 +2682,7 @@ void WebViewImpl::setIsAcceleratedCompositingActive(bool active)
         } else {
             m_isAcceleratedCompositingActive = false;
             m_client->didActivateAcceleratedCompositing(false);
+            m_client->didDeactivateCompositor();
             m_compositorCreationFailed = true;
         }
     }
index 92d5f38..8fddb9d 100644 (file)
@@ -82,6 +82,7 @@ class DragScrollTimer;
 class GeolocationClientProxy;
 class SpeechInputClientImpl;
 class WebAccessibilityObject;
+class WebCompositorImpl;
 class WebDevToolsAgentClient;
 class WebDevToolsAgentPrivate;
 class WebFrameImpl;
@@ -575,6 +576,7 @@ 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 95bdf1b..115a466 100644 (file)
@@ -117,6 +117,7 @@ private:
     {
         bool success = initialize();
         ASSERT(success);
+        UNUSED_PARAM(success);
     }
 
     TestHooks* m_testHooks;
diff --git a/Source/WebKit/chromium/tests/WebCompositorImplTest.cpp b/Source/WebKit/chromium/tests/WebCompositorImplTest.cpp
new file mode 100644 (file)
index 0000000..7c436fa
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * 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 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 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 "WebCompositorImpl.h"
+
+#include "cc/CCProxy.h"
+
+#include <gtest/gtest.h>
+#include <wtf/OwnPtr.h>
+
+using WebKit::WebCompositor;
+using WebKit::WebCompositorImpl;
+
+namespace {
+
+TEST(WebCompositorImpl, fromIdentifier)
+{
+#ifndef NDEBUG
+    // WebCompositor APIs can only be called from the compositor thread.
+    WebCore::CCProxy::setImplThread(true);
+#endif
+
+    // Before creating any WebCompositors, lookups for any value should fail and not crash.
+    EXPECT_EQ(0, WebCompositor::fromIdentifier(2));
+    EXPECT_EQ(0, WebCompositor::fromIdentifier(0));
+    EXPECT_EQ(0, WebCompositor::fromIdentifier(-1));
+
+    int compositorIdentifier = -1;
+    {
+#ifndef NDEBUG
+        WebCore::CCProxy::setImplThread(false);
+#endif
+        OwnPtr<WebCompositorImpl> comp = WebCompositorImpl::create();
+#ifndef NDEBUG
+        WebCore::CCProxy::setImplThread(true);
+#endif
+        compositorIdentifier = comp->identifier();
+        // The compositor we just created should be locatable.
+        EXPECT_EQ(comp.get(), WebCompositor::fromIdentifier(compositorIdentifier));
+
+        // But nothing else.
+        EXPECT_EQ(0, WebCompositor::fromIdentifier(comp->identifier() + 10));
+    }
+
+    // After the compositor is destroyed, its entry should be removed from the map.
+    EXPECT_EQ(0, WebCompositor::fromIdentifier(compositorIdentifier));
+}
+
+}