DebugScopedSetImplThread()
{
#if !ASSERT_DISABLED
- ASSERT(CCProxy::isMainThread());
CCProxy::setImplThread(true);
#endif
}
+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.
'tests/TreeSynchronizerTest.cpp',
'tests/TreeTestHelpers.cpp',
'tests/TreeTestHelpers.h',
+ 'tests/WebCompositorImplTest.cpp',
'tests/WebFrameTest.cpp',
'tests/WebURLRequestTest.cpp',
],
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;
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() { }
#include "WebCompositorClient.h"
#include "WebInputEvent.h"
#include "cc/CCThreadProxy.h"
+#include <wtf/ThreadingPrimitives.h>
using namespace WebCore;
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);
}
#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;
class WebCompositorImpl : public WebCompositor {
WTF_MAKE_NONCOPYABLE(WebCompositorImpl);
public:
+ static WebCompositor* fromIdentifier(int identifier);
+
static PassOwnPtr<WebCompositorImpl> create()
{
return adoptPtr(new WebCompositorImpl);
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;
};
}
#include "Vector.h"
#include "WebAccessibilityObject.h"
#include "WebAutofillClient.h"
+#include "WebCompositorImpl.h"
#include "WebDevToolsAgentImpl.h"
#include "WebDevToolsAgentPrivate.h"
#include "WebDragData.h"
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);
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)
} else {
m_isAcceleratedCompositingActive = false;
m_client->didActivateAcceleratedCompositing(false);
+ m_client->didDeactivateCompositor();
m_compositorCreationFailed = true;
}
}
class GeolocationClientProxy;
class SpeechInputClientImpl;
class WebAccessibilityObject;
+class WebCompositorImpl;
class WebDevToolsAgentClient;
class WebDevToolsAgentPrivate;
class WebFrameImpl;
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;
{
bool success = initialize();
ASSERT(success);
+ UNUSED_PARAM(success);
}
TestHooks* m_testHooks;
--- /dev/null
+/*
+ * 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));
+}
+
+}