Skip to content
Permalink
Browse files
[chromium] Plumb a compositor surface ready notification through to t…
…he threaded compositor

https://bugs.webkit.org/show_bug.cgi?id=84305

Patch by James Robinson <jamesr@chromium.org> on 2012-04-20
Reviewed by Adrienne Walker.

Source/Platform:

Add a notification for when the compositor surface associated with a given view is ready to use.

* chromium/public/WebLayerTreeView.h:
(WebLayerTreeView):

Source/WebCore:

Plumb setSurfaceReady through to the scheduler.

* platform/graphics/chromium/cc/CCLayerTreeHost.cpp:
(WebCore::CCLayerTreeHost::setSurfaceReady):
(WebCore):
* platform/graphics/chromium/cc/CCLayerTreeHost.h:
(CCLayerTreeHost):
* platform/graphics/chromium/cc/CCProxy.h:
(CCProxy):
* platform/graphics/chromium/cc/CCSingleThreadProxy.cpp:
(WebCore::CCSingleThreadProxy::setSurfaceReady):
(WebCore):
* platform/graphics/chromium/cc/CCSingleThreadProxy.h:
(CCSingleThreadProxy):
* platform/graphics/chromium/cc/CCThreadProxy.cpp:
(WebCore::CCThreadProxy::setSurfaceReady):
(WebCore):
(WebCore::CCThreadProxy::setSurfaceReadyOnImplThread):
(WebCore::CCThreadProxy::initializeImplOnImplThread):
* platform/graphics/chromium/cc/CCThreadProxy.h:
(CCThreadProxy):

Source/WebKit/chromium:

Adds a notification to WebWidget for when the compositor surface is ready to use. This exists to fix a race
condition when WebKit requires that we enter compositing mode but we haven't completed initialization of the
native window/etc backing the WebWidget, and we can't block for this initialization to complete without inducing
deadlocks. In this situation, we proceed as usual except that we can't attempt to use the compositor context or
it will fail.

* public/WebWidget.h:
(WebWidget):
* src/WebLayerTreeView.cpp:
(WebKit::WebLayerTreeView::setSurfaceReady):
(WebKit):
* src/WebPagePopupImpl.cpp:
(WebKit::WebPagePopupImpl::setCompositorSurfaceReady):
(WebKit):
* src/WebPagePopupImpl.h:
(WebPagePopupImpl):
* src/WebPopupMenuImpl.cpp:
(WebKit::WebPopupMenuImpl::setCompositorSurfaceReady):
(WebKit):
* src/WebPopupMenuImpl.h:
* src/WebViewImpl.cpp:
(WebKit::WebViewImpl::setCompositorSurfaceReady):
(WebKit):
(WebKit::WebViewImpl::setIsAcceleratedCompositingActive):
* src/WebViewImpl.h:
(WebViewImpl):

Canonical link: https://commits.webkit.org/101991@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@114800 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
jamesr authored and webkit-commit-queue committed Apr 20, 2012
1 parent 28e1adc commit 32031a556ad775e6c1d6571524218da9fa8541b1
Showing 20 changed files with 144 additions and 1 deletion.
@@ -1,3 +1,15 @@
2012-04-20 James Robinson <jamesr@chromium.org>

[chromium] Plumb a compositor surface ready notification through to the threaded compositor
https://bugs.webkit.org/show_bug.cgi?id=84305

Reviewed by Adrienne Walker.

Add a notification for when the compositor surface associated with a given view is ready to use.

* chromium/public/WebLayerTreeView.h:
(WebLayerTreeView):

2012-04-16 James Robinson <jamesr@chromium.org>

