[Chromium] Clean up texture ids on the impl side when losing the context
authorpiman@chromium.org <piman@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 18 Apr 2012 00:52:40 +0000 (00:52 +0000)
committerpiman@chromium.org <piman@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 18 Apr 2012 00:52:40 +0000 (00:52 +0000)
https://bugs.webkit.org/show_bug.cgi?id=84122

Reviewed by James Robinson.

Tested by CCLayerTreeHostImplTest.dontUseOldResourcesAfterLostContext.

* platform/graphics/chromium/cc/CCTextureLayerImpl.cpp:
(WebCore::CCTextureLayerImpl::didLoseContext):
* platform/graphics/chromium/cc/CCTiledLayerImpl.cpp:
(WebCore::CCTiledLayerImpl::didLoseContext):
(WebCore):
* platform/graphics/chromium/cc/CCTiledLayerImpl.h:
(CCTiledLayerImpl):
* platform/graphics/chromium/cc/CCVideoLayerImpl.cpp:
(WebCore::CCVideoLayerImpl::didLoseContext):
(WebCore):
* platform/graphics/chromium/cc/CCVideoLayerImpl.h:
(CCVideoLayerImpl):

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

Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/chromium/cc/CCTextureLayerImpl.cpp
Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.cpp
Source/WebCore/platform/graphics/chromium/cc/CCTiledLayerImpl.h
Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.cpp
Source/WebCore/platform/graphics/chromium/cc/CCVideoLayerImpl.h
Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp

index 86b03750eb0f2953337b7d13adedf6a97053e319..32fdff0f0cc6c9c8d4e0b404fb100da304e4044c 100644 (file)
@@ -1,3 +1,25 @@
+2012-04-17  Antoine Labour  <piman@chromium.org>
+
+        [Chromium] Clean up texture ids on the impl side when losing the context
+        https://bugs.webkit.org/show_bug.cgi?id=84122
+
+        Reviewed by James Robinson.
+
+        Tested by CCLayerTreeHostImplTest.dontUseOldResourcesAfterLostContext.
+
+        * platform/graphics/chromium/cc/CCTextureLayerImpl.cpp:
+        (WebCore::CCTextureLayerImpl::didLoseContext):
+        * platform/graphics/chromium/cc/CCTiledLayerImpl.cpp:
+        (WebCore::CCTiledLayerImpl::didLoseContext):
+        (WebCore):
+        * platform/graphics/chromium/cc/CCTiledLayerImpl.h:
+        (CCTiledLayerImpl):
+        * platform/graphics/chromium/cc/CCVideoLayerImpl.cpp:
+        (WebCore::CCVideoLayerImpl::didLoseContext):
+        (WebCore):
+        * platform/graphics/chromium/cc/CCVideoLayerImpl.h:
+        (CCVideoLayerImpl):
+
 2012-04-17  Emil A Eklund  <eae@chromium.org>
 
         Change RenderThemeChromiumSkia paint methods to use pixel snapping
index 12cbab62570667c88dc87709668832388c24f94f..8534a8c85fdddbf10d83e7283d02f554f8e58f2f 100644 (file)
@@ -105,6 +105,7 @@ void CCTextureLayerImpl::dumpLayerProperties(TextStream& ts, int indent) const
 
 void CCTextureLayerImpl::didLoseContext()
 {
+    m_textureId = 0;
     if (m_ioSurfaceId) {
         // We don't have a valid texture ID in the new context; however,
         // the IOSurface is still valid.
index c5d2a45939e490ccbb3dd09abd7eaa3cc0e4b7df..ec22a9fd676b9082f7085c9a29a50a4cdae219ae 100644 (file)
@@ -235,6 +235,11 @@ Region CCTiledLayerImpl::visibleContentOpaqueRegion() const
     return m_tiler->opaqueRegionInLayerRect(visibleLayerRect());
 }
 
+void CCTiledLayerImpl::didLoseContext()
+{
+    m_tiler->reset();
+}
+
 } // namespace WebCore
 
 #endif // USE(ACCELERATED_COMPOSITING)
