OSDN Git Service

Mark tiles discarded by TransferQueue as dirty
authorChris Craik <ccraik@google.com>
Mon, 10 Oct 2011 22:58:27 +0000 (15:58 -0700)
committerChris Craik <ccraik@google.com>
Tue, 11 Oct 2011 21:46:00 +0000 (14:46 -0700)
bug:5409902

Tiles were being discarded from the queue (and simply unsuccessfully
added). This caused them to get stuck in the 'ValidatedUntransferred' state.

Now if a tile isn't added successfully, or if it's discarded, it removes its
painting texture and will have to repaint from scratch.

Change-Id: I551e00fb8a6be3b0f3cabeabaa91e8b8b30019d5

Source/WebCore/platform/graphics/android/BaseTile.cpp
Source/WebCore/platform/graphics/android/BaseTileTexture.cpp
Source/WebCore/platform/graphics/android/BaseTileTexture.h
Source/WebCore/platform/graphics/android/GLWebViewState.cpp
Source/WebCore/platform/graphics/android/TilesManager.cpp
Source/WebCore/platform/graphics/android/TransferQueue.cpp
Source/WebCore/platform/graphics/android/TransferQueue.h

index 318a969..b38c590 100644 (file)
@@ -135,6 +135,8 @@ void BaseTile::reserveTexture()
 
     android::AutoMutex lock(m_atomicSync);
     if (texture && m_backTexture != texture) {
+        XLOG("tile %p reserving texture %p, back was %p (front %p)",
+             this, texture, m_backTexture, m_frontTexture);
         m_state = Unpainted;
         m_backTexture = texture;
     }
