OSDN Git Service

Return the tile generation thread to default priority.
[android-x86/external-webkit.git] / Source / WebCore / platform / graphics / android / TilesManager.cpp
index cf66de5..62324d7 100644 (file)
@@ -69,7 +69,7 @@
 // number to cap the layer tile texturs, it worked on both phones and tablets.
 // TODO: after merge the pool of base tiles and layer tiles, we should revisit
 // the logic of allocation management.
-#define MAX_TEXTURE_ALLOCATION ((6+TILE_PREFETCH_DISTANCE*2)*(5+TILE_PREFETCH_DISTANCE*2)*2)
+#define MAX_TEXTURE_ALLOCATION ((6+TILE_PREFETCH_DISTANCE*2)*(5+TILE_PREFETCH_DISTANCE*2)*4)
 #define TILE_WIDTH 256
 #define TILE_HEIGHT 256
 #define LAYER_TILE_WIDTH 256
@@ -77,6 +77,8 @@
 
 #define BYTES_PER_PIXEL 4 // 8888 config
 
+#define LAYER_TEXTURES_DESTROY_TIMEOUT 60 // If we do not need layers for 60 seconds, free the textures
+
 namespace WebCore {
 
 GLint TilesManager::getMaxTextureSize()
@@ -93,13 +95,17 @@ int TilesManager::getMaxTextureAllocation()
 }
 
 TilesManager::TilesManager()
-    : m_layersMemoryUsage(0)
+    : m_layerTexturesRemain(true)
     , m_maxTextureCount(0)
+    , m_maxLayerTextureCount(0)
     , m_generatorReady(false)
     , m_showVisualIndicator(false)
     , m_invertedScreen(false)
     , m_invertedScreenSwitch(false)
+    , m_useMinimalMemory(true)
     , m_drawGLCount(1)
+    , m_lastTimeLayersUsed(0)
+    , m_hasLayerTextures(false)
 {
     XLOG("TilesManager ctor");
     m_textures.reserveCapacity(MAX_TEXTURE_ALLOCATION);
@@ -127,9 +133,9 @@ void TilesManager::allocateTiles()
         nbTexturesAllocated++;
     }
 
-    int nbLayersTexturesToAllocate = m_maxTextureCount - m_tilesTextures.size();
+    int nbLayersTexturesToAllocate = m_maxLayerTextureCount - m_tilesTextures.size();
     XLOG("%d layers tiles to allocate (%d textures planned)",
-         nbLayersTexturesToAllocate, m_maxTextureCount);
+         nbLayersTexturesToAllocate, m_maxLayerTextureCount);
     int nbLayersTexturesAllocated = 0;
     for (int i = 0; i < nbLayersTexturesToAllocate; i++) {
         BaseTileTexture* texture = new BaseTileTexture(
@@ -152,7 +158,6 @@ void TilesManager::allocateTiles()
 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) {
@@ -164,19 +169,19 @@ void TilesManager::deallocateTextures(bool allTextures)
                 sparedDrawCount = std::max(sparedDrawCount, owner->drawCount());
         }
     }
+    deallocateTexturesVector(sparedDrawCount, m_textures);
+    deallocateTexturesVector(sparedDrawCount, m_tilesTextures);
+}
 
+void TilesManager::deallocateTexturesVector(unsigned long long sparedDrawCount,
+                                            WTF::Vector<BaseTileTexture*>& textures)
+{
+    const unsigned int max = textures.size();
     int dealloc = 0;
     for (unsigned int i = 0; i < max; i++) {
-        TextureOwner* owner = m_textures[i]->owner();
+        TextureOwner* owner = 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();
+            textures[i]->discardGLTexture();
             dealloc++;
         }
     }
@@ -184,6 +189,23 @@ void TilesManager::deallocateTextures(bool allTextures)
          dealloc, max, maxLayer);
 }
 
