OSDN Git Service

Merge "Modified tile reclamation heuristic for multi-webview display"
authorChris Craik <ccraik@google.com>
Fri, 1 Jul 2011 17:52:57 +0000 (10:52 -0700)
committerAndroid (Google) Code Review <android-gerrit@google.com>
Fri, 1 Jul 2011 17:52:57 +0000 (10:52 -0700)
Source/WebCore/platform/graphics/android/AndroidAnimation.cpp
Source/WebCore/platform/graphics/android/BaseTile.cpp
Source/WebCore/platform/graphics/android/BaseTile.h
Source/WebCore/platform/graphics/android/BaseTileTexture.cpp
Source/WebCore/platform/graphics/android/BaseTileTexture.h
Source/WebCore/platform/graphics/android/GLWebViewState.cpp
Source/WebCore/platform/graphics/android/LayerAndroid.h
Source/WebCore/platform/graphics/android/TextureOwner.h
Source/WebCore/platform/graphics/android/TiledPage.cpp
Source/WebCore/platform/graphics/android/TilesManager.cpp
Source/WebCore/platform/graphics/android/TilesManager.h

index e7d4780..2939cf0 100644 (file)
@@ -83,10 +83,10 @@ AndroidAnimation::AndroidAnimation(AndroidAnimation* anim)
     , m_iterationCount(anim->m_iterationCount)
     , m_direction(anim->m_direction)
     , m_timingFunction(anim->m_timingFunction)
+    , m_name(anim->name())
     , m_type(anim->m_type)
     , m_operations(anim->m_operations)
     , m_originalLayer(0)
-    , m_name(anim->name())
 {
     gDebugAndroidAnimationInstances++;
 }
