Diff
Modified: trunk/Source/WebCore/ChangeLog (98470 => 98471)
--- trunk/Source/WebCore/ChangeLog 2011-10-26 13:17:04 UTC (rev 98470)
+++ trunk/Source/WebCore/ChangeLog 2011-10-26 13:24:56 UTC (rev 98471)
@@ -1,3 +1,59 @@
+2011-10-25 Stephen White <senorbla...@chromium.org>
+
+ [chromium] Canvas2D should rate-limit drawing to prevent swamping the GPU process.
+ https://bugs.webkit.org/show_bug.cgi?id=70367
+
+ Reviewed by James Robinson.
+
+ Sadly, we don't have infrastructure to test this kind of GPU swamping
+ yet.
+
+ * WebCore.gypi:
+ Add RateLimiter.* to the Chromium build.
+ * platform/graphics/chromium/Canvas2DLayerChromium.cpp:
+ (WebCore::Canvas2DLayerChromium::contentChanged):
+ When the layer is notified that the contents have changed, ping the
+ rate limiter.
+ * platform/graphics/chromium/Canvas2DLayerChromium.h:
+ * platform/graphics/chromium/GraphicsLayerChromium.cpp:
+ (WebCore::GraphicsLayerChromium::setContentsNeedsDisplay):
+ Call (new) virtual contentChanged() on a layer when its contents have
+ been changed (e.g., by a drawing call).
+ * platform/graphics/chromium/LayerChromium.h:
+ (WebCore::LayerChromium::contentChanged):
+ New virtual contentChanged().
+ * platform/graphics/chromium/RateLimiter.cpp: Added.
+ (WebCore::RateLimiter::create):
+ Rate limiter factory function.
+ (WebCore::RateLimiter::RateLimiter):
+ (WebCore::RateLimiter::start):
+ Public API to start rate limiting a context.
+ (WebCore::RateLimiter::stop):
+ Public API to stop rate limiting a context.
+ (WebCore::RateLimiter::rateLimitContext):
+ Internal timer callback when a context should be rate limited.
+ * platform/graphics/chromium/RateLimiter.h: Added.
+ * platform/graphics/chromium/WebGLLayerChromium.cpp:
+ (WebCore::WebGLLayerChromium::WebGLLayerChromium):
+ Remove rate limiting timer and extension check (moved to RateLimiter).
+ (WebCore::WebGLLayerChromium::contentChanged):
+ The function formerly known as setTextureUpdated(), now renamed to
+ match the base class virtual contentChanged(). Call rate limiter in
+ CCLayerTreeHost (local implementation removed).
+ (WebCore::WebGLLayerChromium::setContext):
+ When the context is changed, stop the pending rate limiter on the old
+ context. Remove extension check (moved to RateLimiter).
+ * platform/graphics/chromium/WebGLLayerChromium.h:
+ Remove rate limiting timer and extension check (moved to RateLimiter).
+ * platform/graphics/chromium/cc/CCLayerTreeHost.cpp:
+ (WebCore::CCLayerTreeHost::startRateLimiter):
+ Public API for starting per-context rate limiter.
+ (WebCore::CCLayerTreeHost::stopRateLimiter):
+ Public API for stopping per-context rate limiter.
+ * platform/graphics/chromium/cc/CCLayerTreeHost.h:
+ Implementation of per-GraphicsContext3D RateLimiter.
+
+
2011-10-26 Pavel Feldman <pfeld...@chromium.org>
Not reviewed: fixing inspector extensions tests.
Modified: trunk/Source/WebCore/WebCore.gypi (98470 => 98471)
--- trunk/Source/WebCore/WebCore.gypi 2011-10-26 13:17:04 UTC (rev 98470)
+++ trunk/Source/WebCore/WebCore.gypi 2011-10-26 13:24:56 UTC (rev 98471)
@@ -3498,6 +3498,8 @@
'platform/graphics/chromium/PluginLayerChromium.h',
'platform/graphics/chromium/ProgramBinding.cpp',
'platform/graphics/chromium/ProgramBinding.h',
+ 'platform/graphics/chromium/RateLimiter.cpp',
+ 'platform/graphics/chromium/RateLimiter.h',
'platform/graphics/chromium/RenderSurfaceChromium.cpp',
'platform/graphics/chromium/RenderSurfaceChromium.h',
'platform/graphics/chromium/ShaderChromium.cpp',
Modified: trunk/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp (98470 => 98471)
--- trunk/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp 2011-10-26 13:17:04 UTC (rev 98470)
+++ trunk/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp 2011-10-26 13:24:56 UTC (rev 98471)
@@ -36,6 +36,7 @@
#include "Extensions3DChromium.h"
#include "GraphicsContext3D.h"
+#include "cc/CCLayerTreeHost.h"
#if USE(SKIA)
#include "GrContext.h"
@@ -84,5 +85,11 @@
resetNeedsDisplay();
}
+void Canvas2DLayerChromium::contentChanged()
+{
+ if (layerTreeHost())
+ layerTreeHost()->startRateLimiter(m_context);
}
+
+}
#endif // USE(ACCELERATED_COMPOSITING)
Modified: trunk/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h (98470 => 98471)
--- trunk/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h 2011-10-26 13:17:04 UTC (rev 98470)
+++ trunk/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h 2011-10-26 13:24:56 UTC (rev 98471)
@@ -48,7 +48,7 @@
virtual bool drawsContent() const;
virtual void updateCompositorResources(GraphicsContext3D*, CCTextureUpdater&);
- void setTextureChanged();
+ virtual void contentChanged();
private:
explicit Canvas2DLayerChromium(GraphicsContext3D*);
Modified: trunk/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp (98470 => 98471)
--- trunk/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp 2011-10-26 13:17:04 UTC (rev 98470)
+++ trunk/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp 2011-10-26 13:24:56 UTC (rev 98471)
@@ -307,8 +307,10 @@
void GraphicsLayerChromium::setContentsNeedsDisplay()
{
- if (m_contentsLayer)
+ if (m_contentsLayer) {
m_contentsLayer->setNeedsDisplay();
+ m_contentsLayer->contentChanged();
+ }
}
void GraphicsLayerChromium::setNeedsDisplay()
Modified: trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.h (98470 => 98471)
--- trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.h 2011-10-26 13:17:04 UTC (rev 98470)
+++ trunk/Source/WebCore/platform/graphics/chromium/LayerChromium.h 2011-10-26 13:24:56 UTC (rev 98471)
@@ -196,6 +196,7 @@
// Returns true if any of the layer's descendants has content to draw.
bool descendantDrawsContent();
+ virtual void contentChanged() { }
CCLayerTreeHost* layerTreeHost() const { return m_layerTreeHost.get(); }
void cleanupResourcesRecursive();
Added: trunk/Source/WebCore/platform/graphics/chromium/RateLimiter.cpp (0 => 98471)
--- trunk/Source/WebCore/platform/graphics/chromium/RateLimiter.cpp (rev 0)
+++ trunk/Source/WebCore/platform/graphics/chromium/RateLimiter.cpp 2011-10-26 13:24:56 UTC (rev 98471)
@@ -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"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "RateLimiter.h"
+
+#include "Extensions3DChromium.h"
+#include "GraphicsContext3D.h"
+#include "TraceEvent.h"
+
+namespace WebCore {
+
+PassRefPtr<RateLimiter> RateLimiter::create(GraphicsContext3D* context)
+{
+ return adoptRef(new RateLimiter(context));
+}
+
+RateLimiter::RateLimiter(GraphicsContext3D* context)
+ : m_context(context)
+ , m_timer(this, &RateLimiter::rateLimitContext)
+{
+ ASSERT(context);
+ ASSERT(context->getExtensions());
+ m_contextSupportsRateLimitingExtension = context->getExtensions()->supports("GL_CHROMIUM_rate_limit_offscreen_context");
+}
+
+void RateLimiter::start()
+{
+ if (m_contextSupportsRateLimitingExtension && !m_timer.isActive())
+ m_timer.startOneShot(0);
+}
+
+void RateLimiter::stop()
+{
+ m_timer.stop();
+}
+
+void RateLimiter::rateLimitContext(Timer<RateLimiter>*)
+{
+ TRACE_EVENT("RateLimiter::rateLimitContext", this, 0);
+
+ Extensions3DChromium* extensions = static_cast<Extensions3DChromium*>(m_context->getExtensions());
+
+ extensions->rateLimitOffscreenContextCHROMIUM();
+}
+
+}
+#endif // USE(ACCELERATED_COMPOSITING)
Property changes on: trunk/Source/WebCore/platform/graphics/chromium/RateLimiter.cpp
___________________________________________________________________
Added: svn:eol-style
Added: trunk/Source/WebCore/platform/graphics/chromium/RateLimiter.h (0 => 98471)
--- trunk/Source/WebCore/platform/graphics/chromium/RateLimiter.h (rev 0)
+++ trunk/Source/WebCore/platform/graphics/chromium/RateLimiter.h 2011-10-26 13:24:56 UTC (rev 98471)
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+#ifndef RateLimiter_h
+#define RateLimiter_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "PassRefPtr.h"
+#include "Timer.h"
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class GraphicsContext3D;
+
+// A class containing a timer, which calls rateLimitCHROMIUM on expiry
+class RateLimiter : public RefCounted<RateLimiter> {
+public:
+ static PassRefPtr<RateLimiter> create(GraphicsContext3D*);
+ void start();
+ void stop();
+
+private:
+ explicit RateLimiter(GraphicsContext3D*);
+ GraphicsContext3D* m_context;
+ bool m_contextSupportsRateLimitingExtension;
+ Timer<RateLimiter> m_timer;
+ void rateLimitContext(Timer<RateLimiter>*);
+};
+
+}
+#endif // USE(ACCELERATED_COMPOSITING)
+
+#endif
Property changes on: trunk/Source/WebCore/platform/graphics/chromium/RateLimiter.h
___________________________________________________________________
Added: svn:eol-style
Modified: trunk/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp (98470 => 98471)
--- trunk/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp 2011-10-26 13:17:04 UTC (rev 98470)
+++ trunk/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp 2011-10-26 13:24:56 UTC (rev 98471)
@@ -50,14 +50,14 @@
: CanvasLayerChromium(delegate)
, m_context(0)
, m_textureChanged(true)
- , m_contextSupportsRateLimitingExtension(false)
- , m_rateLimitingTimer(this, &WebGLLayerChromium::rateLimitContext)
, m_textureUpdated(false)
{
}
WebGLLayerChromium::~WebGLLayerChromium()
{
+ if (m_context && layerTreeHost())
+ layerTreeHost()->stopRateLimiter(m_context);
}
bool WebGLLayerChromium::drawsContent() const
@@ -115,19 +115,22 @@
return true;
}
-void WebGLLayerChromium::setTextureUpdated()
+void WebGLLayerChromium::contentChanged()
{
m_textureUpdated = true;
// If WebGL commands are issued outside of a the animation callbacks, then use
// call rateLimitOffscreenContextCHROMIUM() to keep the context from getting too far ahead.
- if (layerTreeHost() && !layerTreeHost()->animating() && m_contextSupportsRateLimitingExtension && !m_rateLimitingTimer.isActive())
- m_rateLimitingTimer.startOneShot(0);
+ if (layerTreeHost())
+ layerTreeHost()->startRateLimiter(m_context);
}
void WebGLLayerChromium::setContext(const GraphicsContext3D* context)
{
bool contextChanged = (m_context != context);
+ if (layerTreeHost() && contextChanged)
+ layerTreeHost()->stopRateLimiter(m_context);
+
m_context = const_cast<GraphicsContext3D*>(context);
if (!m_context)
@@ -142,7 +145,6 @@
GraphicsContext3D::Attributes attributes = m_context->getContextAttributes();
m_hasAlpha = attributes.alpha;
m_premultipliedAlpha = attributes.premultipliedAlpha;
- m_contextSupportsRateLimitingExtension = m_context->getExtensions()->supports("GL_CHROMIUM_rate_limit_offscreen_context");
}
GraphicsContext3D* WebGLLayerChromium::layerRendererContext()
@@ -154,16 +156,5 @@
return layerTreeHost()->context();
}
-void WebGLLayerChromium::rateLimitContext(Timer<WebGLLayerChromium>*)
-{
- TRACE_EVENT("WebGLLayerChromium::rateLimitContext", this, 0);
-
- if (!m_context)
- return;
-
- Extensions3DChromium* extensions = static_cast<Extensions3DChromium*>(m_context->getExtensions());
- extensions->rateLimitOffscreenContextCHROMIUM();
}
-
-}
#endif // USE(ACCELERATED_COMPOSITING)
Modified: trunk/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h (98470 => 98471)
--- trunk/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h 2011-10-26 13:17:04 UTC (rev 98470)
+++ trunk/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h 2011-10-26 13:24:56 UTC (rev 98471)
@@ -35,7 +35,6 @@
#if USE(ACCELERATED_COMPOSITING)
#include "CanvasLayerChromium.h"
-#include "Timer.h"
namespace WebCore {
@@ -51,7 +50,7 @@
virtual bool drawsContent() const;
virtual void updateCompositorResources(GraphicsContext3D*, CCTextureUpdater&);
- void setTextureUpdated();
+ virtual void contentChanged();
bool paintRenderedResultsToCanvas(ImageBuffer*);
void setContext(const GraphicsContext3D* context);
@@ -63,15 +62,11 @@
GraphicsContext3D* layerRendererContext();
- void rateLimitContext(Timer<WebGLLayerChromium>*);
-
// GraphicsContext3D::platformLayer has a side-effect of assigning itself
// to the layer. Because of that GraphicsContext3D's destructor will reset
// layer's context to 0.
GraphicsContext3D* m_context;
bool m_textureChanged;
- bool m_contextSupportsRateLimitingExtension;
- Timer<WebGLLayerChromium> m_rateLimitingTimer;
bool m_textureUpdated;
};
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp (98470 => 98471)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp 2011-10-26 13:17:04 UTC (rev 98470)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp 2011-10-26 13:24:56 UTC (rev 98471)
@@ -430,4 +430,28 @@
}
}
+void CCLayerTreeHost::startRateLimiter(GraphicsContext3D* context)
+{
+ if (animating())
+ return;
+ ASSERT(context);
+ RateLimiterMap::iterator it = m_rateLimiters.find(context);
+ if (it != m_rateLimiters.end())
+ it->second->start();
+ else {
+ RefPtr<RateLimiter> rateLimiter = RateLimiter::create(context);
+ m_rateLimiters.set(context, rateLimiter);
+ rateLimiter->start();
+ }
}
+
+void CCLayerTreeHost::stopRateLimiter(GraphicsContext3D* context)
+{
+ RateLimiterMap::iterator it = m_rateLimiters.find(context);
+ if (it != m_rateLimiters.end()) {
+ it->second->stop();
+ m_rateLimiters.remove(it);
+ }
+}
+
+}
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h (98470 => 98471)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h 2011-10-26 13:17:04 UTC (rev 98470)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h 2011-10-26 13:24:56 UTC (rev 98471)
@@ -27,10 +27,12 @@
#include "GraphicsTypes3D.h"
#include "IntRect.h"
+#include "RateLimiter.h"
#include "TransformationMatrix.h"
#include "cc/CCLayerTreeHostCommon.h"
#include "cc/CCProxy.h"
+#include <wtf/HashMap.h>
#include <wtf/PassOwnPtr.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
@@ -160,6 +162,8 @@
void updateCompositorResources(GraphicsContext3D*, CCTextureUpdater&);
void applyScrollDeltas(const CCScrollUpdateSet&);
+ void startRateLimiter(GraphicsContext3D*);
+ void stopRateLimiter(GraphicsContext3D*);
protected:
CCLayerTreeHost(CCLayerTreeHostClient*, PassRefPtr<LayerChromium> rootLayer, const CCSettings&);
bool initialize();
@@ -194,6 +198,8 @@
IntSize m_viewportSize;
TransformationMatrix m_zoomAnimatorTransform;
bool m_visible;
+ typedef HashMap<GraphicsContext3D*, RefPtr<RateLimiter> > RateLimiterMap;
+ RateLimiterMap m_rateLimiters;
};
}
Modified: trunk/Source/WebKit/chromium/ChangeLog (98470 => 98471)
--- trunk/Source/WebKit/chromium/ChangeLog 2011-10-26 13:17:04 UTC (rev 98470)
+++ trunk/Source/WebKit/chromium/ChangeLog 2011-10-26 13:24:56 UTC (rev 98471)
@@ -1,3 +1,14 @@
+2011-10-25 Stephen White <senorbla...@chromium.org>
+
+ [chromium] Canvas2D should rate-limit drawing to prevent swamping the GPU process.
+ https://bugs.webkit.org/show_bug.cgi?id=70367
+
+ * src/GraphicsContext3DChromium.cpp:
+ (WebCore::GraphicsContext3DPrivate::markContextChanged):
+ Remove the call to setTextureChanged (it will be handled internally
+ by the compositor in setContextNeedsDisplay() instead). This decouples
+ GraphicsContext3D from WebGLLayerChromium a bit.
+
2011-10-26 Sheriff Bot <webkit.review....@gmail.com>
Unreviewed, rolling out r98393.
Modified: trunk/Source/WebKit/chromium/src/GraphicsContext3DChromium.cpp (98470 => 98471)
--- trunk/Source/WebKit/chromium/src/GraphicsContext3DChromium.cpp 2011-10-26 13:17:04 UTC (rev 98470)
+++ trunk/Source/WebKit/chromium/src/GraphicsContext3DChromium.cpp 2011-10-26 13:24:56 UTC (rev 98471)
@@ -225,9 +225,6 @@
void GraphicsContext3DPrivate::markContextChanged()
{
-#if USE(ACCELERATED_COMPOSITING)
- platformLayer()->setTextureUpdated();
-#endif
m_layerComposited = false;
}