[chromium] Free texture from CCIOSurfaceLayerImpl when it is destroyed
authordanakj@chromium.org <danakj@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Jun 2012 19:07:37 +0000 (19:07 +0000)
committerdanakj@chromium.org <danakj@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Jun 2012 19:07:37 +0000 (19:07 +0000)
https://bugs.webkit.org/show_bug.cgi?id=88371

Reviewed by James Robinson.

Source/WebCore:

Unit test: CCLayerTreeHostImplTest.layersFreeTextures

* platform/graphics/chromium/cc/CCIOSurfaceLayerImpl.cpp:
(WebCore::CCIOSurfaceLayerImpl::~CCIOSurfaceLayerImpl):
(WebCore::CCIOSurfaceLayerImpl::willDraw):

Source/WebKit/chromium:

* tests/CCLayerTreeHostImplTest.cpp:

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

Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/chromium/cc/CCIOSurfaceLayerImpl.cpp
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp

index b4dbc55..2e038f3 100644 (file)
@@ -1,3 +1,16 @@
+2012-06-07  Dana Jansens  <danakj@chromium.org>
+
+        [chromium] Free texture from CCIOSurfaceLayerImpl when it is destroyed
+        https://bugs.webkit.org/show_bug.cgi?id=88371
+
+        Reviewed by James Robinson.
+
+        Unit test: CCLayerTreeHostImplTest.layersFreeTextures
+
+        * platform/graphics/chromium/cc/CCIOSurfaceLayerImpl.cpp:
+        (WebCore::CCIOSurfaceLayerImpl::~CCIOSurfaceLayerImpl):
+        (WebCore::CCIOSurfaceLayerImpl::willDraw):
+
 2012-06-07  Peter Beverloo  <peter@chromium.org>
 
         Buildfix for ENABLE_OVERFLOW_SCROLLING=0 (though defined)
index 9fe915d..0ce9126 100644 (file)
@@ -33,6 +33,7 @@
 #include "GraphicsContext3D.h"
 #include "LayerRendererChromium.h"
 #include "cc/CCIOSurfaceDrawQuad.h"
+#include "cc/CCLayerTreeHostImpl.h"
 #include "cc/CCProxy.h"
 #include "cc/CCQuadCuller.h"
 
@@ -48,9 +49,14 @@ CCIOSurfaceLayerImpl::CCIOSurfaceLayerImpl(int id)
 
 CCIOSurfaceLayerImpl::~CCIOSurfaceLayerImpl()
 {
-    // FIXME: it seems there is no layer renderer / GraphicsContext3D available here. Ideally we
-    // would like to delete m_ioSurfaceTextureId.
-    m_ioSurfaceTextureId = 0;
+    if (!m_ioSurfaceTextureId)
+        return;
+
+    CCGraphicsContext* context = layerTreeHostImpl()->context();
+    // FIXME: Implement this path for software compositing.
+    GraphicsContext3D* context3d = context->context3D();
+    if (context3d)
+        context3d->deleteTexture(m_ioSurfaceTextureId);
 }
 
 void CCIOSurfaceLayerImpl::willDraw(CCRenderer* layerRenderer, CCGraphicsContext* context)
@@ -67,6 +73,7 @@ void CCIOSurfaceLayerImpl::willDraw(CCRenderer* layerRenderer, CCGraphicsContext
         ASSERT(extensions->supports("GL_CHROMIUM_iosurface"));
         ASSERT(extensions->supports("GL_ARB_texture_rectangle"));
 
+        // FIXME: Do this in a way that we can track memory usage.
         if (!m_ioSurfaceTextureId)
             m_ioSurfaceTextureId = context3d->createTexture();
 
index 337b2cf..74e8b14 100644 (file)
@@ -1,3 +1,12 @@
+2012-06-07  Dana Jansens  <danakj@chromium.org>
+
+        [chromium] Free texture from CCIOSurfaceLayerImpl when it is destroyed
+        https://bugs.webkit.org/show_bug.cgi?id=88371
+
+        Reviewed by James Robinson.
+
+        * tests/CCLayerTreeHostImplTest.cpp:
+
 2012-06-07  Ami Fischman  <fischman@chromium.org>
 
         Plumb CORS attribute information from HTMLMediaElement to media players so it can be used
index 1657c33..f92eed0 100644 (file)
@@ -31,6 +31,7 @@
 #include "FakeWebGraphicsContext3D.h"
 #include "GraphicsContext3DPrivate.h"
 #include "LayerRendererChromium.h"
+#include "cc/CCIOSurfaceLayerImpl.h"
 #include "cc/CCLayerImpl.h"
 #include "cc/CCLayerTilingData.h"
 #include "cc/CCQuadCuller.h"
@@ -1717,6 +1718,15 @@ TEST_F(CCLayerTreeHostImplTest, dontUseOldResourcesAfterLostContext)
     videoLayer->setDrawsContent(true);
     rootLayer->addChild(videoLayer.release());
 
+    OwnPtr<CCIOSurfaceLayerImpl> ioSurfaceLayer = CCIOSurfaceLayerImpl::create(4);
+    ioSurfaceLayer->setBounds(IntSize(10, 10));
+    ioSurfaceLayer->setAnchorPoint(FloatPoint(0, 0));
+    ioSurfaceLayer->setContentBounds(IntSize(10, 10));
+    ioSurfaceLayer->setDrawsContent(true);
+    ioSurfaceLayer->setIOSurfaceProperties(1, IntSize(10, 10));
+    ioSurfaceLayer->setLayerTreeHostImpl(m_hostImpl.get());
+    rootLayer->addChild(ioSurfaceLayer.release());
+
     m_hostImpl->setRootLayer(rootLayer.release());
 
     CCLayerTreeHostImpl::FrameData frame;
@@ -1734,4 +1744,106 @@ TEST_F(CCLayerTreeHostImplTest, dontUseOldResourcesAfterLostContext)
     m_hostImpl->swapBuffers();
 }
 