index 2fa2427..70b98b0 100644 (file)
@@ -54,7 +54,8 @@
 namespace WebCore {
 
 BaseTile::BaseTile()
-    : m_page(0)
+    : m_glWebViewState(0)
+    , m_page(0)
     , m_x(-1)
     , m_y(-1)
     , m_texture(0)
index d336ae2..8a812f8 100644 (file)
@@ -40,6 +40,7 @@ namespace WebCore {
 class TextureInfo;
 class TiledPage;
 class BaseTileTexture;
+class GLWebViewState;
 
 /**
  * An individual tile that is used to construct part of a webpage's BaseLayer of
@@ -94,11 +95,16 @@ public:
     unsigned int lastPaintedPicture() const { return m_lastPaintedPicture; }
     BaseTileTexture* texture() { return m_texture; }
 
+    void setGLWebViewState(GLWebViewState* state) { m_glWebViewState = state; }
+
     // TextureOwner implementation
     virtual bool removeTexture(BaseTileTexture* texture);
     virtual TiledPage* page() { return m_page; }
+    virtual GLWebViewState* state() { return m_glWebViewState; }
 
 private:
+    GLWebViewState* m_glWebViewState;
+
     // these variables are only set when the object is constructed
     TiledPage* m_page;
     int m_x;
index ee8cebf..4d1dec1 100644 (file)
@@ -147,13 +147,12 @@ bool BaseTileTexture::acquire(TextureOwner* owner, bool force)
     return setOwner(owner, force);
 }
 
-bool BaseTileTexture::tryAcquire(TextureOwner* owner, TiledPage* currentPage, TiledPage* nextPage)
+bool BaseTileTexture::tryAcquire(TextureOwner* owner)
 {
     m_busyLock.lock();
     if (!m_busy
         && m_owner
-        && m_owner->page() != currentPage
-        && m_owner->page() != nextPage) {
+        && m_owner->state() != owner->state()) {
         m_busyLock.unlock();
         return this->acquire(owner);
     }
index 0a7534a..5496e66 100644 (file)
@@ -86,7 +86,7 @@ public:
     // returns false if ownership cannot be transferred because the tile is busy
     bool acquire(TextureOwner* owner, bool force = false);
     bool release(TextureOwner* owner);
-    bool tryAcquire(TextureOwner* owner, TiledPage* currentPage, TiledPage* nextPage);
+    bool tryAcquire(TextureOwner* owner);
 
     // set the texture owner if not busy. Return false if busy, true otherwise.
     bool setOwner(TextureOwner* owner, bool force = false);
index dda5dee..54176e0 100644 (file)
@@ -116,6 +116,7 @@ GLWebViewState::~GLWebViewState()
 #ifdef DEBUG_COUNT
     ClassTracker::instance()->decrement("GLWebViewState");
 #endif
+    TilesManager::instance()->unregisterGLWebViewState(this);
 }
 
 void GLWebViewState::setBaseLayer(BaseLayerAndroid* layer, const SkRegion& inval,
@@ -497,6 +498,7 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
                             IntRect& clip, float scale, SkColor color)
 {
     glFinish();
+    TilesManager::instance()->registerGLWebViewState(this);
 
     m_baseLayerLock.lock();
     BaseLayerAndroid* baseLayer = m_currentBaseLayer;
index 9dfe973..bd6c0ef 100644 (file)
@@ -102,6 +102,7 @@ public:
 
     LayerTexture* texture() { return m_reservedTexture; }
     virtual TiledPage* page() { return 0; }
+    virtual GLWebViewState* state() { return 0; }
 
     void setBackfaceVisibility(bool value) { m_backfaceVisibility = value; }
     void setTransform(const TransformationMatrix& matrix) { m_transform = matrix; }
index bd3a291..15395bb 100644 (file)
@@ -30,12 +30,14 @@ namespace WebCore {
 
 class TiledPage;
 class BaseTileTexture;
+class GLWebViewState;
 
 class TextureOwner {
 public:
     virtual ~TextureOwner() { }
     virtual bool removeTexture(BaseTileTexture* texture) = 0;
     virtual TiledPage* page() = 0;
+    virtual GLWebViewState* state() = 0;
 };
 
 }
index 0e1e947..b532d7a 100644 (file)
@@ -171,6 +171,7 @@ void TiledPage::prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y
 
         if (currentTile) {
             currentTile->setScale(m_scale);
+            currentTile->setGLWebViewState(m_glWebViewState);
 
             // ensure there is a texture associated with the tile and then check to
             // see if the texture is dirty and in need of repainting
index da7e89c..ad4cbd3 100644 (file)
@@ -93,6 +93,7 @@ TilesManager::TilesManager()
     , m_expandedTileBounds(false)
     , m_generatorReady(false)
     , m_showVisualIndicator(false)
+    , m_drawRegistrationCount(0)
 {
     XLOG("TilesManager ctor");
     m_textures.reserveCapacity(MAX_TEXTURE_ALLOCATION);
@@ -168,47 +169,41 @@ BaseTileTexture* TilesManager::getAvailableTexture(BaseTile* owner)
     }
 
     // The heuristic for selecting a texture is as follows:
-    //  1. return an unused texture if one exists
-    //  2. return the farthest texture from the viewport (from any tiled page)
-    //  3. return any texture not used by the tile's page or the page's sibiling
-    //
-    // The texture level indicates a tiles closeness to the current viewport
+    //  1. If usedLevel == -1, break with that one
+    //  2. Otherwise, select the highest usedLevel available
+    //  3. Break ties with the lowest LRU(RecentLevel) valued GLWebViewState
+
     BaseTileTexture* farthestTexture = 0;
     int farthestTextureLevel = 0;
+    unsigned int lowestDrawCount = ~0; //maximum uint
     const unsigned int max = m_textures.size();
     for (unsigned int i = 0; i < max; i++) {
         BaseTileTexture* texture = m_textures[i];
+
         if (texture->usedLevel() == -1) { // found an unused texture, grab it
             farthestTexture = texture;
             break;
         }
-        if (farthestTextureLevel < texture->usedLevel()) {
-            farthestTextureLevel = texture->usedLevel();
+
+        int textureLevel = texture->usedLevel();
+        unsigned int textureDrawCount = getGLWebViewStateDrawCount(texture->owner()->state());
+
+        // if (higher distance or equal distance but less recently rendered)
+        if (farthestTextureLevel < textureLevel
+            || ((farthestTextureLevel == textureLevel) && (lowestDrawCount > textureDrawCount))) {
             farthestTexture = texture;
+            farthestTextureLevel = textureLevel;
+            lowestDrawCount = textureDrawCount;
         }
     }
+
     if (farthestTexture && farthestTexture->acquire(owner)) {
-        XLOG("farthest texture, getAvailableTexture(%x) => texture %x (level %d)",
-             owner, farthestTexture, farthestTexture->usedLevel());
+        XLOG("farthest texture, getAvailableTexture(%x) => texture %x (level %d, drawCount %d)",
+             owner, farthestTexture, farthestTextureLevel, lowestDrawCount);
         farthestTexture->setUsedLevel(0);
         return farthestTexture;
     }
 
-    // At this point, all textures are used or we failed to aquire the farthest
-    // texture. Now let's just grab a texture not in use by either of the two
-    // tiled pages associated with this view.
-    TiledPage* currentPage = owner->page();
-    TiledPage* nextPage = currentPage->sibling();
-    for (unsigned int i = 0; i < max; i++) {
-        BaseTileTexture* texture = m_textures[i];
-        if (texture->tryAcquire(owner, currentPage, nextPage)) {
-            XLOG("grab a texture that wasn't ours, (%x != %x) at %d => texture %x",
-                 owner->page(), texture->owner()->page(), i, texture);
-            texture->setUsedLevel(0);
-            return texture;
-        }
-    }
-
     XLOG("Couldn't find an available texture for BaseTile %x (%d, %d) !!!",
          owner, owner->x(), owner->y());
 #ifdef DEBUG
@@ -424,6 +419,25 @@ int TilesManager::expandedTileBoundsY() {
     return m_expandedTileBounds ? EXPANDED_TILE_BOUNDS_Y : 0;
 }
 
+void TilesManager::registerGLWebViewState(GLWebViewState* state)
+{
+    m_glWebViewStateMap.set(state, m_drawRegistrationCount);
+    m_drawRegistrationCount++;
+    XLOG("now state %p, total of %d states", state, m_glWebViewStateMap.size());
+}
+
+void TilesManager::unregisterGLWebViewState(GLWebViewState* state)
+{
+    m_glWebViewStateMap.remove(state);
+    XLOG("state %p now removed, total of %d states", state, m_glWebViewStateMap.size());
+}
+
+unsigned int TilesManager::getGLWebViewStateDrawCount(GLWebViewState* state)
+{
+    XLOG("looking up state %p, contains=%s", state, m_glWebViewStateMap.contains(state) ? "TRUE" : "FALSE");
+    return m_glWebViewStateMap.find(state)->second;
+}
+
 TilesManager* TilesManager::instance()
 {
     if (!gInstance) {
index 5237c14..2ef9e66 100644 (file)
@@ -37,6 +37,7 @@
 #include "TiledPage.h"
 #include "VideoLayerManager.h"
 #include <utils/threads.h>
+#include <wtf/HashMap.h>
 
 namespace WebCore {
 
@@ -108,6 +109,8 @@ public:
     static float tileHeight();
     int expandedTileBoundsX();
     int expandedTileBoundsY();
+    void registerGLWebViewState(GLWebViewState* state);
+    void unregisterGLWebViewState(GLWebViewState* state);
 
     void allocateTiles();
 
@@ -156,6 +159,11 @@ private:
 
     ShaderProgram m_shader;
     VideoLayerManager m_videoLayerManager;
+
+    HashMap<GLWebViewState*, unsigned int> m_glWebViewStateMap;
+    unsigned int m_drawRegistrationCount;
+
+    unsigned int getGLWebViewStateDrawCount(GLWebViewState* state);
 };
 
 } // namespace WebCore