[chromium] Convert WebPluginContainerImpl over to use WebExternalTextureLayer
@@ -85,6 +85,11 @@ class WebLayerTreeView : public WebNonCopyable {
// Must be called before any methods below.
WEBKIT_EXPORT bool initialize(WebLayerTreeViewClient*, const WebLayer& root, const Settings&);

// Indicates that the compositing surface used by this WebLayerTreeView is ready to use.
// A WebLayerTreeView may request a context from its client before the surface is ready,
// but it won't attempt to use it.
WEBKIT_EXPORT void setSurfaceReady();

// Sets the root of the tree. The root is set by way of the constructor.
// This is typically used to explicitly set the root to null to break
// cycles.
@@ -1,3 +1,32 @@
2012-04-20 James Robinson <jamesr@chromium.org>

[chromium] Plumb a compositor surface ready notification through to the threaded compositor
https://bugs.webkit.org/show_bug.cgi?id=84305

Reviewed by Adrienne Walker.

Plumb setSurfaceReady through to the scheduler.

* platform/graphics/chromium/cc/CCLayerTreeHost.cpp:
(WebCore::CCLayerTreeHost::setSurfaceReady):
(WebCore):
* platform/graphics/chromium/cc/CCLayerTreeHost.h:
(CCLayerTreeHost):
* platform/graphics/chromium/cc/CCProxy.h:
(CCProxy):
* platform/graphics/chromium/cc/CCSingleThreadProxy.cpp:
(WebCore::CCSingleThreadProxy::setSurfaceReady):
(WebCore):
* platform/graphics/chromium/cc/CCSingleThreadProxy.h:
(CCSingleThreadProxy):
* platform/graphics/chromium/cc/CCThreadProxy.cpp:
(WebCore::CCThreadProxy::setSurfaceReady):
(WebCore):
(WebCore::CCThreadProxy::setSurfaceReadyOnImplThread):
(WebCore::CCThreadProxy::initializeImplOnImplThread):
* platform/graphics/chromium/cc/CCThreadProxy.h:
(CCThreadProxy):

2012-04-20 Mark Pilgrim <pilgrim@chromium.org>

[Chromium] Call memoryUsageMB directly
@@ -123,6 +123,11 @@ CCLayerTreeHost::~CCLayerTreeHost()
numLayerTreeInstances--;
}

void CCLayerTreeHost::setSurfaceReady()
{
m_proxy->setSurfaceReady();
}

