summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--Source/WebKit/android/nav/WebView.cpp11
9 files changed, 96 insertions, 33 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,
diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp
index 78881a9..6c49bb7 100644
--- a/Source/WebKit/android/nav/WebView.cpp
+++ b/Source/WebKit/android/nav/WebView.cpp
@@ -450,8 +450,9 @@ bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect,
return false;
if (!m_glWebViewState) {
+ TilesManager::instance()->setHighEndGfx(m_isHighEndGfx);
+
m_glWebViewState = new GLWebViewState();
- m_glWebViewState->setHighEndGfx(m_isHighEndGfx);
m_glWebViewState->glExtras()->setCursorRingExtra(&m_ring);
m_glWebViewState->glExtras()->setFindOnPageExtra(&m_findOnPage);
if (m_baseLayer->content()) {
@@ -2640,6 +2641,14 @@ static jstring nativeGetProperty(JNIEnv *env, jobject obj, jstring jkey)
static void nativeOnTrimMemory(JNIEnv *env, jobject obj, jint level)
{
if (TilesManager::hardwareAccelerationEnabled()) {
+ // When we got TRIM_MEMORY_MODERATE or TRIM_MEMORY_COMPLETE, we should
+ // make sure the transfer queue is empty and then abandon the Surface
+ // Texture to avoid ANR b/c framework may destroy the EGL context.
+ // Refer to WindowManagerImpl.java for conditions we followed.
+ if (level >= TRIM_MEMORY_MODERATE
+ && !TilesManager::instance()->highEndGfx())
+ TilesManager::instance()->transferQueue()->emptyQueue();
+
bool freeAllTextures = (level > TRIM_MEMORY_UI_HIDDEN), glTextures = true;
TilesManager::instance()->discardTextures(freeAllTextures, glTextures);
}