@@ -148,8 +150,8 @@ void BaseTile::reserveTexture()
 
 bool BaseTile::removeTexture(BaseTileTexture* texture)
 {
-    XLOG("%x removeTexture back %x front %x... page %x",
-         this, m_backTexture, m_frontTexture, m_page);
+    XLOG("%p removeTexture %p, back %p front %p... page %p",
+         this, texture, m_backTexture, m_frontTexture, m_page);
     // We update atomically, so paintBitmap() can see the correct value
     android::AutoMutex lock(m_atomicSync);
     if (m_frontTexture == texture) {
@@ -484,6 +486,8 @@ void BaseTile::paintBitmap()
 
 void BaseTile::discardTextures() {
     android::AutoMutex lock(m_atomicSync);
+    XLOG("%p discarding bt %p, ft %p",
+         this, m_backTexture, m_frontTexture);
     if (m_frontTexture) {
         m_frontTexture->release(this);
         m_frontTexture = 0;
index 54c96c8..cedad99 100644 (file)
@@ -82,22 +82,18 @@ BaseTileTexture::~BaseTileTexture()
 #endif
 }
 
-void BaseTileTexture::requireTexture()
+void BaseTileTexture::requireGLTexture()
 {
     if (!m_ownTextureId)
         m_ownTextureId = GLUtils::createBaseTileGLTexture(m_size.width(), m_size.height());
 }
 
-void BaseTileTexture::discardTexture()
+void BaseTileTexture::discardGLTexture()
 {
     if (m_ownTextureId)
         GLUtils::deleteTexture(&m_ownTextureId);
 
-    if (m_owner) {
-        // clear both Tile->Texture and Texture->Tile links
-        m_owner->removeTexture(this);
-        release(m_owner);
-    }
+    releaseAndRemoveFromTile();
 }
 
 void BaseTileTexture::destroyTextures(SharedTexture** textures)
@@ -185,19 +181,6 @@ bool BaseTileTexture::acquire(TextureOwner* owner, bool force)
     return setOwner(owner, force);
 }
 
-bool BaseTileTexture::tryAcquire(TextureOwner* owner)
-{
-    m_busyLock.lock();
-    if (!m_busy
-        && m_owner
-        && m_owner->state() != owner->state()) {
-        m_busyLock.unlock();
-        return this->acquire(owner);
-    }
-    m_busyLock.unlock();
-    return false;
-}
-
 bool BaseTileTexture::setOwner(TextureOwner* owner, bool force)
 {
     // if the writable texture is busy (i.e. currently being written to) then we
@@ -232,6 +215,7 @@ bool BaseTileTexture::setOwner(TextureOwner* owner, bool force)
 bool BaseTileTexture::release(TextureOwner* owner)
 {
     android::Mutex::Autolock lock(m_busyLock);
+    XLOG("texture %p releasing tile %p, m_owner %p, m_busy %d", this, owner, m_owner, m_busy);
     if (m_owner != owner)
         return false;
 
@@ -244,6 +228,15 @@ bool BaseTileTexture::release(TextureOwner* owner)
     return true;
 }
 
+void BaseTileTexture::releaseAndRemoveFromTile()
+{
+    if (m_owner) {
+        // clear both Tile->Texture and Texture->Tile links
+        m_owner->removeTexture(this);
+        release(m_owner);
+    }
+}
+
 void BaseTileTexture::setTile(TextureInfo* info, int x, int y,
                                           float scale, TilePainter* painter,
                                           unsigned int pictureCount)
index 9c2d8a7..6a9ce43 100644 (file)
@@ -82,7 +82,9 @@ public:
     // returns false if ownership cannot be transferred because the tile is busy
     bool acquire(TextureOwner* owner, bool force = false);
     bool release(TextureOwner* owner);
-    bool tryAcquire(TextureOwner* owner);
+
+    // removes Tile->Texture, and Texture->Tile links to fully discard the texture
+    void releaseAndRemoveFromTile();
 
     // set the texture owner if not busy. Return false if busy, true otherwise.
     bool setOwner(TextureOwner* owner, bool force = false);
@@ -104,8 +106,8 @@ public:
     // OpenGL ID of backing texture, 0 when not allocated
     GLuint m_ownTextureId;
     // these are used for dynamically (de)allocating backing graphics memory
-    void requireTexture();
-    void discardTexture();
+    void requireGLTexture();
+    void discardGLTexture();
 
     void setOwnTextureTileInfoFromQueue(const TextureTileInfo* info);
 
index 9f266d2..113ccde 100644 (file)
@@ -205,7 +205,8 @@ void GLWebViewState::inval(const IntRect& rect)
         m_currentPictureCounter++;
         if (!rect.isEmpty()) {
             // find which tiles fall within the invalRect and mark them as dirty
-            frontPage()->invalidateRect(rect, m_currentPictureCounter);
+            m_tiledPageA->invalidateRect(rect, m_currentPictureCounter);
+            m_tiledPageB->invalidateRect(rect, m_currentPictureCounter);
             if (m_frameworkInval.isEmpty())
                 m_frameworkInval = rect;
             else
index f077d48..72c48b2 100644 (file)
@@ -169,14 +169,14 @@ void TilesManager::deallocateTextures(bool allTextures)
     for (unsigned int i = 0; i < max; i++) {
         TextureOwner* owner = m_textures[i]->owner();
         if (!owner || owner->drawCount() < sparedDrawCount) {
-            m_textures[i]->discardTexture();
+            m_textures[i]->discardGLTexture();
             dealloc++;
         }
     }
     for (unsigned int i = 0; i < maxLayer; i++) {
         TextureOwner* owner = m_tilesTextures[i]->owner();
         if (!owner || owner->drawCount() < sparedDrawCount) {
-            m_tilesTextures[i]->discardTexture();
+            m_tilesTextures[i]->discardGLTexture();
             dealloc++;
         }
     }
index 43d73ee..a9d6b9a 100644 (file)
@@ -308,7 +308,7 @@ void TransferQueue::updateDirtyBaseTiles()
             }
 
             // guarantee that we have a texture to blit into
-            destTexture->requireTexture();
+            destTexture->requireGLTexture();
 
             if (m_transferQueue[index].uploadType == CpuUpload) {
                 // Here we just need to upload the bitmap content to the GL Texture
@@ -357,6 +357,21 @@ void TransferQueue::updateDirtyBaseTiles()
 void TransferQueue::updateQueueWithBitmap(const TileRenderInfo* renderInfo,
                                           int x, int y, const SkBitmap& bitmap)
 {
+    if (!tryUpdateQueueWithBitmap(renderInfo, x, y, bitmap)) {
+        // failed placing bitmap in queue, discard tile's texture so it will be
+        // re-enqueued (and repainted)
+        BaseTile* tile = renderInfo->baseTile;
+        if (tile) {
+            BaseTileTexture* texture = tile->backTexture();
+            if (texture)
+                texture->releaseAndRemoveFromTile();
+        }
+    }
+}
+
+bool TransferQueue::tryUpdateQueueWithBitmap(const TileRenderInfo* renderInfo,
+                                          int x, int y, const SkBitmap& bitmap)
+{
     m_transferQueueItemLocks.lock();
     bool ready = readyForUpdate();
     TextureUploadType currentUploadType = m_currentUploadType;
@@ -364,18 +379,18 @@ void TransferQueue::updateQueueWithBitmap(const TileRenderInfo* renderInfo,
     if (!ready) {
         XLOG("Quit bitmap update: not ready! for tile x y %d %d",
              renderInfo->x, renderInfo->y);
-        return;
+        return false;
     }
     if (currentUploadType == GpuUpload) {
         // a) Dequeue the Surface Texture and write into the buffer
         if (!m_ANW.get()) {
             XLOG("ERROR: ANW is null");
-            return;
+            return false;
         }
 
         ANativeWindow_Buffer buffer;
         if (ANativeWindow_lock(m_ANW.get(), &buffer, 0))
-            return;
+            return false;
 
         uint8_t* img = (uint8_t*)buffer.bits;
         int row, col;
@@ -411,6 +426,7 @@ void TransferQueue::updateQueueWithBitmap(const TileRenderInfo* renderInfo,
     m_transferQueueItemLocks.unlock();
     XLOG("Bitmap updated x, y %d %d, baseTile %p",
          renderInfo->x, renderInfo->y, renderInfo->baseTile);
+    return true;
 }
 
 // Note that there should be lock/unlock around this function call.
@@ -476,6 +492,17 @@ void TransferQueue::cleanupTransportQueue()
             // be called to keep things in sync.
             if (m_transferQueue[index].uploadType == GpuUpload)
                 m_sharedSurfaceTexture->updateTexImage();
+
+            // since tiles in the queue may be from another webview, remove
+            // their textures so that they will be repainted / retransferred
+            BaseTile* tile = m_transferQueue[index].savedBaseTilePtr;
+            if (tile) {
+                BaseTileTexture* texture = tile->backTexture();
+                if (texture)
+                    texture->releaseAndRemoveFromTile();
+            }
+            XLOG("transfer queue discarded tile %p, removed texture", tile);
+
             m_transferQueue[index].savedBaseTilePtr = 0;
             m_transferQueue[index].status = emptyItem;
         }
index 200df25..bddc85d 100644 (file)
@@ -112,6 +112,7 @@ public:
 
     void initSharedSurfaceTextures(int width, int height);
 
+    // insert the bitmap into the queue, mark the tile dirty if failing
     void updateQueueWithBitmap(const TileRenderInfo* renderInfo, int x, int y,
                                const SkBitmap& bitmap);
 
@@ -139,6 +140,9 @@ public:
     EGLSurface m_eglSurface;
 
 private:
+    // return true if successfully inserted into queue
+    bool tryUpdateQueueWithBitmap(const TileRenderInfo* renderInfo, int x, int y,
+                                  const SkBitmap& bitmap);
     bool getHasGLContext();
     void setHasGLContext(bool hasContext);