Diff
Modified: trunk/Source/WebCore/ChangeLog (114474 => 114475)
--- trunk/Source/WebCore/ChangeLog 2012-04-18 02:49:54 UTC (rev 114474)
+++ trunk/Source/WebCore/ChangeLog 2012-04-18 02:57:28 UTC (rev 114475)
@@ -1,3 +1,48 @@
+2012-04-17 John Bauman <[email protected]>
+
+ [chromium] Ensure RateLimiter waits for Swapbuffers completion
+ https://bugs.webkit.org/show_bug.cgi?id=83649
+
+ Reviewed by James Robinson.
+
+ We were waiting only on the canvas context, which with the new GPU
+ scheduling was causing the RateLimiter not to ratelimit enough. We
+ need to insert no-op commands in the compositor context, so that we'll
+ wait for the canvas context and SwapBuffers as well.
+
+ * platform/graphics/chromium/LayerRendererChromium.cpp:
+ (WebCore::LayerRendererChromium::doNoOp):
+ (WebCore):
+ * platform/graphics/chromium/LayerRendererChromium.h:
+ (LayerRendererChromium):
+ * platform/graphics/chromium/RateLimiter.cpp:
+ (WebCore::RateLimiter::create):
+ (WebCore::RateLimiter::RateLimiter):
+ (WebCore::RateLimiter::rateLimitContext):
+ * platform/graphics/chromium/RateLimiter.h:
+ (RateLimiterClient):
+ (WebCore):
+ (RateLimiter):
+ * platform/graphics/chromium/cc/CCLayerTreeHost.cpp:
+ (WebCore::CCLayerTreeHost::startRateLimiter):
+ (WebCore::CCLayerTreeHost::rateLimit):
+ (WebCore):
+ * platform/graphics/chromium/cc/CCLayerTreeHost.h:
+ (CCLayerTreeHost):
+ * platform/graphics/chromium/cc/CCProxy.h:
+ (CCProxy):
+ * platform/graphics/chromium/cc/CCSingleThreadProxy.cpp:
+ (WebCore::CCSingleThreadProxy::forceNoOpCommand):
+ (WebCore):
+ * platform/graphics/chromium/cc/CCSingleThreadProxy.h:
+ (CCSingleThreadProxy):
+ * platform/graphics/chromium/cc/CCThreadProxy.cpp:
+ (WebCore::CCThreadProxy::forceNoOpCommand):
+ (WebCore):
+ (WebCore::CCThreadProxy::forceNoOpCommandOnImplThread):
+ * platform/graphics/chromium/cc/CCThreadProxy.h:
+ (CCThreadProxy):
+
2012-04-17 Andreas Kling <[email protected]>
CSSValuePool: Made identifier value cache a fixed-size array.
Modified: trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp (114474 => 114475)
--- trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp 2012-04-18 02:49:54 UTC (rev 114474)
+++ trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp 2012-04-18 02:57:28 UTC (rev 114475)
@@ -423,6 +423,12 @@
GLC(m_context.get(), m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
}
+void LayerRendererChromium::doNoOp()
+{
+ GLC(m_context.get(), m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0));
+ GLC(m_context.get(), m_context->flush());
+}
+
void LayerRendererChromium::drawRenderPass(const CCRenderPass* renderPass)
{
CCRenderSurface* renderSurface = renderPass->targetSurface();
Modified: trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h (114474 => 114475)
--- trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h 2012-04-18 02:49:54 UTC (rev 114474)
+++ trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h 2012-04-18 02:57:28 UTC (rev 114475)
@@ -100,6 +100,7 @@
// waits for rendering to finish
void finish();
+ void doNoOp();
// puts backbuffer onscreen
bool swapBuffers(const IntRect& subBuffer);
Modified: trunk/Source/WebCore/platform/graphics/chromium/RateLimiter.cpp (114474 => 114475)
--- trunk/Source/WebCore/platform/graphics/chromium/RateLimiter.cpp 2012-04-18 02:49:54 UTC (rev 114474)
+++ trunk/Source/WebCore/platform/graphics/chromium/RateLimiter.cpp 2012-04-18 02:57:28 UTC (rev 114475)
@@ -35,14 +35,15 @@
namespace WebCore {
-PassRefPtr<RateLimiter> RateLimiter::create(GraphicsContext3D* context)
+PassRefPtr<RateLimiter> RateLimiter::create(GraphicsContext3D* context, RateLimiterClient *client)
{
- return adoptRef(new RateLimiter(context));
+ return adoptRef(new RateLimiter(context, client));
}
-RateLimiter::RateLimiter(GraphicsContext3D* context)
+RateLimiter::RateLimiter(GraphicsContext3D* context, RateLimiterClient *client)
: m_context(context)
, m_timer(this, &RateLimiter::rateLimitContext)
+ , m_client(client)
{
ASSERT(context);
ASSERT(context->getExtensions());
@@ -70,6 +71,7 @@
Extensions3DChromium* extensions = static_cast<Extensions3DChromium*>(m_context->getExtensions());
+ m_client->rateLimit();
extensions->rateLimitOffscreenContextCHROMIUM();
}
Modified: trunk/Source/WebCore/platform/graphics/chromium/RateLimiter.h (114474 => 114475)
--- trunk/Source/WebCore/platform/graphics/chromium/RateLimiter.h 2012-04-18 02:49:54 UTC (rev 114474)
+++ trunk/Source/WebCore/platform/graphics/chromium/RateLimiter.h 2012-04-18 02:57:28 UTC (rev 114475)
@@ -36,21 +36,27 @@
class GraphicsContext3D;
+class RateLimiterClient {
+public:
+ virtual void rateLimit() = 0;
+};
+
// A class containing a timer, which calls rateLimitCHROMIUM on expiry
class RateLimiter : public RefCounted<RateLimiter> {
public:
- static PassRefPtr<RateLimiter> create(GraphicsContext3D*);
+ static PassRefPtr<RateLimiter> create(GraphicsContext3D*, RateLimiterClient*);
~RateLimiter();
void start();
void stop();
private:
- explicit RateLimiter(GraphicsContext3D*);
+ RateLimiter(GraphicsContext3D*, RateLimiterClient*);
RefPtr<GraphicsContext3D> m_context;
bool m_contextSupportsRateLimitingExtension;
Timer<RateLimiter> m_timer;
void rateLimitContext(Timer<RateLimiter>*);
+ RateLimiterClient *m_client;
};
}
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp (114474 => 114475)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp 2012-04-18 02:49:54 UTC (rev 114474)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp 2012-04-18 02:57:28 UTC (rev 114475)
@@ -593,12 +593,19 @@
if (it != m_rateLimiters.end())
it->second->start();
else {
- RefPtr<RateLimiter> rateLimiter = RateLimiter::create(context);
+ RefPtr<RateLimiter> rateLimiter = RateLimiter::create(context, this);
m_rateLimiters.set(context, rateLimiter);
rateLimiter->start();
}
}
+void CCLayerTreeHost::rateLimit()
+{
+ // Force a no-op command on the compositor context, so that any ratelimiting commands will wait for the compositing
+ // context, and therefore for the SwapBuffers.
+ m_proxy->forceSerializeOnSwapBuffers();
+}
+
void CCLayerTreeHost::stopRateLimiter(GraphicsContext3D* context)
{
RateLimiterMap::iterator it = m_rateLimiters.find(context);
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h (114474 => 114475)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h 2012-04-18 02:49:54 UTC (rev 114474)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h 2012-04-18 02:57:28 UTC (rev 114475)
@@ -122,7 +122,7 @@
int maxTextureSize;
};
-class CCLayerTreeHost {
+class CCLayerTreeHost : public RateLimiterClient {
WTF_MAKE_NONCOPYABLE(CCLayerTreeHost);
public:
static PassOwnPtr<CCLayerTreeHost> create(CCLayerTreeHostClient*, const CCSettings&);
@@ -215,6 +215,9 @@
void startRateLimiter(GraphicsContext3D*);
void stopRateLimiter(GraphicsContext3D*);
+ // RateLimitClient implementation
+ virtual void rateLimit() OVERRIDE;
+
bool bufferedUpdates();
bool requestPartialTextureUpdate();
void deleteTextureAfterCommit(PassOwnPtr<ManagedTexture>);
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCProxy.h (114474 => 114475)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCProxy.h 2012-04-18 02:49:54 UTC (rev 114474)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCProxy.h 2012-04-18 02:57:28 UTC (rev 114475)
@@ -88,6 +88,10 @@
virtual void start() = 0; // Must be called before using the proxy.
virtual void stop() = 0; // Must be called before deleting the proxy.
+ // Forces 3D commands on all contexts to wait for all previous SwapBuffers to finish before executing in the GPU
+ // process.
+ virtual void forceSerializeOnSwapBuffers() = 0;
+
// Maximum number of sub-region texture updates supported for each commit.
virtual size_t maxPartialTextureUpdates() const = 0;
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.cpp (114474 => 114475)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.cpp 2012-04-18 02:49:54 UTC (rev 114474)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.cpp 2012-04-18 02:57:28 UTC (rev 114475)
@@ -282,6 +282,15 @@
}
}
+void CCSingleThreadProxy::forceSerializeOnSwapBuffers()
+{
+ {
+ DebugScopedSetImplThread impl;
+ if (m_layerRendererInitialized)
+ m_layerTreeHostImpl->layerRenderer()->doNoOp();
+ }
+}
+
bool CCSingleThreadProxy::commitAndComposite()
{
ASSERT(CCProxy::isMainThread());
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.h (114474 => 114475)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.h 2012-04-18 02:49:54 UTC (rev 114474)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCSingleThreadProxy.h 2012-04-18 02:57:28 UTC (rev 114475)
@@ -62,6 +62,7 @@
virtual void stop() OVERRIDE;
virtual size_t maxPartialTextureUpdates() const OVERRIDE { return std::numeric_limits<size_t>::max(); }
virtual void setFontAtlas(PassOwnPtr<CCFontAtlas>) OVERRIDE;
+ virtual void forceSerializeOnSwapBuffers() OVERRIDE;
// CCLayerTreeHostImplClient implementation
virtual void didLoseContextOnImplThread() OVERRIDE { }
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp (114474 => 114475)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp 2012-04-18 02:49:54 UTC (rev 114474)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.cpp 2012-04-18 02:57:28 UTC (rev 114475)
@@ -380,6 +380,21 @@
m_started = false;
}
+void CCThreadProxy::forceSerializeOnSwapBuffers()
+{
+ CCCompletionEvent completion;
+ CCProxy::implThread()->postTask(createCCThreadTask(this, &CCThreadProxy::forceSerializeOnSwapBuffersOnImplThread, AllowCrossThreadAccess(&completion)));
+ completion.wait();
+}
+
+void CCThreadProxy::forceSerializeOnSwapBuffersOnImplThread(CCCompletionEvent* completion)
+{
+ if (m_layerRendererInitialized)
+ m_layerTreeHostImpl->layerRenderer()->doNoOp();
+ completion->signal();
+}
+
+
void CCThreadProxy::finishAllRenderingOnImplThread(CCCompletionEvent* completion)
{
TRACE_EVENT("CCThreadProxy::finishAllRenderingOnImplThread", this, 0);
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.h (114474 => 114475)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.h 2012-04-18 02:49:54 UTC (rev 114474)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCThreadProxy.h 2012-04-18 02:57:28 UTC (rev 114475)
@@ -71,6 +71,7 @@
virtual void stop() OVERRIDE;
virtual size_t maxPartialTextureUpdates() const OVERRIDE;
virtual void setFontAtlas(PassOwnPtr<CCFontAtlas>) OVERRIDE;
+ virtual void forceSerializeOnSwapBuffers() OVERRIDE;
// CCLayerTreeHostImplClient implementation
virtual void didLoseContextOnImplThread() OVERRIDE;
@@ -136,6 +137,7 @@
void recreateContextOnImplThread(CCCompletionEvent*, GraphicsContext3D*, bool* recreateSucceeded, LayerRendererCapabilities*);
CCScheduledActionDrawAndSwapResult scheduledActionDrawAndSwapInternal(bool forcedDraw);
void setFontAtlasOnImplThread(PassOwnPtr<CCFontAtlas>);
+ void forceSerializeOnSwapBuffersOnImplThread(CCCompletionEvent*);
// Accessed on main thread only.
bool m_animateRequested;