+void TilesManager::gatherTexturesNumbers(int* nbTextures, int* nbAllocatedTextures,
+                                        int* nbLayerTextures, int* nbAllocatedLayerTextures)
+{
+    *nbTextures = m_textures.size();
+    for (unsigned int i = 0; i < m_textures.size(); i++) {
+        BaseTileTexture* texture = m_textures[i];
+        if (texture->m_ownTextureId)
+            *nbAllocatedTextures += 1;
+    }
+    *nbLayerTextures = m_tilesTextures.size();
+    for (unsigned int i = 0; i < m_tilesTextures.size(); i++) {
+        BaseTileTexture* texture = m_tilesTextures[i];
+        if (texture->m_ownTextureId)
+            *nbAllocatedLayerTextures += 1;
+    }
+}
+
 void TilesManager::printTextures()
 {
 #ifdef DEBUG
@@ -207,21 +229,6 @@ void TilesManager::printTextures()
 #endif // DEBUG
 }
 
-void TilesManager::swapLayersTextures(LayerAndroid* oldTree, LayerAndroid* newTree)
-{
-    if (oldTree)
-        oldTree->assignTextureTo(newTree);
-
-    if (newTree)
-        newTree->createTexture();
-
-    GLWebViewState* oldState = 0;
-    if (oldTree && !newTree)
-        oldState = oldTree->state();
-
-    paintedSurfacesCleanup(oldState);
-}
-
 void TilesManager::addPaintedSurface(PaintedSurface* surface)
 {
     m_paintedSurfaces.append(surface);
@@ -237,6 +244,7 @@ void TilesManager::gatherLayerTextures()
 {
     android::Mutex::Autolock lock(m_texturesLock);
     m_availableTilesTextures = m_tilesTextures;
+    m_layerTexturesRemain = true;
 }
 
 BaseTileTexture* TilesManager::getAvailableTexture(BaseTile* owner)
@@ -276,7 +284,7 @@ BaseTileTexture* TilesManager::getAvailableTexture(BaseTile* owner)
     const unsigned int max = availableTexturePool->size();
     for (unsigned int i = 0; i < max; i++) {
         BaseTileTexture* texture = (*availableTexturePool)[i];
-        TextureOwner* currentOwner = texture->owner();
+        BaseTile* currentOwner = static_cast<BaseTile*>(texture->owner());
 
         if (texture->busy()) {
             // don't bother, since the acquire() will likely fail
@@ -295,7 +303,7 @@ BaseTileTexture* TilesManager::getAvailableTexture(BaseTile* owner)
             continue;
         }
 
-        if (currentOwner->page() == owner->page() && texture->scale() != owner->scale()) {
+        if (currentOwner->painter() == owner->painter() && texture->scale() != owner->scale()) {
             // if we render the back page with one scale, then another while
             // still zooming, we recycle the tiles with the old scale instead of
             // taking ones from the front page
@@ -326,6 +334,13 @@ BaseTileTexture* TilesManager::getAvailableTexture(BaseTile* owner)
             availableTexturePool->remove(availableTexturePool->find(farthestTexture));
             return farthestTexture;
         }
+    } else {
+        if (owner->isLayerTile()) {
+            // couldn't find a tile for a layer, layers shouldn't request redraw
+            // TODO: once we do layer prefetching, don't set this for those
+            // tiles
+            m_layerTexturesRemain = false;
+        }
     }
 
     XLOG("Couldn't find an available texture for %s tile %x (%d, %d) out of %d available",
@@ -343,6 +358,12 @@ int TilesManager::maxTextureCount()
     return m_maxTextureCount;
 }
 
+int TilesManager::maxLayerTextureCount()
+{
+    android::Mutex::Autolock lock(m_texturesLock);
+    return m_maxLayerTextureCount;
+}
+
 void TilesManager::setMaxTextureCount(int max)
 {
     XLOG("setMaxTextureCount: %d (current: %d, total:%d)",
@@ -361,6 +382,36 @@ void TilesManager::setMaxTextureCount(int max)
     allocateTiles();
 }
 
+void TilesManager::setMaxLayerTextureCount(int max)
+{
+    XLOG("setMaxLayerTextureCount: %d (current: %d, total:%d)",
+         max, m_maxLayerTextureCount, MAX_TEXTURE_ALLOCATION);
+    if (!max && m_hasLayerTextures) {
+        double secondsSinceLayersUsed = WTF::currentTime() - m_lastTimeLayersUsed;
+        if (secondsSinceLayersUsed > LAYER_TEXTURES_DESTROY_TIMEOUT) {
+            unsigned long long sparedDrawCount = ~0; // by default, spare no textures
+            deallocateTexturesVector(sparedDrawCount, m_tilesTextures);
+            m_hasLayerTextures = false;
+        }
+        return;
+    }
+    m_lastTimeLayersUsed = WTF::currentTime();
+    if (m_maxLayerTextureCount == MAX_TEXTURE_ALLOCATION ||
+         max <= m_maxLayerTextureCount)
+        return;
+
+    android::Mutex::Autolock lock(m_texturesLock);
+
+    if (max < MAX_TEXTURE_ALLOCATION)
+        m_maxLayerTextureCount = max;
+    else
+        m_maxLayerTextureCount = MAX_TEXTURE_ALLOCATION;
+
+    allocateTiles();
+    m_hasLayerTextures = true;
+}
+
+
 float TilesManager::tileWidth()
 {
     return TILE_WIDTH;
@@ -403,13 +454,24 @@ void TilesManager::paintedSurfacesCleanup(GLWebViewState* state)
     WTF::Vector<PaintedSurface*> collect;
     for (unsigned int i = 0; i < m_paintedSurfaces.size(); i++) {
         PaintedSurface* surface = m_paintedSurfaces[i];
-        if (!surface->layer() || (state && surface->layer()->state() == state))
+
+        Layer* drawing = surface->drawingLayer();
+        Layer* painting = surface->paintingLayer();
+
+        XLOG("considering PS %p, drawing %p, painting %p", surface, drawing, painting);
+
+        bool drawingMatchesState = state && drawing && (drawing->state() == state);
+        bool paintingMatchesState = state && painting && (painting->state() == state);
+
+        if ((!painting && !drawing) || drawingMatchesState || paintingMatchesState) {
+            XLOG("trying to remove PS %p, painting %p, drawing %p, DMS %d, PMS %d",
+                 surface, painting, drawing, drawingMatchesState, paintingMatchesState);
             collect.append(surface);
+        }
     }
     for (unsigned int i = 0; i < collect.size(); i++) {
         PaintedSurface* surface = collect[i];
         m_paintedSurfaces.remove(m_paintedSurfaces.find(surface));
-        surface->removeLayer();
         SkSafeUnref(surface);
     }
 }
@@ -421,52 +483,6 @@ void TilesManager::unregisterGLWebViewState(GLWebViewState* state)
     transferQueue()->discardQueue();
 }
 
-void TilesManager::addImage(SkBitmapRef* imgRef)
-{
-    if (!imgRef)
-        return;
-
-    android::Mutex::Autolock lock(m_imagesLock);
-    if (!m_images.contains(imgRef))
-        m_images.set(imgRef, new ImageTexture(imgRef));
-}
-
-void TilesManager::removeImage(SkBitmapRef* imgRef)
-{
-    android::Mutex::Autolock lock(m_imagesLock);
-    if (!m_images.contains(imgRef))
-        return;
-
-    ImageTexture* image = m_images.get(imgRef);
-    image->release();
-
-    if (!image->refCount()) {
-        m_images.remove(imgRef);
-        delete image;
-    }
-}
-
-void TilesManager::showImages()
-{
-    XLOGC("We have %d images", m_images.size());
-    HashMap<SkBitmapRef*, ImageTexture*>::iterator end = m_images.end();
-    int i = 0;
-    for (HashMap<SkBitmapRef*, ImageTexture*>::iterator it = m_images.begin(); it != end; ++it) {
-        XLOGC("Image %x (%d/%d) has %d references", it->first, i,
-              m_images.size(), it->second->refCount());
-        i++;
-    }
-}
-
-ImageTexture* TilesManager::getTextureForImage(SkBitmapRef* img)
-{
-    android::Mutex::Autolock lock(m_imagesLock);
-    ImageTexture* image = m_images.get(img);
-    if (image)
-        image->retain();
-    return image;
-}
-
 TilesManager* TilesManager::instance()
 {
     if (!gInstance) {