void CCLayerTreeHost::initializeLayerRenderer()
{
TRACE_EVENT("CCLayerTreeHost::initializeLayerRenderer", this, 0);
@@ -128,6 +128,8 @@ class CCLayerTreeHost : public RateLimiterClient {
static PassOwnPtr<CCLayerTreeHost> create(CCLayerTreeHostClient*, const CCSettings&);
virtual ~CCLayerTreeHost();

void setSurfaceReady();

// Returns true if any CCLayerTreeHost is alive.
static bool anyLayerTreeHostInstanceExists();

@@ -67,6 +67,9 @@ class CCProxy {
// The context will not be used and no frames may be produced until initializeLayerRenderer() is called.
virtual bool initializeContext() = 0;

// Indicates that the compositing surface associated with our context is ready to use.
virtual void setSurfaceReady() = 0;

// Attempts to initialize the layer renderer. Returns false if the context isn't usable for compositing.
virtual bool initializeLayerRenderer() = 0;

@@ -126,6 +126,11 @@ bool CCSingleThreadProxy::initializeContext()
return true;
}

void CCSingleThreadProxy::setSurfaceReady()
{
// Scheduling is controlled by the embedder in the single thread case, so nothing to do.
}

bool CCSingleThreadProxy::initializeLayerRenderer()
{
ASSERT(CCProxy::isMainThread());
@@ -48,6 +48,7 @@ class CCSingleThreadProxy : public CCProxy, CCLayerTreeHostImplClient {
virtual void finishAllRendering() OVERRIDE;
virtual bool isStarted() const OVERRIDE;
virtual bool initializeContext() OVERRIDE;
virtual void setSurfaceReady() OVERRIDE;
virtual bool initializeLayerRenderer() OVERRIDE;
virtual bool recreateContext() OVERRIDE;
virtual int compositorIdentifier() const OVERRIDE { return m_compositorIdentifier; }
@@ -180,6 +180,18 @@ bool CCThreadProxy::initializeContext()
return true;
}

void CCThreadProxy::setSurfaceReady()
{
TRACE_EVENT0("cc", "CCThreadProxy::setSurfaceReady");
CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::setSurfaceReadyOnImplThread));
}

void CCThreadProxy::setSurfaceReadyOnImplThread()
{
TRACE_EVENT0("cc", "CCThreadProxy::setSurfaceReadyOnImplThread");
m_schedulerOnImplThread->setCanBeginFrame(true);
}

bool CCThreadProxy::initializeLayerRenderer()
{
TRACE_EVENT("CCThreadProxy::initializeLayerRenderer", this, 0);
@@ -711,7 +723,6 @@ void CCThreadProxy::initializeImplOnImplThread(CCCompletionEvent* completion)
const double displayRefreshInterval = 1.0 / 60.0;
OwnPtr<CCFrameRateController> frameRateController = adoptPtr(new CCFrameRateController(CCDelayBasedTimeSource::create(displayRefreshInterval, CCProxy::implThread())));
m_schedulerOnImplThread = CCScheduler::create(this, frameRateController.release());
m_schedulerOnImplThread->setCanBeginFrame(true); // FIXME: Set this when we actually can begin a frame.
m_schedulerOnImplThread->setVisible(m_layerTreeHostImpl->visible());

m_inputHandlerOnImplThread = CCInputHandler::create(m_layerTreeHostImpl.get());
@@ -57,6 +57,7 @@ class CCThreadProxy : public CCProxy, CCLayerTreeHostImplClient, CCSchedulerClie
virtual void finishAllRendering() OVERRIDE;
virtual bool isStarted() const OVERRIDE;
virtual bool initializeContext() OVERRIDE;
virtual void setSurfaceReady() OVERRIDE;
virtual bool initializeLayerRenderer() OVERRIDE;
virtual bool recreateContext() OVERRIDE;
virtual int compositorIdentifier() const OVERRIDE;
@@ -129,6 +130,7 @@ class CCThreadProxy : public CCProxy, CCLayerTreeHostImplClient, CCSchedulerClie
void requestStartPageScaleAnimationOnImplThread(IntSize targetPosition, bool useAnchor, float scale, double durationSec);
void finishAllRenderingOnImplThread(CCCompletionEvent*);
void initializeImplOnImplThread(CCCompletionEvent*);
void setSurfaceReadyOnImplThread();
void initializeContextOnImplThread(GraphicsContext3D*);
void initializeLayerRendererOnImplThread(CCCompletionEvent*, bool* initializeSucceeded, LayerRendererCapabilities*);
void setVisibleOnImplThread(CCCompletionEvent*, bool visible);
@@ -1,3 +1,37 @@
2012-04-20 James Robinson <jamesr@chromium.org>

[chromium] Plumb a compositor surface ready notification through to the threaded compositor
https://bugs.webkit.org/show_bug.cgi?id=84305

Reviewed by Adrienne Walker.

Adds a notification to WebWidget for when the compositor surface is ready to use. This exists to fix a race
condition when WebKit requires that we enter compositing mode but we haven't completed initialization of the
native window/etc backing the WebWidget, and we can't block for this initialization to complete without inducing
deadlocks. In this situation, we proceed as usual except that we can't attempt to use the compositor context or
it will fail.

* public/WebWidget.h:
(WebWidget):
* src/WebLayerTreeView.cpp:
(WebKit::WebLayerTreeView::setSurfaceReady):
(WebKit):
* src/WebPagePopupImpl.cpp:
(WebKit::WebPagePopupImpl::setCompositorSurfaceReady):
(WebKit):
* src/WebPagePopupImpl.h:
(WebPagePopupImpl):
* src/WebPopupMenuImpl.cpp:
(WebKit::WebPopupMenuImpl::setCompositorSurfaceReady):
(WebKit):
* src/WebPopupMenuImpl.h:
* src/WebViewImpl.cpp:
(WebKit::WebViewImpl::setCompositorSurfaceReady):
(WebKit):
(WebKit::WebViewImpl::setIsAcceleratedCompositingActive):
* src/WebViewImpl.h:
(WebViewImpl):

2012-04-20 Mark Pilgrim <pilgrim@chromium.org>

[Chromium] Call memoryUsageMB directly
@@ -40,6 +40,7 @@
#include "platform/WebSize.h"

#define WEBKIT_HAS_NEW_FULLSCREEN_API 1
#define WEBWIDGET_HAS_SETCOMPOSITORSURFACEREADY 1

namespace WebKit {

@@ -107,6 +108,10 @@ class WebWidget {
// animate or layout in this case.
virtual void composite(bool finish) = 0;

// Indicates that the compositing surface associated with this WebWidget is
// ready to use.
virtual void setCompositorSurfaceReady() = 0;

// Temporary method for the embedder to notify the WebWidget that the widget
// has taken damage, e.g. due to a window expose. This method will be
// removed when the WebWidget inversion patch lands --- http://crbug.com/112837
@@ -69,6 +69,11 @@ bool WebLayerTreeView::initialize(WebLayerTreeViewClient* client, const WebLayer
return !isNull();
}

void WebLayerTreeView::setSurfaceReady()
{
m_private->setSurfaceReady();
}

void WebLayerTreeView::setRootLayer(WebLayer *root)
{
if (root)
@@ -209,6 +209,10 @@ void WebPagePopupImpl::animate(double)
PageWidgetDelegate::animate(m_page.get(), monotonicallyIncreasingTime());
}

void WebPagePopupImpl::setCompositorSurfaceReady()
{
}

void WebPagePopupImpl::composite(bool)
{
}
@@ -65,6 +65,7 @@ class WebPagePopupImpl : public WebPagePopup,
// WebWidget functions
virtual WebSize size() OVERRIDE;
virtual void animate(double) OVERRIDE;
virtual void setCompositorSurfaceReady() OVERRIDE;
virtual void composite(bool) OVERRIDE;
virtual void layout() OVERRIDE;
virtual void paint(WebCanvas*, const WebRect&) OVERRIDE;
@@ -207,6 +207,11 @@ void WebPopupMenuImpl::themeChanged()
notImplemented();
}

void WebPopupMenuImpl::setCompositorSurfaceReady()
{
notImplemented();
}

void WebPopupMenuImpl::composite(bool)
{
notImplemented();
@@ -75,6 +75,7 @@ class WebPopupMenuImpl : public WebPopupMenu,
virtual void layout() OVERRIDE;
virtual void paint(WebCanvas*, const WebRect&) OVERRIDE;
virtual void themeChanged() OVERRIDE;
virtual void setCompositorSurfaceReady() OVERRIDE;
virtual void composite(bool finish) OVERRIDE;
virtual bool handleInputEvent(const WebInputEvent&) OVERRIDE;
virtual void mouseCaptureLost() OVERRIDE;
@@ -384,6 +384,7 @@ WebViewImpl::WebViewImpl(WebViewClient* client)
, m_isAcceleratedCompositingActive(false)
, m_compositorCreationFailed(false)
, m_recreatingGraphicsContext(false)
, m_compositorSurfaceReady(false)
#endif
#if ENABLE(INPUT_SPEECH)
, m_speechInputClient(SpeechInputClientImpl::create(client))
@@ -1401,6 +1402,13 @@ void WebViewImpl::updateBatteryStatus(const WebBatteryStatus& status)
}
#endif

void WebViewImpl::setCompositorSurfaceReady()
{
m_compositorSurfaceReady = true;
if (!m_layerTreeView.isNull())
m_layerTreeView.setSurfaceReady();
}

void WebViewImpl::animate(double)
{
#if ENABLE(REQUEST_ANIMATION_FRAME)
@@ -3269,6 +3277,8 @@ void WebViewImpl::setIsAcceleratedCompositingActive(bool active)
m_layerTreeView.initialize(this, m_rootLayer, layerTreeViewSettings);
if (!m_layerTreeView.isNull()) {
m_layerTreeView.setPageScaleFactorAndLimits(pageScaleFactor(), m_minimumPageScaleFactor, m_maximumPageScaleFactor);
if (m_compositorSurfaceReady)
m_layerTreeView.setSurfaceReady();
updateLayerTreeViewport();
m_client->didActivateCompositor(m_layerTreeView.compositorIdentifier());
m_isAcceleratedCompositingActive = true;
@@ -124,6 +124,7 @@ class WebViewImpl : public WebView, public WebLayerTreeViewClient, public RefCou
virtual void didEnterFullScreen();
virtual void willExitFullScreen();
virtual void didExitFullScreen();
virtual void setCompositorSurfaceReady();
virtual void animate(double);
virtual void layout(); // Also implements WebLayerTreeViewClient::layout()
virtual void paint(WebCanvas*, const WebRect&);
@@ -754,6 +755,7 @@ class WebViewImpl : public WebView, public WebLayerTreeViewClient, public RefCou
bool m_compositorCreationFailed;
// If true, the graphics context is being restored.
bool m_recreatingGraphicsContext;
bool m_compositorSurfaceReady;
#endif
static const WebInputEvent* m_currentInputEvent;

@@ -538,6 +538,7 @@ void CCLayerTreeHostTest::doBeginTest()
m_layerTreeHost = MockLayerTreeHost::create(this, m_client.get(), rootLayer, m_settings);
ASSERT_TRUE(m_layerTreeHost);
rootLayer->setLayerTreeHost(m_layerTreeHost.get());
m_layerTreeHost->setSurfaceReady();

m_beginning = true;
beginTest();

0 comments on commit 32031a5

Please sign in to comment.