Title: [114475] trunk/Source/WebCore
Revision
114475
Author
[email protected]
Date
2012-04-17 19:57:28 -0700 (Tue, 17 Apr 2012)

Log Message

[chromium] Ensure RateLimiter waits for Swapbuffers completion
https://bugs.webkit.org/show_bug.cgi?id=83649

Patch by John Bauman <[email protected]> on 2012-04-17
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):

Modified Paths

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;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to