Coordinated Graphics: Refactor code related to directly composited images.
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 16 Nov 2012 02:24:31 +0000 (02:24 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 16 Nov 2012 02:24:31 +0000 (02:24 +0000)
https://bugs.webkit.org/show_bug.cgi?id=101023

Patch by Huang Dongsung <luxtella@company100.net> on 2012-11-15
Reviewed by Noam Rosenthal.

Internal Review by Gwang Yoon Hwang and Jae Hyun Park.

Currently, LayerTreeCoordinator manages composited images using
ShareableBitmap. This patch introduces CoordinatedImageBacking which
plays a role in managing composited images. CoordinatedImageBacking makes us
gather code related to a directly composited image into a single class.

We create only one CoordinatedImageBacking per image. For example, in the leaves
demo, we create only 3 textures of leaves.

* CMakeLists.txt:
* Shared/WebLayerTreeInfo.h:
(WebKit::WebLayerInfo::WebLayerInfo):
(WebLayerInfo):
* Target.pri:
* UIProcess/CoordinatedGraphics/CoordinatedBackingStore.cpp:
(WebKit::CoordinatedBackingStoreTile::swapBuffers):
* UIProcess/CoordinatedGraphics/LayerTreeCoordinatorProxy.cpp:
(WebKit::LayerTreeCoordinatorProxy::createImageBacking):
(WebKit::LayerTreeCoordinatorProxy::updateImageBacking):
(WebKit):
(WebKit::LayerTreeCoordinatorProxy::removeImageBacking):
* UIProcess/CoordinatedGraphics/LayerTreeCoordinatorProxy.h:
(LayerTreeCoordinatorProxy):
* UIProcess/CoordinatedGraphics/LayerTreeCoordinatorProxy.messages.in:
* UIProcess/CoordinatedGraphics/LayerTreeRenderer.cpp:
(WebKit::LayerTreeRenderer::setLayerState):
(WebKit::LayerTreeRenderer::createImageBacking):
(WebKit::LayerTreeRenderer::updateImageBacking):
(WebKit::LayerTreeRenderer::removeImageBacking):
(WebKit):
(WebKit::LayerTreeRenderer::assignImageBackingToLayer):
(WebKit::LayerTreeRenderer::removeReleasedImageBackingsIfNeeded):
(WebKit::LayerTreeRenderer::flushLayerChanges):
(WebKit::LayerTreeRenderer::purgeGLResources):
* UIProcess/CoordinatedGraphics/LayerTreeRenderer.h:
(LayerTreeRenderer):
* WebProcess/WebPage/CoordinatedGraphics/CoordinatedGraphicsLayer.cpp:
(WebCore::CoordinatedGraphicsLayer::setContentsToImage):
(WebCore::CoordinatedGraphicsLayer::syncImageBacking):
(WebCore::CoordinatedGraphicsLayer::releaseImageBackingIfNeeded):
(WebCore::CoordinatedGraphicsLayer::beginContentUpdate):
* WebProcess/WebPage/CoordinatedGraphics/CoordinatedGraphicsLayer.h:
(CoordinatedGraphicsLayerClient):
(CoordinatedGraphicsLayer):
* WebProcess/WebPage/CoordinatedGraphics/CoordinatedImageBacking.cpp: Added.
(WebKit):
(WebKit::CoordinatedImageBacking::getCoordinatedImageBackingID):
(WebKit::CoordinatedImageBacking::create):
(WebKit::CoordinatedImageBacking::CoordinatedImageBacking):
(WebKit::CoordinatedImageBacking::~CoordinatedImageBacking):
(WebKit::CoordinatedImageBacking::addLayerClient):
(WebKit::CoordinatedImageBacking::removeLayerClient):
(WebKit::CoordinatedImageBacking::markDirty):
(WebKit::CoordinatedImageBacking::update):
(WebKit::CoordinatedImageBacking::releaseSurfaceIfNeeded):
* WebProcess/WebPage/CoordinatedGraphics/CoordinatedImageBacking.h: Added.
(WebCore):
(WebKit):
(CoordinatedImageBacking):
(Coordinator):
(WebKit::CoordinatedImageBacking::id):
* WebProcess/WebPage/CoordinatedGraphics/LayerTreeCoordinator.cpp:
(WebKit::LayerTreeCoordinator::flushPendingLayerChanges):
(WebKit::LayerTreeCoordinator::createImageBackingIfNeeded):
(WebKit::LayerTreeCoordinator::createImageBacking):
(WebKit::LayerTreeCoordinator::updateImageBacking):
(WebKit::LayerTreeCoordinator::removeImageBacking):
(WebKit::LayerTreeCoordinator::flushPendingImageBackingChanges):
(WebKit::LayerTreeCoordinator::purgeBackingStores):
* WebProcess/WebPage/CoordinatedGraphics/LayerTreeCoordinator.h:
(LayerTreeCoordinator):

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

16 files changed:
Source/WebKit2/CMakeLists.txt
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/WebLayerTreeInfo.h
Source/WebKit2/Target.pri
Source/WebKit2/UIProcess/CoordinatedGraphics/CoordinatedBackingStore.cpp
Source/WebKit2/UIProcess/CoordinatedGraphics/LayerTreeCoordinatorProxy.cpp
Source/WebKit2/UIProcess/CoordinatedGraphics/LayerTreeCoordinatorProxy.h
Source/WebKit2/UIProcess/CoordinatedGraphics/LayerTreeCoordinatorProxy.messages.in
Source/WebKit2/UIProcess/CoordinatedGraphics/LayerTreeRenderer.cpp
Source/WebKit2/UIProcess/CoordinatedGraphics/LayerTreeRenderer.h
Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedGraphicsLayer.cpp
Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedGraphicsLayer.h
Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedImageBacking.cpp [new file with mode: 0644]
Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedImageBacking.h [new file with mode: 0644]
Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/LayerTreeCoordinator.cpp
Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/LayerTreeCoordinator.h

index 6e46f48..05d7c6d 100644 (file)
@@ -494,6 +494,7 @@ SET(WebKit2_SOURCES
     WebProcess/WebPage/WebPageGroupProxy.cpp
     WebProcess/WebPage/WebUndoStep.cpp
 
+    WebProcess/WebPage/CoordinatedGraphics/CoordinatedImageBacking.cpp
     WebProcess/WebPage/CoordinatedGraphics/CoordinatedGraphicsLayer.cpp
     WebProcess/WebPage/CoordinatedGraphics/CoordinatedTile.cpp
     WebProcess/WebPage/CoordinatedGraphics/LayerTreeCoordinator.cpp
index 7c3d8a8..464aec5 100644 (file)
@@ -1,5 +1,85 @@
 2012-11-15  Huang Dongsung  <luxtella@company100.net>
 
+        Coordinated Graphics: Refactor code related to directly composited images.
+        https://bugs.webkit.org/show_bug.cgi?id=101023
+
+        Reviewed by Noam Rosenthal.
+
+        Internal Review by Gwang Yoon Hwang and Jae Hyun Park.
+
+        Currently, LayerTreeCoordinator manages composited images using
+        ShareableBitmap. This patch introduces CoordinatedImageBacking which
+        plays a role in managing composited images. CoordinatedImageBacking makes us
+        gather code related to a directly composited image into a single class.
+
+        We create only one CoordinatedImageBacking per image. For example, in the leaves
+        demo, we create only 3 textures of leaves.
+
+        * CMakeLists.txt:
+        * Shared/WebLayerTreeInfo.h:
+        (WebKit::WebLayerInfo::WebLayerInfo):
+        (WebLayerInfo):
+        * Target.pri:
+        * UIProcess/CoordinatedGraphics/CoordinatedBackingStore.cpp:
+        (WebKit::CoordinatedBackingStoreTile::swapBuffers):
+        * UIProcess/CoordinatedGraphics/LayerTreeCoordinatorProxy.cpp:
+        (WebKit::LayerTreeCoordinatorProxy::createImageBacking):
+        (WebKit::LayerTreeCoordinatorProxy::updateImageBacking):
+        (WebKit):
+        (WebKit::LayerTreeCoordinatorProxy::removeImageBacking):
+        * UIProcess/CoordinatedGraphics/LayerTreeCoordinatorProxy.h:
+        (LayerTreeCoordinatorProxy):
+        * UIProcess/CoordinatedGraphics/LayerTreeCoordinatorProxy.messages.in:
+        * UIProcess/CoordinatedGraphics/LayerTreeRenderer.cpp:
+        (WebKit::LayerTreeRenderer::setLayerState):
+        (WebKit::LayerTreeRenderer::createImageBacking):
+        (WebKit::LayerTreeRenderer::updateImageBacking):
+        (WebKit::LayerTreeRenderer::removeImageBacking):
+        (WebKit):
+        (WebKit::LayerTreeRenderer::assignImageBackingToLayer):
+        (WebKit::LayerTreeRenderer::removeReleasedImageBackingsIfNeeded):
+        (WebKit::LayerTreeRenderer::flushLayerChanges):
+        (WebKit::LayerTreeRenderer::purgeGLResources):
+        * UIProcess/CoordinatedGraphics/LayerTreeRenderer.h:
+        (LayerTreeRenderer):
+        * WebProcess/WebPage/CoordinatedGraphics/CoordinatedGraphicsLayer.cpp:
+        (WebCore::CoordinatedGraphicsLayer::setContentsToImage):
+        (WebCore::CoordinatedGraphicsLayer::syncImageBacking):
+        (WebCore::CoordinatedGraphicsLayer::releaseImageBackingIfNeeded):
+        (WebCore::CoordinatedGraphicsLayer::beginContentUpdate):
+        * WebProcess/WebPage/CoordinatedGraphics/CoordinatedGraphicsLayer.h:
+        (CoordinatedGraphicsLayerClient):
+        (CoordinatedGraphicsLayer):
+        * WebProcess/WebPage/CoordinatedGraphics/CoordinatedImageBacking.cpp: Added.
+        (WebKit):
+        (WebKit::CoordinatedImageBacking::getCoordinatedImageBackingID):
+        (WebKit::CoordinatedImageBacking::create):
+        (WebKit::CoordinatedImageBacking::CoordinatedImageBacking):
+        (WebKit::CoordinatedImageBacking::~CoordinatedImageBacking):
+        (WebKit::CoordinatedImageBacking::addLayerClient):
+        (WebKit::CoordinatedImageBacking::removeLayerClient):
+        (WebKit::CoordinatedImageBacking::markDirty):
+        (WebKit::CoordinatedImageBacking::update):
+        (WebKit::CoordinatedImageBacking::releaseSurfaceIfNeeded):
+        * WebProcess/WebPage/CoordinatedGraphics/CoordinatedImageBacking.h: Added.
+        (WebCore):
+        (WebKit):
+        (CoordinatedImageBacking):
+        (Coordinator):
+        (WebKit::CoordinatedImageBacking::id):
+        * WebProcess/WebPage/CoordinatedGraphics/LayerTreeCoordinator.cpp:
+        (WebKit::LayerTreeCoordinator::flushPendingLayerChanges):
+        (WebKit::LayerTreeCoordinator::createImageBackingIfNeeded):
+        (WebKit::LayerTreeCoordinator::createImageBacking):
+        (WebKit::LayerTreeCoordinator::updateImageBacking):
+        (WebKit::LayerTreeCoordinator::removeImageBacking):
+        (WebKit::LayerTreeCoordinator::flushPendingImageBackingChanges):
+        (WebKit::LayerTreeCoordinator::purgeBackingStores):
+        * WebProcess/WebPage/CoordinatedGraphics/LayerTreeCoordinator.h:
+        (LayerTreeCoordinator):
+
+2012-11-15  Huang Dongsung  <luxtella@company100.net>
+
         Coordinated Graphics: A Minor optimization of calculating transforms in CoordinagedGraphicsLayer.
         https://bugs.webkit.org/show_bug.cgi?id=102309
 
index 58e07bc..e6a2aed 100644 (file)
 #include "FloatRect.h"
 #include "FloatSize.h"
 #include "GraphicsLayer.h"
-#include "ShareableBitmap.h"
 
 namespace WebKit {
 
 typedef uint32_t WebLayerID;
 enum { InvalidWebLayerID = 0 };
 
+typedef uintptr_t CoordinatedImageBackingID;
+enum { InvalidCoordinatedImageBackingID = 0 };
+
 // NOTE: WebLayerInfo should only use POD types, as to make serialization faster.
 struct WebLayerInfo {
     WebLayerInfo()
         : replica(InvalidWebLayerID)
         , mask(InvalidWebLayerID)
-        , imageBackingStoreID(0)
+        , imageID(InvalidCoordinatedImageBackingID)
         , opacity(0)
         , flags(0) { }
 
     WebLayerID replica;
     WebLayerID mask;
-    int64_t imageBackingStoreID;
+    CoordinatedImageBackingID imageID;
 
     WebCore::FloatPoint pos;
     WebCore::FloatPoint3D anchorPoint;
index dac9b9a..7cd016e 100644 (file)
@@ -369,6 +369,7 @@ HEADERS += \
     WebProcess/WebPage/EventDispatcher.h \
     WebProcess/WebPage/FindController.h \
     WebProcess/WebPage/CoordinatedGraphics/CoordinatedGraphicsLayer.h \
+    WebProcess/WebPage/CoordinatedGraphics/CoordinatedImageBacking.h \
     WebProcess/WebPage/CoordinatedGraphics/CoordinatedTile.h \
     WebProcess/WebPage/CoordinatedGraphics/LayerTreeCoordinator.h \
     WebProcess/WebPage/TapHighlightController.h \
@@ -750,6 +751,7 @@ SOURCES += \
     WebProcess/WebPage/EventDispatcher.cpp \
     WebProcess/WebPage/FindController.cpp \
     WebProcess/WebPage/CoordinatedGraphics/CoordinatedGraphicsLayer.cpp \
+    WebProcess/WebPage/CoordinatedGraphics/CoordinatedImageBacking.cpp \
     WebProcess/WebPage/CoordinatedGraphics/CoordinatedTile.cpp \
     WebProcess/WebPage/CoordinatedGraphics/LayerTreeCoordinator.cpp \
     WebProcess/WebPage/TapHighlightController.cpp \
index 51ed6c8..054a1e9 100644 (file)
@@ -49,6 +49,7 @@ void CoordinatedBackingStoreTile::swapBuffers(WebCore::TextureMapper* textureMap
         shouldReset = true;
     }
 
+    ASSERT(textureMapper->maxTextureSize() >= std::max(m_tileRect.size().width(), m_tileRect.size().height()));
     if (shouldReset)
         texture->reset(m_tileRect.size(), m_surface->flags() & ShareableBitmap::SupportsAlpha ? BitmapTexture::SupportsAlpha : 0);
 
index b3d140f..46fee53 100644 (file)
@@ -127,15 +127,19 @@ void LayerTreeCoordinatorProxy::didRenderFrame(const WebCore::IntSize& contentsS
 #endif
 }
 
-void LayerTreeCoordinatorProxy::createDirectlyCompositedImage(int64_t key, const WebKit::ShareableBitmap::Handle& handle)
+void LayerTreeCoordinatorProxy::createImageBacking(CoordinatedImageBackingID imageID)
 {
-    RefPtr<ShareableBitmap> bitmap = ShareableBitmap::create(handle);
-    dispatchUpdate(bind(&LayerTreeRenderer::createImage, m_renderer.get(), key, bitmap));
+    dispatchUpdate(bind(&LayerTreeRenderer::createImageBacking, m_renderer.get(), imageID));
 }
 
-void LayerTreeCoordinatorProxy::destroyDirectlyCompositedImage(int64_t key)
+void LayerTreeCoordinatorProxy::updateImageBacking(CoordinatedImageBackingID imageID, const ShareableSurface::Handle& handle)
 {
-    dispatchUpdate(bind(&LayerTreeRenderer::destroyImage, m_renderer.get(), key));
+    dispatchUpdate(bind(&LayerTreeRenderer::updateImageBacking, m_renderer.get(), imageID, ShareableSurface::create(handle)));
+}
+
+void LayerTreeCoordinatorProxy::removeImageBacking(CoordinatedImageBackingID imageID)
+{
+    dispatchUpdate(bind(&LayerTreeRenderer::removeImageBacking, m_renderer.get(), imageID));
 }
 
 void LayerTreeCoordinatorProxy::setContentsSize(const FloatSize& contentsSize)
index 6468011..4e9978a 100644 (file)
@@ -67,8 +67,9 @@ public:
     void removeTileForLayer(int layerID, int tileID);
     void createUpdateAtlas(int atlasID, const ShareableSurface::Handle&);
     void removeUpdateAtlas(int atlasID);
-    void createDirectlyCompositedImage(int64_t, const WebKit::ShareableBitmap::Handle&);
-    void destroyDirectlyCompositedImage(int64_t);
+    void createImageBacking(CoordinatedImageBackingID);
+    void updateImageBacking(CoordinatedImageBackingID, const ShareableSurface::Handle&);
+    void removeImageBacking(CoordinatedImageBackingID);
     void didReceiveLayerTreeCoordinatorProxyMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::MessageDecoder&);
     void updateViewport();
     void renderNextFrame();
index cd32ed9..7f744a6 100644 (file)
@@ -31,8 +31,9 @@ messages -> LayerTreeCoordinatorProxy {
     RemoveTileForLayer(uint32_t layerID, int tileID)
     CreateUpdateAtlas(int atlasID, WebKit::ShareableSurface::Handle handle)
     RemoveUpdateAtlas(int atlasID)
-    CreateDirectlyCompositedImage(int64_t key, WebKit::ShareableBitmap::Handle handle)
-    DestroyDirectlyCompositedImage(int64_t key)
+    CreateImageBacking(uintptr_t imageID)
+    UpdateImageBacking(uintptr_t imageID, WebKit::ShareableSurface::Handle handle)
+    RemoveImageBacking(uintptr_t imageID)
     DidRenderFrame(WebCore::IntSize contentsSize, WebCore::IntRect coveredRect)
     DidChangeScrollPosition(WebCore::IntPoint position)
     SetLayerAnimations(uint32_t id, WebCore::GraphicsLayerAnimations animations)
index 11ed03b..0bf72a6 100644 (file)
@@ -1,5 +1,6 @@
 /*
     Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
+    Copyright (C) 2012 Company 100, Inc.
 
     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Library General Public
@@ -27,7 +28,6 @@
 #include "GraphicsLayerTextureMapper.h"
 #include "LayerTreeCoordinatorProxy.h"
 #include "MessageID.h"
-#include "ShareableBitmap.h"
 #include "TextureMapper.h"
 #include "TextureMapperBackingStore.h"
 #include "TextureMapperGL.h"
@@ -302,7 +302,7 @@ void LayerTreeRenderer::setLayerState(WebLayerID id, const WebLayerInfo& layerIn
     else
         m_fixedLayers.remove(id);
 
-    assignImageToLayer(layer, layerInfo.imageBackingStoreID);
+    assignImageBackingToLayer(layer, layerInfo.imageID);
 
     // Never make the root layer clip.
     layer->setMasksToBounds(layerInfo.isRootLayer ? false : layerInfo.masksToBounds);
@@ -416,31 +416,56 @@ void LayerTreeRenderer::updateTile(WebLayerID layerID, int tileID, const TileUpd
     m_backingStoresWithPendingBuffers.add(backingStore);
 }
 
-void LayerTreeRenderer::createImage(int64_t imageID, PassRefPtr<ShareableBitmap> weakBitmap)
+void LayerTreeRenderer::createImageBacking(CoordinatedImageBackingID imageID)
 {
-    RefPtr<ShareableBitmap> bitmap = weakBitmap;
-    RefPtr<TextureMapperTiledBackingStore> backingStore = TextureMapperTiledBackingStore::create();
-    m_directlyCompositedImages.set(imageID, backingStore);
-    backingStore->updateContents(m_textureMapper.get(), bitmap->createImage().get(), BitmapTexture::UpdateCannotModifyOriginalImageData);
+    ASSERT(!m_imageBackings.contains(imageID));
+    RefPtr<CoordinatedBackingStore> backingStore(CoordinatedBackingStore::create());
+    m_imageBackings.add(imageID, backingStore.release());
 }
 
-void LayerTreeRenderer::destroyImage(int64_t imageID)
+void LayerTreeRenderer::updateImageBacking(CoordinatedImageBackingID imageID, PassRefPtr<ShareableSurface> surface)
 {
-    m_directlyCompositedImages.remove(imageID);
+    ASSERT(m_imageBackings.contains(imageID));
+    ImageBackingMap::iterator it = m_imageBackings.find(imageID);
+    RefPtr<CoordinatedBackingStore> backingStore = it->value;
+
+    // CoordinatedImageBacking is realized to CoordinatedBackingStore with only one tile in UI Process.
+    backingStore->createTile(1 /* id */, 1 /* scale */);
+    IntRect rect(IntPoint::zero(), surface->size());
+    // See CoordinatedGraphicsLayer::shouldDirectlyCompositeImage()
+    ASSERT(2000 >= std::max(rect.width(), rect.height()));
+    backingStore->setSize(rect.size());
+    backingStore->updateTile(1 /* id */, rect, rect, surface, rect.location());
+
+    m_backingStoresWithPendingBuffers.add(backingStore);
 }
 
-void LayerTreeRenderer::assignImageToLayer(GraphicsLayer* layer, int64_t imageID)
+void LayerTreeRenderer::removeImageBacking(CoordinatedImageBackingID imageID)
 {
-    if (!imageID) {
+    ASSERT(m_imageBackings.contains(imageID));
+
+    // We don't want TextureMapperLayer refers a dangling pointer.
+    ImageBackingMap::iterator it = m_imageBackings.find(imageID);
+    m_releasedImageBackings.append(it->value);
+    m_imageBackings.remove(imageID);
+}
+
+void LayerTreeRenderer::assignImageBackingToLayer(GraphicsLayer* layer, CoordinatedImageBackingID imageID)
+{
+    if (imageID == InvalidCoordinatedImageBackingID) {
         layer->setContentsToMedia(0);
         return;
     }
-
-    HashMap<int64_t, RefPtr<TextureMapperBackingStore> >::iterator it = m_directlyCompositedImages.find(imageID);
-    ASSERT(it != m_directlyCompositedImages.end());
+    ImageBackingMap::iterator it = m_imageBackings.find(imageID);
+    ASSERT(it != m_imageBackings.end());
     layer->setContentsToMedia(it->value.get());
 }
 
+void LayerTreeRenderer::removeReleasedImageBackingsIfNeeded()
+{
+    m_releasedImageBackings.clear();
+}
+
 void LayerTreeRenderer::commitTileOperations()
 {
     HashSet<RefPtr<CoordinatedBackingStore> >::iterator end = m_backingStoresWithPendingBuffers.end();
@@ -459,6 +484,7 @@ void LayerTreeRenderer::flushLayerChanges()
 
     m_rootLayer->flushCompositingState(FloatRect());
     commitTileOperations();
+    removeReleasedImageBackingsIfNeeded();
 
     // The pending tiles state is on its way for the screen, tell the web process to render the next one.
     dispatchOnMainThread(bind(&LayerTreeRenderer::renderNextFrame, this));
@@ -515,7 +541,7 @@ void LayerTreeRenderer::purgeGLResources()
     if (layer)
         layer->clearBackingStoresRecursive();
 
-    m_directlyCompositedImages.clear();
+    m_imageBackings.clear();
 #if USE(GRAPHICS_SURFACE)
     m_surfaceBackingStores.clear();
 #endif
index 2ef01ec..47e23d3 100644 (file)
@@ -89,8 +89,9 @@ public:
     void removeTile(WebLayerID, int);
     void updateTile(WebLayerID, int, const TileUpdate&);
     void flushLayerChanges();
-    void createImage(int64_t, PassRefPtr<ShareableBitmap>);
-    void destroyImage(int64_t);
+    void createImageBacking(CoordinatedImageBackingID);
+    void updateImageBacking(CoordinatedImageBackingID, PassRefPtr<ShareableSurface>);
+    void removeImageBacking(CoordinatedImageBackingID);
     void setLayerAnimations(WebLayerID, const WebCore::GraphicsLayerAnimations&);
     void setAnimationsLocked(bool);
 
@@ -119,7 +120,8 @@ private:
     void dispatchOnMainThread(const Function<void()>&);
     void adjustPositionForFixedLayers();
 
-    void assignImageToLayer(WebCore::GraphicsLayer*, int64_t imageID);
+    void assignImageBackingToLayer(WebCore::GraphicsLayer*, CoordinatedImageBackingID);
+    void removeReleasedImageBackingsIfNeeded();
     void ensureRootLayer();
     void ensureLayer(WebLayerID);
     void commitTileOperations();
@@ -139,7 +141,11 @@ private:
     Mutex m_renderQueueMutex;
 
     OwnPtr<WebCore::TextureMapper> m_textureMapper;
-    HashMap<int64_t, RefPtr<WebCore::TextureMapperBackingStore> > m_directlyCompositedImages;
+
+    typedef HashMap<CoordinatedImageBackingID, RefPtr<CoordinatedBackingStore> > ImageBackingMap;
+    ImageBackingMap m_imageBackings;
+    Vector<RefPtr<CoordinatedBackingStore> > m_releasedImageBackings;
+
     HashSet<RefPtr<CoordinatedBackingStore> > m_backingStoresWithPendingBuffers;
 
 #if USE(GRAPHICS_SURFACE)
index 43e7d63..5586d4c 100644 (file)
@@ -1,5 +1,6 @@
 /*
  Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ Copyright (C) 2012 Company 100, Inc.
 
  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Library General Public
@@ -351,8 +352,7 @@ void CoordinatedGraphicsLayer::setContentsToImage(Image* image)
         // This code makes the assumption that pointer equality on a NativeImagePtr is a valid way to tell if the image is changed.
         // This assumption is true in Qt, GTK and EFL.
         NativeImagePtr newNativeImagePtr = image->nativeImageForCurrentFrame();
-        if (!newNativeImagePtr)
-            return;
+        ASSERT(newNativeImagePtr);
 
         if (newNativeImagePtr == m_compositedNativeImagePtr)
             return;
@@ -473,16 +473,25 @@ void CoordinatedGraphicsLayer::syncImageBacking()
         return;
     m_shouldSyncImageBacking = false;
 
-    releaseImageBackingIfNeeded();
-
     if (m_compositedNativeImagePtr) {
         ASSERT(!m_mainBackingStore);
         ASSERT(m_compositedImage);
 
-        m_layerInfo.imageBackingStoreID = m_coordinator->adoptImageBackingStore(m_compositedImage.get());
-    }
+        bool imageInstanceReplaced = m_coordinatedImageBacking && (m_coordinatedImageBacking->id() != CoordinatedImageBacking::getCoordinatedImageBackingID(m_compositedImage.get()));
+        if (imageInstanceReplaced)
+            releaseImageBackingIfNeeded();
+
+        if (!m_coordinatedImageBacking) {
+            m_coordinatedImageBacking = m_coordinator->createImageBackingIfNeeded(m_compositedImage.get());
+            m_coordinatedImageBacking->addLayerClient(this);
+            m_layerInfo.imageID = m_coordinatedImageBacking->id();
+        }
+
+        m_coordinatedImageBacking->markDirty();
+    } else
+        releaseImageBackingIfNeeded();
 
-    // This method changes m_layerInfo.imageBackingStoreID.
+    // syncImageBacking() changed m_layerInfo.imageID.
     didChangeLayerState();
 }
 
@@ -554,12 +563,13 @@ void CoordinatedGraphicsLayer::flushCompositingStateForThisLayerOnly()
 
 void CoordinatedGraphicsLayer::releaseImageBackingIfNeeded()
 {
-    if (!m_layerInfo.imageBackingStoreID)
+    if (!m_coordinatedImageBacking)
         return;
 
     ASSERT(m_coordinator);
-    m_coordinator->releaseImageBackingStore(m_layerInfo.imageBackingStoreID);
-    m_layerInfo.imageBackingStoreID = 0;
+    m_coordinatedImageBacking->removeLayerClient(this);
+    m_coordinatedImageBacking.clear();
+    m_layerInfo.imageID = InvalidCoordinatedImageBackingID;
 }
 
 void CoordinatedGraphicsLayer::tiledBackingStorePaintBegin()
@@ -665,7 +675,7 @@ Color CoordinatedGraphicsLayer::tiledBackingStoreBackgroundColor() const
     return contentsOpaque() ? Color::white : Color::transparent;
 }
 
-PassOwnPtr<WebCore::GraphicsContext> CoordinatedGraphicsLayer::beginContentUpdate(const WebCore::IntSize& size, int& atlas, WebCore::IntPoint& offset)
+PassOwnPtr<GraphicsContext> CoordinatedGraphicsLayer::beginContentUpdate(const IntSize& size, int& atlas, IntPoint& offset)
 {
     if (!m_coordinator)
         return PassOwnPtr<WebCore::GraphicsContext>();
index 2e94fe4..d1f5811 100644 (file)
@@ -21,6 +21,7 @@
 #ifndef CoordinatedGraphicsLayer_h
 #define CoordinatedGraphicsLayer_h
 
+#include "CoordinatedImageBacking.h"
 #include "CoordinatedTile.h"
 #include "FloatPoint3D.h"
 #include "GraphicsLayer.h"
@@ -56,8 +57,7 @@ public:
 
     virtual WebCore::IntRect visibleContentsRect() const = 0;
     virtual bool layerTreeTileUpdatesAllowed() const = 0;
-    virtual int64_t adoptImageBackingStore(WebCore::Image*) = 0;
-    virtual void releaseImageBackingStore(int64_t) = 0;
+    virtual PassRefPtr<CoordinatedImageBacking> createImageBackingIfNeeded(WebCore::Image*) = 0;
     virtual void syncLayerState(WebLayerID, const WebLayerInfo&) = 0;
     virtual void syncLayerChildren(WebLayerID, const Vector<WebLayerID>&) = 0;
 #if ENABLE(CSS_FILTERS)
@@ -216,6 +216,7 @@ private:
 
     RefPtr<Image> m_compositedImage;
     NativeImagePtr m_compositedNativeImagePtr;
+    RefPtr<WebKit::CoordinatedImageBacking> m_coordinatedImageBacking;
 
     PlatformLayer* m_canvasPlatformLayer;
     Timer<CoordinatedGraphicsLayer> m_animationStartedTimer;
diff --git a/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedImageBacking.cpp b/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedImageBacking.cpp
new file mode 100644 (file)
index 0000000..a4f9e90
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2012 Company 100, 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 INC. 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 INC. 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(COORDINATED_GRAPHICS)
+#include "CoordinatedImageBacking.h"
+
+#include "GraphicsContext.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+CoordinatedImageBackingID CoordinatedImageBacking::getCoordinatedImageBackingID(Image* image)
+{
+    // CoordinatedImageBacking keeps a RefPtr<Image> member, so the same Image pointer can not refer two different instances until CoordinatedImageBacking releases the member.
+    return reinterpret_cast<CoordinatedImageBackingID>(image);
+}
+
+PassRefPtr<CoordinatedImageBacking> CoordinatedImageBacking::create(Coordinator* client, PassRefPtr<Image> image)
+{
+    return adoptRef(new CoordinatedImageBacking(client, image));
+}
+
+CoordinatedImageBacking::CoordinatedImageBacking(Coordinator* client, PassRefPtr<Image> image)
+    : m_coordinator(client)
+    , m_image(image)
+    , m_id(getCoordinatedImageBackingID(m_image.get()))
+    , m_isDirty(false)
+{
+    // FIXME: We would need to decode a small image directly into a GraphicsSurface.
+    // http://webkit.org/b/101426
+
+    m_coordinator->createImageBacking(id());
+}
+
+CoordinatedImageBacking::~CoordinatedImageBacking()
+{
+}
+
+void CoordinatedImageBacking::addLayerClient(CoordinatedGraphicsLayer* layerClient)
+{
+    ASSERT(!m_layerClients.contains(layerClient));
+    m_layerClients.append(layerClient);
+}
+
+void CoordinatedImageBacking::removeLayerClient(CoordinatedGraphicsLayer* layerClient)
+{
+    size_t position = m_layerClients.find(layerClient);
+    ASSERT(position != notFound);
+    m_layerClients.remove(position);
+
+    if (m_layerClients.isEmpty())
+        m_coordinator->removeImageBacking(id());
+}
+
+void CoordinatedImageBacking::markDirty()
+{
+    m_isDirty = true;
+}
+
+void CoordinatedImageBacking::update()
+{
+    releaseSurfaceIfNeeded();
+
+    if (!m_isDirty)
+        return;
+
+    m_surface = ShareableSurface::create(m_image->size(), m_image->currentFrameHasAlpha() ? ShareableBitmap::SupportsAlpha : ShareableBitmap::NoFlags, ShareableSurface::SupportsGraphicsSurface);
+    m_handle = adoptPtr(new ShareableSurface::Handle());
+
+    if (!m_surface->createHandle(*m_handle)) {
+        releaseSurfaceIfNeeded();
+        m_isDirty = false;
+        return;
+    }
+
+    IntRect rect(IntPoint::zero(), m_image->size());
+    OwnPtr<GraphicsContext> context = m_surface->createGraphicsContext(rect);
+    context->drawImage(m_image.get(), ColorSpaceDeviceRGB, rect, rect);
+
+    m_coordinator->updateImageBacking(id(), *m_handle);
+    m_isDirty = false;
+}
+
+void CoordinatedImageBacking::releaseSurfaceIfNeeded()
+{
+    // We must keep m_surface until UI Process reads m_surface.
+    // If m_surface exists, it was created in the previous update.
+    m_handle.clear();
+    m_surface.clear();
+}
+
+}
+#endif
diff --git a/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedImageBacking.h b/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/CoordinatedImageBacking.h
new file mode 100644 (file)
index 0000000..d0cd217
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2012 Company 100, 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 INC. 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 INC. 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 CoordinatedImageBacking_h
+#define CoordinatedImageBacking_h
+
+#if USE(COORDINATED_GRAPHICS)
+#include "Image.h"
+#include "ShareableSurface.h"
+#include "WebLayerTreeInfo.h"
+#include <WebCore/Timer.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+class CoordinatedGraphicsLayer;
+}
+
+namespace WebKit {
+
+class CoordinatedImageBacking : public RefCounted<CoordinatedImageBacking> {
+public:
+    class Coordinator {
+    public:
+        virtual void createImageBacking(CoordinatedImageBackingID) = 0;
+        virtual void updateImageBacking(CoordinatedImageBackingID, const ShareableSurface::Handle&) = 0;
+        virtual void removeImageBacking(CoordinatedImageBackingID) = 0;
+    };
+
+    static PassRefPtr<CoordinatedImageBacking> create(Coordinator*, PassRefPtr<WebCore::Image>);
+    virtual ~CoordinatedImageBacking();
+
+    static CoordinatedImageBackingID getCoordinatedImageBackingID(WebCore::Image*);
+    CoordinatedImageBackingID id() const { return m_id; }
+
+    void addLayerClient(WebCore::CoordinatedGraphicsLayer*);
+    void removeLayerClient(WebCore::CoordinatedGraphicsLayer*);
+
+    // When a new image is updated or an animated gif is progressed, CoordinatedGraphicsLayer calls markDirty().
+    void markDirty();
+
+    // Create, remove or update its backing.
+    void update();
+
+private:
+    CoordinatedImageBacking(Coordinator*, PassRefPtr<WebCore::Image>);
+
+    void releaseSurfaceIfNeeded();
+
+    Coordinator* m_coordinator;
+    RefPtr<WebCore::Image> m_image;
+    CoordinatedImageBackingID m_id;
+    Vector<WebCore::CoordinatedGraphicsLayer*> m_layerClients;
+
+    RefPtr<ShareableSurface> m_surface;
+    OwnPtr<ShareableSurface::Handle> m_handle;
+
+    bool m_isDirty;
+};
+
+}
+#endif
+
+#endif // CoordinatedImageBacking_H
index bb9eb3b..59a94dd 100644 (file)
@@ -268,7 +268,7 @@ bool LayerTreeCoordinator::flushPendingLayerChanges()
 
     m_rootLayer->flushCompositingStateForThisLayerOnly();
 
-    purgeReleasedImages();
+    flushPendingImageBackingChanges();
 
     if (m_shouldSyncRootLayer) {
         m_webPage->send(Messages::LayerTreeCoordinatorProxy::SetRootCompositingLayer(toCoordinatedGraphicsLayer(m_rootLayer.get())->id()));
@@ -439,15 +439,6 @@ void LayerTreeCoordinator::didPerformScheduledLayerFlush()
     }
 }
 
-void LayerTreeCoordinator::purgeReleasedImages()
-{
-    if (!m_isPurging) {
-        for (size_t i = 0; i < m_releasedDirectlyCompositedImages.size(); ++i)
-            m_webPage->send(Messages::LayerTreeCoordinatorProxy::DestroyDirectlyCompositedImage(m_releasedDirectlyCompositedImages[i]));
-    }
-    m_releasedDirectlyCompositedImages.clear();
-}
-
 void LayerTreeCoordinator::layerFlushTimerFired(Timer<LayerTreeCoordinator>*)
 {
     performScheduledLayerFlush();
@@ -475,79 +466,49 @@ void LayerTreeCoordinator::destroyPageOverlayLayer()
     m_pageOverlayLayer = nullptr;
 }
 
-int64_t LayerTreeCoordinator::adoptImageBackingStore(Image* image)
+PassRefPtr<CoordinatedImageBacking> LayerTreeCoordinator::createImageBackingIfNeeded(Image* image)
 {
-    if (!image)
-        return InvalidWebLayerID;
-
-    int64_t key = 0;
-
-#if PLATFORM(QT)
-    QPixmap* nativeImage = image->nativeImageForCurrentFrame();
-
-    if (!nativeImage)
-        return InvalidWebLayerID;
-
-    key = nativeImage->cacheKey();
-#elif USE(CAIRO)
-    NativeImageCairo* nativeImage = image->nativeImageForCurrentFrame();
-    if (!nativeImage)
-        return InvalidWebLayerID;
-    // This can be safely done since we own the reference.
-    // A corresponding cairo_surface_destroy() is ensured in releaseImageBackingStore().
-    cairo_surface_t* cairoSurface = cairo_surface_reference(nativeImage->surface());
-    key = reinterpret_cast<int64_t>(cairoSurface);
-#endif
-
-    HashMap<int64_t, int>::iterator it = m_directlyCompositedImageRefCounts.find(key);
-
-    if (it != m_directlyCompositedImageRefCounts.end()) {
-        ++(it->value);
-        return key;
-    }
-
-    // Check if we were going to release this image during the next flush.
-    size_t releasedIndex = m_releasedDirectlyCompositedImages.find(key);
-    if (releasedIndex == notFound) {
-        RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(image->size(), (image->currentFrameHasAlpha() ? ShareableBitmap::SupportsAlpha : 0));
-        {
-            OwnPtr<WebCore::GraphicsContext> graphicsContext = bitmap->createGraphicsContext();
-            graphicsContext->drawImage(image, ColorSpaceDeviceRGB, IntPoint::zero());
-        }
-        ShareableBitmap::Handle handle;
-        bitmap->createHandle(handle);
-        m_webPage->send(Messages::LayerTreeCoordinatorProxy::CreateDirectlyCompositedImage(key, handle));
+    CoordinatedImageBackingID imageID = CoordinatedImageBacking::getCoordinatedImageBackingID(image);
+    ImageBackingMap::iterator it = m_imageBackings.find(imageID);
+    RefPtr<CoordinatedImageBacking> imageBacking;
+    if (it == m_imageBackings.end()) {
+        imageBacking = CoordinatedImageBacking::create(this, image);
+        m_imageBackings.add(imageID, imageBacking);
     } else
-        m_releasedDirectlyCompositedImages.remove(releasedIndex);
+        imageBacking = it->value;
 
-    m_directlyCompositedImageRefCounts.add(key, 1);
-    return key;
+    return imageBacking;
 }
 
-void LayerTreeCoordinator::releaseImageBackingStore(int64_t key)
+void LayerTreeCoordinator::createImageBacking(CoordinatedImageBackingID imageID)
 {
-    if (!key)
-        return;
-    HashMap<int64_t, int>::iterator it = m_directlyCompositedImageRefCounts.find(key);
-    if (it == m_directlyCompositedImageRefCounts.end())
-        return;
+    m_shouldSyncFrame = true;
+    m_webPage->send(Messages::LayerTreeCoordinatorProxy::CreateImageBacking(imageID));
+}
 
-    it->value--;
+void LayerTreeCoordinator::updateImageBacking(CoordinatedImageBackingID imageID, const ShareableSurface::Handle& handle)
+{
+    m_shouldSyncFrame = true;
+    m_webPage->send(Messages::LayerTreeCoordinatorProxy::UpdateImageBacking(imageID, handle));
+}
 
-    if (it->value)
+void LayerTreeCoordinator::removeImageBacking(CoordinatedImageBackingID imageID)
+{
+    if (m_isPurging)
         return;
 
-#if USE(CAIRO)
-    // Complement the referencing in adoptImageBackingStore().
-    cairo_surface_t* cairoSurface = reinterpret_cast<cairo_surface_t*>(key);
-    cairo_surface_destroy(cairoSurface);
-#endif
-
-    m_directlyCompositedImageRefCounts.remove(it);
-    m_releasedDirectlyCompositedImages.append(key);
-    scheduleLayerFlush();
+    ASSERT(m_imageBackings.contains(imageID));
+    m_shouldSyncFrame = true;
+    m_imageBackings.remove(imageID);
+    m_webPage->send(Messages::LayerTreeCoordinatorProxy::RemoveImageBacking(imageID));
 }
 
+void LayerTreeCoordinator::flushPendingImageBackingChanges()
+{
+    ImageBackingMap::iterator end = m_imageBackings.end();
+    for (ImageBackingMap::iterator iter = m_imageBackings.begin(); iter != end; ++iter)
+        iter->value->update();
+}
 
 void LayerTreeCoordinator::notifyAnimationStarted(const WebCore::GraphicsLayer*, double /* time */)
 {
@@ -697,10 +658,7 @@ void LayerTreeCoordinator::purgeBackingStores()
     for (HashSet<WebCore::CoordinatedGraphicsLayer*>::iterator it = m_registeredLayers.begin(); it != end; ++it)
         (*it)->purgeBackingStores();
 
-    purgeReleasedImages();
-
-    ASSERT(!m_directlyCompositedImageRefCounts.size());
-    ASSERT(!m_releasedDirectlyCompositedImages.size());
+    m_imageBackings.clear();
     m_updateAtlases.clear();
 }
 
index 1a9e179..198e3c1 100644 (file)
@@ -23,6 +23,7 @@
 #if USE(COORDINATED_GRAPHICS)
 
 #include "CoordinatedGraphicsLayer.h"
+#include "CoordinatedImageBacking.h"
 #include "LayerTreeContext.h"
 #include "LayerTreeHost.h"
 #include "Timer.h"
@@ -39,6 +40,7 @@ class WebPage;
 
 class LayerTreeCoordinator : public LayerTreeHost, WebCore::GraphicsLayerClient
     , public CoordinatedGraphicsLayerClient
+    , public CoordinatedImageBacking::Coordinator
     , public UpdateAtlasClient
     , public WebCore::GraphicsLayerFactory {
 public:
@@ -67,8 +69,7 @@ public:
     virtual void pauseRendering() { m_isSuspended = true; }
     virtual void resumeRendering() { m_isSuspended = false; scheduleLayerFlush(); }
     virtual void deviceScaleFactorDidChange() { }
-    virtual int64_t adoptImageBackingStore(WebCore::Image*);
-    virtual void releaseImageBackingStore(int64_t);
+    virtual PassRefPtr<CoordinatedImageBacking> createImageBackingIfNeeded(WebCore::Image*) OVERRIDE;
 
     virtual void createTile(WebLayerID, int tileID, const SurfaceUpdateInfo&, const WebCore::IntRect&);
     virtual void updateTile(WebLayerID, int tileID, const SurfaceUpdateInfo&, const WebCore::IntRect&);
@@ -112,6 +113,13 @@ private:
     virtual void notifyFlushRequired(const WebCore::GraphicsLayer*);
     virtual void paintContents(const WebCore::GraphicsLayer*, WebCore::GraphicsContext&, WebCore::GraphicsLayerPaintingPhase, const WebCore::IntRect& clipRect);
 
+    // CoordinatedImageBacking::Coordinator
+    virtual void createImageBacking(CoordinatedImageBackingID) OVERRIDE;
+    virtual void updateImageBacking(CoordinatedImageBackingID, const ShareableSurface::Handle&) OVERRIDE;
+    virtual void removeImageBacking(CoordinatedImageBackingID) OVERRIDE;
+
+    void flushPendingImageBackingChanges();
+
     // GraphicsLayerFactory
     virtual PassOwnPtr<WebCore::GraphicsLayer> createGraphicsLayer(WebCore::GraphicsLayerClient*) OVERRIDE;
 
@@ -125,7 +133,6 @@ private:
     void syncDisplayState();
     void lockAnimations();
     void unlockAnimations();
-    void purgeReleasedImages();
 
     void layerFlushTimerFired(WebCore::Timer<LayerTreeCoordinator>*);
 
@@ -146,8 +153,8 @@ private:
 
     HashSet<WebCore::CoordinatedGraphicsLayer*> m_registeredLayers;
     Vector<WebLayerID> m_detachedLayers;
-    HashMap<int64_t, int> m_directlyCompositedImageRefCounts;
-    Vector<int64_t> m_releasedDirectlyCompositedImages;
+    typedef HashMap<CoordinatedImageBackingID, RefPtr<CoordinatedImageBacking> > ImageBackingMap;
+    ImageBackingMap m_imageBackings;
     Vector<OwnPtr<UpdateAtlas> > m_updateAtlases;
 
     bool m_notifyAfterScheduledLayerFlush;