OSDN Git Service

Deallocate graphics memory with onTrimMemory signals
authorChris Craik <ccraik@google.com>
Thu, 8 Sep 2011 03:04:24 +0000 (20:04 -0700)
committerChris Craik <ccraik@google.com>
Thu, 8 Sep 2011 18:53:34 +0000 (11:53 -0700)
bug:5269460
Deallocate the graphics memory backing a BaseTileTexture on onTrimMemory
signals, and accordingly allocate it lazily, as needed.

Change-Id: I52039723f47e6470e4fe8dd987d384017005390f

Source/WebCore/platform/graphics/android/BaseTileTexture.cpp
Source/WebCore/platform/graphics/android/BaseTileTexture.h
Source/WebCore/platform/graphics/android/TilesManager.cpp
Source/WebCore/platform/graphics/android/TilesManager.h
Source/WebCore/platform/graphics/android/TransferQueue.cpp
Source/WebKit/android/nav/WebView.cpp

index 34de9e7..8cc67b9 100644 (file)
@@ -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()) &&
index 9c94a53..6fbc216 100644 (file)
@@ -128,7 +128,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);
 
index 2c263e3..769d9e3 100644 (file)
@@ -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
index 513494c..3298c94 100644 (file)
@@ -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;
index b73f388..488c601 100644 (file)
@@ -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,
index ebbbc1a..a528e9a 100644 (file)
@@ -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)