[chromium] Implement a global resource limit for DrawingBuffer to limit the amount...
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 4 Aug 2011 23:46:59 +0000 (23:46 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 4 Aug 2011 23:46:59 +0000 (23:46 +0000)
https://bugs.webkit.org/show_bug.cgi?id=65655

Patch by James Robinson <jamesr@chromium.org> on 2011-08-04
Reviewed by Kenneth Russell.

* platform/graphics/gpu/DrawingBuffer.cpp:
(WebCore::DrawingBuffer::setResourceLimit):
(WebCore::DrawingBuffer::clear):
(WebCore::DrawingBuffer::reset):
* platform/graphics/gpu/DrawingBuffer.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@92430 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp
Source/WebCore/platform/graphics/gpu/DrawingBuffer.h

index 98505b4..265ef3a 100644 (file)
@@ -1,3 +1,16 @@
+2011-08-04  James Robinson  <jamesr@chromium.org>
+
+        [chromium] Implement a global resource limit for DrawingBuffer to limit the amount of GPU memory used by 2d canvas backing stores
+        https://bugs.webkit.org/show_bug.cgi?id=65655
+
+        Reviewed by Kenneth Russell.
+
+        * platform/graphics/gpu/DrawingBuffer.cpp:
+        (WebCore::DrawingBuffer::setResourceLimit):
+        (WebCore::DrawingBuffer::clear):
+        (WebCore::DrawingBuffer::reset):
+        * platform/graphics/gpu/DrawingBuffer.h:
+
 2011-08-04  Kenichi Ishibashi  <bashi@chromium.org>
 
         [Chromium] Reduce memory consumption of HarfbuzzFace
index 1d8acaf..9abea82 100644 (file)
 
 namespace WebCore {
 
+// Global resource ceiling (expressed in terms of pixels) for DrawingBuffer creation and resize.
+// When this limit is set, DrawingBuffer::create() and DrawingBuffer::reset() calls that would
+// exceed the global cap will instead clear the buffer.
+#if PLATFORM(CHROMIUM) // Currently, this cap only exists for chromium.
+static int s_maximumResourceUsePixels = 16 * 1024 * 1024;
+#else
+static int s_maximumResourceUsePixels = 0;
+#endif
+static int s_currentResourceUsePixels = 0;
+
 PassRefPtr<DrawingBuffer> DrawingBuffer::create(GraphicsContext3D* context, const IntSize& size)
 {
     Extensions3D* extensions = context->getExtensions();
@@ -60,6 +70,8 @@ void DrawingBuffer::clear()
         return;
 
     m_context->makeContextCurrent();
+    if (!m_size.isEmpty())
+        s_currentResourceUsePixels -= m_size.width() * m_size.height();
 
     if (m_colorBuffer) {
         m_context->deleteTexture(m_colorBuffer);
@@ -202,9 +214,19 @@ bool DrawingBuffer::reset(const IntSize& newSize)
     int maxTextureSize = 0;
     m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &maxTextureSize);
     if (newSize.height() > maxTextureSize || newSize.width() > maxTextureSize) {
-      clear();
-      return false;
+        clear();
+        return false;
+    }
+
+    int pixelDelta = newSize.width() * newSize.height();
+    if (!m_size.isEmpty())
+        pixelDelta -= m_size.width() * m_size.height();
+
+    if (s_maximumResourceUsePixels && (s_currentResourceUsePixels + pixelDelta) > s_maximumResourceUsePixels) {
+        clear();
+        return false;
     }
+    s_currentResourceUsePixels += pixelDelta;
 
     const GraphicsContext3D::Attributes& attributes = m_context->getContextAttributes();
 
index 637df37..019ab65 100644 (file)
@@ -58,7 +58,7 @@ class Canvas2DLayerChromium;
 class DrawingBuffer : public RefCounted<DrawingBuffer> {
 public:
     friend class GraphicsContext3D;
-    
+
     ~DrawingBuffer();
 
     void clearFramebuffer();
@@ -114,7 +114,7 @@ private:
     static PassRefPtr<DrawingBuffer> create(GraphicsContext3D*, const IntSize&);
     
     DrawingBuffer(GraphicsContext3D*, const IntSize&, bool multisampleExtensionSupported, bool packedDepthStencilExtensionSupported);
-    
+
     // Platform specific function called after reset() so each platform can do extra work if needed
     void didReset();