+// Fake WebGraphicsContext3D that tracks the number of textures in use.
+class TrackingWebGraphicsContext3D : public FakeWebGraphicsContext3D {
+public:
+    TrackingWebGraphicsContext3D()
+        : m_nextTextureId(1)
+        , m_numTextures(0)
+    { }
+
+    virtual WebGLId createTexture()
+    {
+        WebGLId id = m_nextTextureId;
+        ++m_nextTextureId;
+
+        m_textures.set(id, true);
+        ++m_numTextures;
+        return id;
+    }
+
+    virtual void deleteTexture(WebGLId id)
+    {
+        if (!m_textures.get(id))
+            return;
+        m_textures.set(id, false);
+        --m_numTextures;
+    }
+
+    PassRefPtr<GraphicsContext3D> createGraphicsContext()
+    {
+        return GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(this), GraphicsContext3D::RenderDirectlyToHostWindow);
+    }
+
+    unsigned numTextures() const { return m_numTextures; }
+
+private:
+    WebGLId m_nextTextureId;
+    HashMap<WebGLId, bool> m_textures;
+    unsigned m_numTextures;
+};
+
+TEST_F(CCLayerTreeHostImplTest, layersFreeTextures)
+{
+    OwnPtr<CCLayerImpl> rootLayer(CCLayerImpl::create(0));
+    rootLayer->setBounds(IntSize(10, 10));
+    rootLayer->setAnchorPoint(FloatPoint(0, 0));
+
+    OwnPtr<CCTiledLayerImpl> tileLayer = CCTiledLayerImpl::create(1);
+    tileLayer->setBounds(IntSize(10, 10));
+    tileLayer->setAnchorPoint(FloatPoint(0, 0));
+    tileLayer->setContentBounds(IntSize(10, 10));
+    tileLayer->setDrawsContent(true);
+    tileLayer->setSkipsDraw(false);
+    OwnPtr<CCLayerTilingData> tilingData(CCLayerTilingData::create(IntSize(10, 10), CCLayerTilingData::NoBorderTexels));
+    tilingData->setBounds(IntSize(10, 10));
+    tileLayer->setTilingData(*tilingData);
+    tileLayer->pushTileProperties(0, 0, 1, IntRect(0, 0, 10, 10));
+    rootLayer->addChild(tileLayer.release());
+
+    OwnPtr<CCTextureLayerImpl> textureLayer = CCTextureLayerImpl::create(2);
+    textureLayer->setBounds(IntSize(10, 10));
+    textureLayer->setAnchorPoint(FloatPoint(0, 0));
+    textureLayer->setContentBounds(IntSize(10, 10));
+    textureLayer->setDrawsContent(true);
+    textureLayer->setTextureId(1);
+    rootLayer->addChild(textureLayer.release());
+
+    FakeVideoFrameProvider provider;
+    OwnPtr<CCVideoLayerImpl> videoLayer = CCVideoLayerImpl::create(3, &provider);
+    videoLayer->setBounds(IntSize(10, 10));
+    videoLayer->setAnchorPoint(FloatPoint(0, 0));
+    videoLayer->setContentBounds(IntSize(10, 10));
+    videoLayer->setDrawsContent(true);
+    videoLayer->setLayerTreeHostImpl(m_hostImpl.get());
+    rootLayer->addChild(videoLayer.release());
+
+    OwnPtr<CCIOSurfaceLayerImpl> ioSurfaceLayer = CCIOSurfaceLayerImpl::create(4);
+    ioSurfaceLayer->setBounds(IntSize(10, 10));
+    ioSurfaceLayer->setAnchorPoint(FloatPoint(0, 0));
+    ioSurfaceLayer->setContentBounds(IntSize(10, 10));
+    ioSurfaceLayer->setDrawsContent(true);
+    ioSurfaceLayer->setIOSurfaceProperties(1, IntSize(10, 10));
+    ioSurfaceLayer->setLayerTreeHostImpl(m_hostImpl.get());
+    rootLayer->addChild(ioSurfaceLayer.release());
+
+    // Lose the context, replacing it with a TrackingWebGraphicsContext3D, that
+    // tracks the number of textures allocated. This pointer is owned by its
+    // GraphicsContext3D.
+    TrackingWebGraphicsContext3D* trackingWebGraphicsContext = new TrackingWebGraphicsContext3D();
+    m_hostImpl->initializeLayerRenderer(CCGraphicsContext::create3D(trackingWebGraphicsContext->createGraphicsContext()), UnthrottledUploader);
+
+    m_hostImpl->setRootLayer(rootLayer.release());
+
+    CCLayerTreeHostImpl::FrameData frame;
+    EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
+    m_hostImpl->drawLayers(frame);
+    m_hostImpl->didDrawAllLayers(frame);
+    m_hostImpl->swapBuffers();
+
+    // Kill the layer tree. There should be no textures left in use after.
+    m_hostImpl.clear();
+    EXPECT_EQ(0u, trackingWebGraphicsContext->numTextures());
+}
+
 } // namespace