index ce3cd62f846ee2c5e7abbe97a07eceda168d9869..6fc5c9e49df6aed2210590d5d64114382c05643f 100644 (file)
@@ -57,6 +57,7 @@ public:
     bool contentsSwizzled() const { return m_contentsSwizzled; }
 
     virtual Region visibleContentOpaqueRegion() const OVERRIDE;
+    virtual void didLoseContext() OVERRIDE;
 
     typedef ProgramBinding<VertexShaderTile, FragmentShaderRGBATexAlpha> Program;
     // Shader program that swaps red and blue components of texture.
index a1dac35e9145380ea9da30ad81062669d266ccef..83d262f1109727a62d0189c1b39c035162cc36b7 100644 (file)
@@ -253,6 +253,12 @@ void CCVideoLayerImpl::didUpdateMatrix(const float matrix[16])
     setNeedsRedraw();
 }
 
+void CCVideoLayerImpl::didLoseContext()
+{
+    for (unsigned i = 0; i < MaxPlanes; ++i)
+        m_textures[i].m_texture.clear();
+}
+
 void CCVideoLayerImpl::setNeedsRedraw()
 {
     if (m_layerTreeHostImpl)
index cacfef8260e3c0a852314539ff677e4436a21a05..9a99285dddd3520cd2309a004f31fc78effc59f8 100644 (file)
@@ -70,6 +70,8 @@ public:
     virtual void didReceiveFrame(); // Callable on impl thread.
     virtual void didUpdateMatrix(const float*); // Callable on impl thread.
 
+    virtual void didLoseContext() OVERRIDE;
+
     void setNeedsRedraw();
 
     static const float yuv2RGB[9];
index 4db2dbcd1a2671b74c109cb0c50dec586e17e604..077e4c239bd353789a97215f12ae980930780899 100644 (file)
@@ -1153,4 +1153,183 @@ TEST_F(CCLayerTreeHostImplTest, scrollbarLayerLostContext)
     }
 }
 
