diff options
7 files changed, 63 insertions, 32 deletions
diff --git a/Source/WebCore/platform/graphics/android/BaseTile.cpp b/Source/WebCore/platform/graphics/android/BaseTile.cpp index 318a969..b38c590 100644 --- a/Source/WebCore/platform/graphics/android/BaseTile.cpp +++ b/Source/WebCore/platform/graphics/android/BaseTile.cpp @@ -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; diff --git a/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp b/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp index 54c96c8..cedad99 100644 --- a/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp +++ b/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp @@ -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) diff --git a/Source/WebCore/platform/graphics/android/BaseTileTexture.h b/Source/WebCore/platform/graphics/android/BaseTileTexture.h index 9c2d8a7..6a9ce43 100644 --- a/Source/WebCore/platform/graphics/android/BaseTileTexture.h +++ b/Source/WebCore/platform/graphics/android/BaseTileTexture.h @@ -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); diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp index 9f266d2..113ccde 100644 --- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp +++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp @@ -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 diff --git a/Source/WebCore/platform/graphics/android/TilesManager.cpp b/Source/WebCore/platform/graphics/android/TilesManager.cpp index f077d48..72c48b2 100644 --- a/Source/WebCore/platform/graphics/android/TilesManager.cpp +++ b/Source/WebCore/platform/graphics/android/TilesManager.cpp @@ -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++; } } diff --git a/Source/WebCore/platform/graphics/android/TransferQueue.cpp b/Source/WebCore/platform/graphics/android/TransferQueue.cpp index 43d73ee..a9d6b9a 100644 --- a/Source/WebCore/platform/graphics/android/TransferQueue.cpp +++ b/Source/WebCore/platform/graphics/android/TransferQueue.cpp @@ -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; } diff --git a/Source/WebCore/platform/graphics/android/TransferQueue.h b/Source/WebCore/platform/graphics/android/TransferQueue.h index 200df25..bddc85d 100644 --- a/Source/WebCore/platform/graphics/android/TransferQueue.h +++ b/Source/WebCore/platform/graphics/android/TransferQueue.h @@ -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); |