summaryrefslogtreecommitdiffstats
path: root/Source/WebCore
diff options
context:
space:
mode:
authorChris Craik <ccraik@google.com>2011-07-01 10:27:35 -0700
committerChris Craik <ccraik@google.com>2011-07-01 10:47:26 -0700
commit72a76070d36a51926c224d230f1503c46f30da60 (patch)
tree08c67ac8a25dc7714de98243709b513d51699e5d /Source/WebCore
parentbeb5d5b7abfe05ecd6dccd281a0885e7a9526286 (diff)
downloadexternal_webkit-72a76070d36a51926c224d230f1503c46f30da60.zip
external_webkit-72a76070d36a51926c224d230f1503c46f30da60.tar.gz
external_webkit-72a76070d36a51926c224d230f1503c46f30da60.tar.bz2
Modified tile reclamation heuristic for multi-webview display
When tiles are reclaimed, they are now taken first from webviews that haven't been drawn in a while. Previously they were taken from any other webview - which may have been one still being displayed if multiple are onscreen. bug:4049143 partially solved (still not enough graphics memory allocated for tiles on tablet devices) Change-Id: Id400ea28e92ba805120c8353881834157fefa483
Diffstat (limited to 'Source/WebCore')
-rw-r--r--Source/WebCore/platform/graphics/android/AndroidAnimation.cpp2
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTile.cpp3
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTile.h6
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTileTexture.cpp5
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTileTexture.h2
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.cpp2
-rw-r--r--Source/WebCore/platform/graphics/android/LayerAndroid.h1
-rw-r--r--Source/WebCore/platform/graphics/android/TextureOwner.h2
-rw-r--r--Source/WebCore/platform/graphics/android/TiledPage.cpp1
-rw-r--r--Source/WebCore/platform/graphics/android/TilesManager.cpp62
-rw-r--r--Source/WebCore/platform/graphics/android/TilesManager.h8
11 files changed, 64 insertions, 30 deletions
diff --git a/Source/WebCore/platform/graphics/android/AndroidAnimation.cpp b/Source/WebCore/platform/graphics/android/AndroidAnimation.cpp
index e7d4780..2939cf0 100644
--- a/Source/WebCore/platform/graphics/android/AndroidAnimation.cpp
+++ b/Source/WebCore/platform/graphics/android/AndroidAnimation.cpp
@@ -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++;
}
diff --git a/Source/WebCore/platform/graphics/android/BaseTile.cpp b/Source/WebCore/platform/graphics/android/BaseTile.cpp
index 2fa2427..70b98b0 100644
--- a/Source/WebCore/platform/graphics/android/BaseTile.cpp
+++ b/Source/WebCore/platform/graphics/android/BaseTile.cpp
@@ -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)
diff --git a/Source/WebCore/platform/graphics/android/BaseTile.h b/Source/WebCore/platform/graphics/android/BaseTile.h
index d336ae2..8a812f8 100644
--- a/Source/WebCore/platform/graphics/android/BaseTile.h
+++ b/Source/WebCore/platform/graphics/android/BaseTile.h
@@ -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;
diff --git a/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp b/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp
index ee8cebf..4d1dec1 100644
--- a/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp
+++ b/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp
@@ -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);
}
diff --git a/Source/WebCore/platform/graphics/android/BaseTileTexture.h b/Source/WebCore/platform/graphics/android/BaseTileTexture.h
index 0a7534a..5496e66 100644
--- a/Source/WebCore/platform/graphics/android/BaseTileTexture.h
+++ b/Source/WebCore/platform/graphics/android/BaseTileTexture.h
@@ -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);
diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
index dda5dee..54176e0 100644
--- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
+++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
@@ -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;
diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.h b/Source/WebCore/platform/graphics/android/LayerAndroid.h
index 9dfe973..bd6c0ef 100644
--- a/Source/WebCore/platform/graphics/android/LayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/LayerAndroid.h
@@ -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; }
diff --git a/Source/WebCore/platform/graphics/android/TextureOwner.h b/Source/WebCore/platform/graphics/android/TextureOwner.h
index bd3a291..15395bb 100644
--- a/Source/WebCore/platform/graphics/android/TextureOwner.h
+++ b/Source/WebCore/platform/graphics/android/TextureOwner.h
@@ -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;
};
}
diff --git a/Source/WebCore/platform/graphics/android/TiledPage.cpp b/Source/WebCore/platform/graphics/android/TiledPage.cpp
index 0e1e947..b532d7a 100644
--- a/Source/WebCore/platform/graphics/android/TiledPage.cpp
+++ b/Source/WebCore/platform/graphics/android/TiledPage.cpp
@@ -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
diff --git a/Source/WebCore/platform/graphics/android/TilesManager.cpp b/Source/WebCore/platform/graphics/android/TilesManager.cpp
index da7e89c..ad4cbd3 100644
--- a/Source/WebCore/platform/graphics/android/TilesManager.cpp
+++ b/Source/WebCore/platform/graphics/android/TilesManager.cpp
@@ -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) {
diff --git a/Source/WebCore/platform/graphics/android/TilesManager.h b/Source/WebCore/platform/graphics/android/TilesManager.h
index 5237c14..2ef9e66 100644
--- a/Source/WebCore/platform/graphics/android/TilesManager.h
+++ b/Source/WebCore/platform/graphics/android/TilesManager.h
@@ -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