summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/graphics/android
diff options
context:
space:
mode:
authorTeng-Hui Zhu <ztenghui@google.com>2012-01-25 14:25:28 -0800
committerTeng-Hui Zhu <ztenghui@google.com>2012-01-27 11:47:08 -0800
commite1dfe84b38ed080c7bb7ac00fd9e3c6c590a147d (patch)
treeebe3660dd305146b68dfd65a4c9579c6888ad44d /Source/WebCore/platform/graphics/android
parentce7f402c69fcd625a91611f47cd61d1baa3681b9 (diff)
downloadexternal_webkit-e1dfe84b38ed080c7bb7ac00fd9e3c6c590a147d.zip
external_webkit-e1dfe84b38ed080c7bb7ac00fd9e3c6c590a147d.tar.gz
external_webkit-e1dfe84b38ed080c7bb7ac00fd9e3c6c590a147d.tar.bz2
Clean up tranfer queue before EGL context destroy
This will avoid ANR when texture generation thread is stuck b/c transfer queue is running out of slots, at the same time, EGL context get destroyed and no more draw call coming to free up more slots. Abandon the surface texture will also help to be more memory friendly. Move the highEndGfx check to TilesManager. bug:5639899 Change-Id: I98f0289ae5ca18361f71dec853327223506e3073
Diffstat (limited to 'Source/WebCore/platform/graphics/android')
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTileTexture.cpp3
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.cpp13
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.h2
-rw-r--r--Source/WebCore/platform/graphics/android/TiledPage.cpp2
-rw-r--r--Source/WebCore/platform/graphics/android/TilesManager.cpp11
-rw-r--r--Source/WebCore/platform/graphics/android/TilesManager.h5
-rw-r--r--Source/WebCore/platform/graphics/android/TransferQueue.cpp69
-rw-r--r--Source/WebCore/platform/graphics/android/TransferQueue.h13
8 files changed, 86 insertions, 32 deletions
diff --git a/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp b/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp
index b3a6b84..04d0fc9 100644
--- a/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp
+++ b/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp
@@ -59,9 +59,6 @@ BaseTileTexture::BaseTileTexture(uint32_t w, uint32_t h)
m_size.set(w, h);
m_ownTextureId = 0;
- // Make sure they are created on the UI thread.
- TilesManager::instance()->transferQueue()->initSharedSurfaceTextures(w, h);
-
#ifdef DEBUG_COUNT
ClassTracker::instance()->increment("BaseTileTexture");
#endif
diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
index d8ad1c5..b701169 100644
--- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
+++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
@@ -92,7 +92,6 @@ GLWebViewState::GLWebViewState()
, m_goingLeft(false)
, m_expandedTileBoundsX(0)
, m_expandedTileBoundsY(0)
- , m_highEndGfx(false)
, m_scale(1)
, m_layersRenderingMode(kAllTextures)
{
@@ -276,10 +275,11 @@ void GLWebViewState::setViewport(SkRect& viewport, float scale)
int viewMaxTileX = static_cast<int>(ceilf((viewport.width()-1) * invTileContentWidth)) + 1;
int viewMaxTileY = static_cast<int>(ceilf((viewport.height()-1) * invTileContentHeight)) + 1;
+ TilesManager* manager = TilesManager::instance();
int maxTextureCount = (viewMaxTileX + m_expandedTileBoundsX * 2) *
- (viewMaxTileY + m_expandedTileBoundsY * 2) * (m_highEndGfx ? 4 : 2);
+ (viewMaxTileY + m_expandedTileBoundsY * 2) * (manager->highEndGfx() ? 4 : 2);
- TilesManager::instance()->setMaxTextureCount(maxTextureCount);
+ manager->setMaxTextureCount(maxTextureCount);
m_tiledPageA->updateBaseTileSize();
m_tiledPageB->updateBaseTileSize();
}
@@ -350,11 +350,18 @@ double GLWebViewState::setupDrawing(IntRect& viewRect, SkRect& visibleRect,
int width = viewRect.width();
int height = viewRect.height();
+ // Make sure GL resources are created on the UI thread.
ShaderProgram* shader = TilesManager::instance()->shader();
if (shader->needsInit()) {
XLOG("Reinit shader");
shader->init();
}
+ TransferQueue* transferQueue = TilesManager::instance()->transferQueue();
+ if (transferQueue->needsInit()) {
+ transferQueue->initGLResources(TilesManager::tileWidth(),
+ TilesManager::tileHeight());
+ }
+
shader->setViewport(visibleRect, scale);
shader->setViewRect(viewRect);
shader->setWebViewRect(webViewRect);
diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.h b/Source/WebCore/platform/graphics/android/GLWebViewState.h
index d195597..169e276 100644
--- a/Source/WebCore/platform/graphics/android/GLWebViewState.h
+++ b/Source/WebCore/platform/graphics/android/GLWebViewState.h
@@ -234,7 +234,6 @@ public:
int expandedTileBoundsX() { return m_expandedTileBoundsX; }
int expandedTileBoundsY() { return m_expandedTileBoundsY; }
- void setHighEndGfx(bool highEnd) { m_highEndGfx = highEnd; }
float scale() { return m_scale; }
@@ -289,7 +288,6 @@ private:
int m_expandedTileBoundsX;
int m_expandedTileBoundsY;
- bool m_highEndGfx;
float m_scale;
diff --git a/Source/WebCore/platform/graphics/android/TiledPage.cpp b/Source/WebCore/platform/graphics/android/TiledPage.cpp
index 136b5a7..8c43fc4 100644
--- a/Source/WebCore/platform/graphics/android/TiledPage.cpp
+++ b/Source/WebCore/platform/graphics/android/TiledPage.cpp
@@ -99,7 +99,7 @@ TiledPage::~TiledPage()
tilesManager->removeOperationsForPage(this);
// Discard the transfer queue after the removal operation to make sure
// no tiles for this page will be left in the transfer queue.
- tilesManager->transferQueue()->discardQueue();
+ tilesManager->transferQueue()->setPendingDiscardWithLock();
delete[] m_baseTiles;
#ifdef DEBUG_COUNT
ClassTracker::instance()->decrement("TiledPage");
diff --git a/Source/WebCore/platform/graphics/android/TilesManager.cpp b/Source/WebCore/platform/graphics/android/TilesManager.cpp
index cbbbe5c..082f0bc 100644
--- a/Source/WebCore/platform/graphics/android/TilesManager.cpp
+++ b/Source/WebCore/platform/graphics/android/TilesManager.cpp
@@ -96,6 +96,7 @@ int TilesManager::getMaxTextureAllocation()
TilesManager::TilesManager()
: m_layerTexturesRemain(true)
+ , m_highEndGfx(false)
, m_maxTextureCount(0)
, m_maxLayerTextureCount(0)
, m_generatorReady(false)
@@ -356,6 +357,16 @@ BaseTileTexture* TilesManager::getAvailableTexture(BaseTile* owner)
return 0;
}
+void TilesManager::setHighEndGfx(bool highEnd)
+{
+ m_highEndGfx = highEnd;
+}
+
+bool TilesManager::highEndGfx()
+{
+ return m_highEndGfx;
+}
+
int TilesManager::maxTextureCount()
{
android::Mutex::Autolock lock(m_texturesLock);
diff --git a/Source/WebCore/platform/graphics/android/TilesManager.h b/Source/WebCore/platform/graphics/android/TilesManager.h
index dd01fc5..855994d 100644
--- a/Source/WebCore/platform/graphics/android/TilesManager.h
+++ b/Source/WebCore/platform/graphics/android/TilesManager.h
@@ -106,6 +106,10 @@ public:
void resetTextureUsage(TiledPage* page);
+ // m_highEndGfx is written/read only on UI thread, no need for a lock.
+ void setHighEndGfx(bool highEnd);
+ bool highEndGfx();
+
int maxTextureCount();
int maxLayerTextureCount();
void setMaxTextureCount(int max);
@@ -226,6 +230,7 @@ private:
Vector<PaintedSurface*> m_paintedSurfaces;
+ bool m_highEndGfx;
int m_maxTextureCount;
int m_maxLayerTextureCount;
diff --git a/Source/WebCore/platform/graphics/android/TransferQueue.cpp b/Source/WebCore/platform/graphics/android/TransferQueue.cpp
index 5d47629..56d79a1 100644
--- a/Source/WebCore/platform/graphics/android/TransferQueue.cpp
+++ b/Source/WebCore/platform/graphics/android/TransferQueue.cpp
@@ -77,16 +77,32 @@ TransferQueue::TransferQueue()
TransferQueue::~TransferQueue()
{
- glDeleteFramebuffers(1, &m_fboID);
- m_fboID = 0;
- glDeleteTextures(1, &m_sharedSurfaceTextureId);
- m_sharedSurfaceTextureId = 0;
-
+ android::Mutex::Autolock lock(m_transferQueueItemLocks);
+ cleanupGLResources();
delete[] m_transferQueue;
}
-void TransferQueue::initSharedSurfaceTextures(int width, int height)
+// This should be called within the m_transferQueueItemLocks.
+// Now only called by emptyQueue() and destructor.
+void TransferQueue::cleanupGLResources()
{
+ if (m_sharedSurfaceTexture.get()) {
+ m_sharedSurfaceTexture->abandon();
+ m_sharedSurfaceTexture.clear();
+ }
+ if (m_fboID) {
+ glDeleteFramebuffers(1, &m_fboID);
+ m_fboID = 0;
+ }
+ if (m_sharedSurfaceTextureId) {
+ glDeleteTextures(1, &m_sharedSurfaceTextureId);
+ m_sharedSurfaceTextureId = 0;
+ }
+}
+
+void TransferQueue::initGLResources(int width, int height)
+{
+ android::Mutex::Autolock lock(m_transferQueueItemLocks);
if (!m_sharedSurfaceTextureId) {
glGenTextures(1, &m_sharedSurfaceTextureId);
m_sharedSurfaceTexture =
@@ -260,11 +276,27 @@ void TransferQueue::setHasGLContext(bool hasContext)
m_hasGLContext = hasContext;
}
-// Only called when WebView is destroyed or switching the uploadType.
-void TransferQueue::discardQueue()
+void TransferQueue::setPendingDiscardWithLock()
+{
+ android::Mutex::Autolock lock(m_transferQueueItemLocks);
+ setPendingDiscard();
+}
+
+void TransferQueue::emptyQueue()
{
android::Mutex::Autolock lock(m_transferQueueItemLocks);
+ setPendingDiscard();
+ cleanupPendingDiscard();
+ cleanupGLResources();
+}
+// Set all the content in the queue to pendingDiscard, after this, there will
+// be nothing added to the queue, and this can be called in any thread.
+// However, in order to discard the content in the Surface Texture using
+// updateTexImage, cleanupPendingDiscard need to be called on the UI thread.
+// Must be called within a m_transferQueueItemLocks.
+void TransferQueue::setPendingDiscard()
+{
for (int i = 0 ; i < ST_BUFFER_NUMBER; i++)
if (m_transferQueue[i].status == pendingBlit)
m_transferQueue[i].status = pendingDiscard;
@@ -306,7 +338,7 @@ void TransferQueue::updateDirtyBaseTiles()
{
android::Mutex::Autolock lock(m_transferQueueItemLocks);
- cleanupTransportQueue();
+ cleanupPendingDiscard();
if (!getHasGLContext())
setHasGLContext(true);
@@ -402,10 +434,13 @@ void TransferQueue::updateQueueWithBitmap(const TileRenderInfo* renderInfo,
bool TransferQueue::tryUpdateQueueWithBitmap(const TileRenderInfo* renderInfo,
int x, int y, const SkBitmap& bitmap)
{
- m_transferQueueItemLocks.lock();
+ // This lock need to cover the full update since it is possible that queue
+ // will be cleaned up in the middle of this update without the lock.
+ // The Surface Texture will not block us since the readyForUpdate will check
+ // availability of the slots in the queue first.
+ android::Mutex::Autolock lock(m_transferQueueItemLocks);
bool ready = readyForUpdate();
TextureUploadType currentUploadType = m_currentUploadType;
- m_transferQueueItemLocks.unlock();
if (!ready) {
XLOG("Quit bitmap update: not ready! for tile x y %d %d",
renderInfo->x, renderInfo->y);
@@ -449,11 +484,9 @@ bool TransferQueue::tryUpdateQueueWithBitmap(const TileRenderInfo* renderInfo,
ANativeWindow_unlockAndPost(m_ANW.get());
}
- m_transferQueueItemLocks.lock();
// b) After update the Surface Texture, now udpate the transfer queue info.
addItemInTransferQueue(renderInfo, currentUploadType, &bitmap);
- m_transferQueueItemLocks.unlock();
XLOG("Bitmap updated x, y %d %d, baseTile %p",
renderInfo->x, renderInfo->y, renderInfo->baseTile);
return true;
@@ -524,19 +557,19 @@ void TransferQueue::addItemInTransferQueue(const TileRenderInfo* renderInfo,
void TransferQueue::setTextureUploadType(TextureUploadType type)
{
+ android::Mutex::Autolock lock(m_transferQueueItemLocks);
if (m_currentUploadType == type)
return;
- discardQueue();
+ setPendingDiscard();
- android::Mutex::Autolock lock(m_transferQueueItemLocks);
m_currentUploadType = type;
XLOGC("Now we set the upload to %s", m_currentUploadType == GpuUpload ? "GpuUpload" : "CpuUpload");
}
-// Note: this need to be called within th lock.
-// Only called by updateDirtyBaseTiles() for now
-void TransferQueue::cleanupTransportQueue()
+// Note: this need to be called within the lock and on the UI thread.
+// Only called by updateDirtyBaseTiles() and emptyQueue() for now
+void TransferQueue::cleanupPendingDiscard()
{
int index = getNextTransferQueueIndex();
diff --git a/Source/WebCore/platform/graphics/android/TransferQueue.h b/Source/WebCore/platform/graphics/android/TransferQueue.h
index 629935f..a18d448 100644
--- a/Source/WebCore/platform/graphics/android/TransferQueue.h
+++ b/Source/WebCore/platform/graphics/android/TransferQueue.h
@@ -113,17 +113,15 @@ public:
// This will be called by the browser through nativeSetProperty
void setTextureUploadType(TextureUploadType type);
-
+ void cleanupGLResources();
void updateDirtyBaseTiles();
- void initSharedSurfaceTextures(int width, int height);
+ void initGLResources(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);
- void discardQueue();
-
void addItemInTransferQueue(const TileRenderInfo* info,
TextureUploadType type,
const SkBitmap* bitmap);
@@ -138,6 +136,10 @@ public:
void addItemInPureColorQueue(const TileRenderInfo* renderInfo, Color color);
+ void setPendingDiscardWithLock();
+ void emptyQueue();
+
+ bool needsInit() { return !m_sharedSurfaceTextureId; }
// This queue can be accessed from UI and TexGen thread, therefore, we need
// a lock to protect its access
TileTransferData* m_transferQueue;
@@ -164,9 +166,10 @@ private:
// Check the current transfer queue item is obsolete or not.
bool checkObsolete(const TileTransferData* data);
+ void setPendingDiscard();
// Before each draw call and the blit operation, clean up all the
// pendingDiscard items.
- void cleanupTransportQueue();
+ void cleanupPendingDiscard();
void blitTileFromQueue(GLuint fboID, BaseTileTexture* destTex,
GLuint srcTexId, GLenum srcTexTarget,