summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTileTexture.cpp21
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTileTexture.h4
-rw-r--r--Source/WebCore/platform/graphics/android/TilesManager.cpp35
-rw-r--r--Source/WebCore/platform/graphics/android/TilesManager.h3
-rw-r--r--Source/WebCore/platform/graphics/android/TransferQueue.cpp3
-rw-r--r--Source/WebKit/android/nav/WebView.cpp4
6 files changed, 69 insertions, 1 deletions
diff --git a/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp b/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp
index 34de9e7..8cc67b9 100644
--- a/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp
+++ b/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp
@@ -58,7 +58,7 @@ BaseTileTexture::BaseTileTexture(uint32_t w, uint32_t h)
, m_busy(false)
{
m_size.set(w, h);
- m_ownTextureId = GLUtils::createBaseTileGLTexture(w, h);
+ m_ownTextureId = 0;
// Make sure they are created on the UI thread.
TilesManager::instance()->transferQueue()->initSharedSurfaceTextures(w, h);
@@ -79,6 +79,18 @@ BaseTileTexture::~BaseTileTexture()
#endif
}
+void BaseTileTexture::requireTexture()
+{
+ if (!m_ownTextureId)
+ m_ownTextureId = GLUtils::createBaseTileGLTexture(m_size.width(), m_size.height());
+}
+
+void BaseTileTexture::discardTexture()
+{
+ if (m_ownTextureId)
+ GLUtils::deleteTexture(&m_ownTextureId);
+}
+
void BaseTileTexture::destroyTextures(SharedTexture** textures)
{
int x = 0;
@@ -263,6 +275,13 @@ void BaseTileTexture::setOwnTextureTileInfoFromQueue(const TextureTileInfo* info
bool BaseTileTexture::readyFor(BaseTile* baseTile)
{
+ if (!m_ownTextureId) {
+ // If our backing opengl texture doesn't exist, allocate it and return
+ // false since it won't have useful data
+ requireTexture();
+ return false;
+ }
+
const TextureTileInfo* info = &m_ownTextureTileInfo;
if (info &&
(info->m_x == baseTile->x()) &&
diff --git a/Source/WebCore/platform/graphics/android/BaseTileTexture.h b/Source/WebCore/platform/graphics/android/BaseTileTexture.h
index c11ef95..0f694a5 100644
--- a/Source/WebCore/platform/graphics/android/BaseTileTexture.h
+++ b/Source/WebCore/platform/graphics/android/BaseTileTexture.h
@@ -133,7 +133,11 @@ public:
bool readyFor(BaseTile* baseTile);
float scale();
+ // 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 setOwnTextureTileInfoFromQueue(const TextureTileInfo* info);
diff --git a/Source/WebCore/platform/graphics/android/TilesManager.cpp b/Source/WebCore/platform/graphics/android/TilesManager.cpp
index 2c263e3..769d9e3 100644
--- a/Source/WebCore/platform/graphics/android/TilesManager.cpp
+++ b/Source/WebCore/platform/graphics/android/TilesManager.cpp
@@ -149,6 +149,41 @@ void TilesManager::allocateTiles()
m_tilesTextures.size() * LAYER_TILE_WIDTH * LAYER_TILE_HEIGHT * 4 / 1024 / 1024);
}
+void TilesManager::deallocateTextures(bool allTextures)
+{
+ const unsigned int max = m_textures.size();
+ const unsigned int maxLayer = m_tilesTextures.size();
+
+ unsigned long long sparedDrawCount = ~0; // by default, spare no textures
+ if (!allTextures) {
+ // if we're not deallocating all textures, spare those with max drawcount
+ sparedDrawCount = 0;
+ for (unsigned int i = 0; i < max; i++) {
+ TextureOwner* owner = m_textures[i]->owner();
+ if (owner)
+ sparedDrawCount = std::max(sparedDrawCount, owner->drawCount());
+ }
+ }
+
+ int dealloc = 0;
+ for (unsigned int i = 0; i < max; i++) {
+ TextureOwner* owner = m_textures[i]->owner();
+ if (!owner || owner->drawCount() < sparedDrawCount) {
+ m_textures[i]->discardTexture();
+ dealloc++;
+ }
+ }
+ for (unsigned int i = 0; i < maxLayer; i++) {
+ TextureOwner* owner = m_tilesTextures[i]->owner();
+ if (!owner || owner->drawCount() < sparedDrawCount) {
+ m_tilesTextures[i]->discardTexture();
+ dealloc++;
+ }
+ }
+ XLOG("Deallocated %d gl textures (out of %d base tiles and %d layer tiles)",
+ dealloc, max, maxLayer);
+}
+
void TilesManager::printTextures()
{
#ifdef DEBUG
diff --git a/Source/WebCore/platform/graphics/android/TilesManager.h b/Source/WebCore/platform/graphics/android/TilesManager.h
index 513494c..3298c94 100644
--- a/Source/WebCore/platform/graphics/android/TilesManager.h
+++ b/Source/WebCore/platform/graphics/android/TilesManager.h
@@ -112,6 +112,9 @@ public:
void allocateTiles();
+ // Called when webview is hidden to discard graphics memory
+ void deallocateTextures(bool allTextures);
+
bool getShowVisualIndicator()
{
return m_showVisualIndicator;
diff --git a/Source/WebCore/platform/graphics/android/TransferQueue.cpp b/Source/WebCore/platform/graphics/android/TransferQueue.cpp
index a13474a..50502f6 100644
--- a/Source/WebCore/platform/graphics/android/TransferQueue.cpp
+++ b/Source/WebCore/platform/graphics/android/TransferQueue.cpp
@@ -134,6 +134,9 @@ bool TransferQueue::checkObsolete(int index)
void TransferQueue::blitTileFromQueue(GLuint fboID, BaseTileTexture* destTex, GLuint srcTexId, GLenum srcTexTarget)
{
+ // guarantee that we have a texture to blit into
+ destTex->requireTexture();
+
// Then set up the FBO and copy the SurfTex content in.
glBindFramebuffer(GL_FRAMEBUFFER, fboID);
glFramebufferTexture2D(GL_FRAMEBUFFER,
diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp
index ebbbc1a..a528e9a 100644
--- a/Source/WebKit/android/nav/WebView.cpp
+++ b/Source/WebKit/android/nav/WebView.cpp
@@ -2573,6 +2573,10 @@ static jstring nativeGetProperty(JNIEnv *env, jobject obj, jstring key)
static void nativeOnTrimMemory(JNIEnv *env, jobject obj, jint level)
{
+ if (TilesManager::hardwareAccelerationEnabled()) {
+ bool freeAllTextures = (level > TRIM_MEMORY_UI_HIDDEN);
+ TilesManager::instance()->deallocateTextures(freeAllTextures);
+ }
}
static void nativeDumpDisplayTree(JNIEnv* env, jobject jwebview, jstring jurl)