+// Fake WebGraphicsContext3D that will cause a failure if trying to use a
+// resource that wasn't created by it (resources created by
+// FakeWebGraphicsContext3D have an id of 1).
+class StrictWebGraphicsContext3D : public FakeWebGraphicsContext3D {
+public:
+    virtual WebGLId createBuffer() { return 2; }
+    virtual WebGLId createFramebuffer() { return 3; }
+    virtual WebGLId createProgram() { return 4; }
+    virtual WebGLId createRenderbuffer() { return 5; }
+    virtual WebGLId createShader(WGC3Denum) { return 6; }
+    virtual WebGLId createTexture() { return 7; }
+
+    virtual void deleteBuffer(WebGLId id)
+    {
+        if (id != 2)
+            ADD_FAILURE() << "Trying to delete buffer id " << id;
+    }
+
+    virtual void deleteFramebuffer(WebGLId id)
+    {
+        if (id != 3)
+            ADD_FAILURE() << "Trying to delete framebuffer id " << id;
+    }
+
+    virtual void deleteProgram(WebGLId id)
+    {
+        if (id != 4)
+            ADD_FAILURE() << "Trying to delete program id " << id;
+    }
+
+    virtual void deleteRenderbuffer(WebGLId id)
+    {
+        if (id != 5)
+            ADD_FAILURE() << "Trying to delete renderbuffer id " << id;
+    }
+
+    virtual void deleteShader(WebGLId id)
+    {
+        if (id != 6)
+            ADD_FAILURE() << "Trying to delete shader id " << id;
+    }
+
+    virtual void deleteTexture(WebGLId id)
+    {
+        if (id != 7)
+            ADD_FAILURE() << "Trying to delete texture id " << id;
+    }
+
+    virtual void bindBuffer(WGC3Denum, WebGLId id)
+    {
+        if (id != 2 && id)
+            ADD_FAILURE() << "Trying to bind buffer id " << id;
+    }
+
+    virtual void bindFramebuffer(WGC3Denum, WebGLId id)
+    {
+        if (id != 3 && id)
+            ADD_FAILURE() << "Trying to bind framebuffer id " << id;
+    }
+
+    virtual void useProgram(WebGLId id)
+    {
+        if (id != 4)
+            ADD_FAILURE() << "Trying to use program id " << id;
+    }
+
+    virtual void bindRenderbuffer(WGC3Denum, WebGLId id)
+    {
+        if (id != 5 && id)
+            ADD_FAILURE() << "Trying to bind renderbuffer id " << id;
+    }
+
+    virtual void attachShader(WebGLId program, WebGLId shader)
+    {
+        if ((program != 4) || (shader != 6))
+            ADD_FAILURE() << "Trying to attach shader id " << shader << " to program id " << program;
+    }
+
+    virtual void bindTexture(WGC3Denum, WebGLId id)
+    {
+        if (id != 7 && id)
+            ADD_FAILURE() << "Trying to bind texture id " << id;
+    }
+
+    static PassRefPtr<GraphicsContext3D> createGraphicsContext()
+    {
+        return GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new StrictWebGraphicsContext3D()), GraphicsContext3D::RenderDirectlyToHostWindow);
+    }
+};
+
+// Fake video frame that represents a 4x4 YUV video frame.
+class FakeVideoFrame: public WebVideoFrame {
+public:
+    FakeVideoFrame() { memset(m_data, 0x80, sizeof(m_data)); }
+    virtual ~FakeVideoFrame() { }
+    virtual Format format() const { return FormatYV12; }
+    virtual unsigned width() const { return 4; }
+    virtual unsigned height() const { return 4; }
+    virtual unsigned planes() const { return 3; }
+    virtual int stride(unsigned plane) const { return 4; }
+    virtual const void* data(unsigned plane) const { return m_data; }
+    virtual unsigned textureId() const { return 0; }
+    virtual unsigned textureTarget() const { return 0; }
+
+private:
+    char m_data[16];
+};
+
+// Fake video frame provider that always provides the same FakeVideoFrame.
+class FakeVideoFrameProvider: public WebVideoFrameProvider {
+public:
+    FakeVideoFrameProvider() : m_client(0) { }
+    virtual ~FakeVideoFrameProvider()
+    {
+        if (m_client)
+            m_client->stopUsingProvider();
+    }
+
+    virtual void setVideoFrameProviderClient(Client* client) { m_client = client; }
+    virtual WebVideoFrame* getCurrentFrame() { return &m_frame; }
+    virtual void putCurrentFrame(WebVideoFrame*) { }
+
+private:
+    FakeVideoFrame m_frame;
+    Client* m_client;
+};
+
+TEST_F(CCLayerTreeHostImplTest, dontUseOldResourcesAfterLostContext)
+{
+    m_hostImpl->initializeLayerRenderer(createContext());
+    m_hostImpl->setViewportSize(IntSize(10, 10));
+
+    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);
+    rootLayer->addChild(videoLayer.release());
+
+    m_hostImpl->setRootLayer(rootLayer.release());
+
+    CCLayerTreeHostImpl::FrameData frame;
+    EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
+    m_hostImpl->drawLayers(frame);
+    m_hostImpl->swapBuffers();
+
+    // Lose the context, replacing it with a StrictWebGraphicsContext3D, that
+    // will warn if any resource from the previous context gets used.
+    m_hostImpl->initializeLayerRenderer(StrictWebGraphicsContext3D::createGraphicsContext());
+    EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
+    m_hostImpl->drawLayers(frame);
+    m_hostImpl->swapBuffers();
+}
+
 } // namespace