summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/graphics
diff options
context:
space:
mode:
authorChris Craik <ccraik@google.com>2011-10-10 15:58:27 -0700
committerChris Craik <ccraik@google.com>2011-10-11 14:46:00 -0700
commit959c08a729d39539327aeb634dbce69524e7b678 (patch)
treee9652bd8a5e0d3d356f37b57c2bd3405d0ef3a98 /Source/WebCore/platform/graphics
parent8242049005e7219ea9846eff8eff3cead8e2461e (diff)
downloadexternal_webkit-959c08a729d39539327aeb634dbce69524e7b678.zip
external_webkit-959c08a729d39539327aeb634dbce69524e7b678.tar.gz
external_webkit-959c08a729d39539327aeb634dbce69524e7b678.tar.bz2
Mark tiles discarded by TransferQueue as dirty
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
Diffstat (limited to 'Source/WebCore/platform/graphics')
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTile.cpp8
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTileTexture.cpp33
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTileTexture.h8
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.cpp3
-rw-r--r--Source/WebCore/platform/graphics/android/TilesManager.cpp4
-rw-r--r--Source/WebCore/platform/graphics/android/TransferQueue.cpp35
-rw-r--r--Source/WebCore/platform/graphics/android/TransferQueue.h4
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);