summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDerek Sollenberger <djsollen@google.com>2010-11-11 06:56:03 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2010-11-11 06:56:03 -0800
commit7021bf0a7e2979e98e815cb40f2408780d773571 (patch)
treecfce1c7000908ab54017ab9800d910d9c0823d24
parent35eccae0b7870c531ab56dfee7002108c95d908c (diff)
parentffc715a2e6382fe9e331557c35fafc426507b8f5 (diff)
downloadexternal_webkit-7021bf0a7e2979e98e815cb40f2408780d773571.zip
external_webkit-7021bf0a7e2979e98e815cb40f2408780d773571.tar.gz
external_webkit-7021bf0a7e2979e98e815cb40f2408780d773571.tar.bz2
Merge "Use a fixed number of BaseTiles per TiledPage."
-rw-r--r--WebCore/platform/graphics/android/BaseTile.cpp16
-rw-r--r--WebCore/platform/graphics/android/BaseTile.h5
-rw-r--r--WebCore/platform/graphics/android/GLWebViewState.cpp8
-rw-r--r--WebCore/platform/graphics/android/TiledPage.cpp140
-rw-r--r--WebCore/platform/graphics/android/TiledPage.h12
-rw-r--r--WebCore/platform/graphics/android/TilesManager.cpp23
-rw-r--r--WebCore/platform/graphics/android/TilesManager.h5
7 files changed, 121 insertions, 88 deletions
diff --git a/WebCore/platform/graphics/android/BaseTile.cpp b/WebCore/platform/graphics/android/BaseTile.cpp
index ff5d9ca..6fd9e89 100644
--- a/WebCore/platform/graphics/android/BaseTile.cpp
+++ b/WebCore/platform/graphics/android/BaseTile.cpp
@@ -66,10 +66,10 @@ int BaseTile::count()
}
#endif
-BaseTile::BaseTile(TiledPage* page, int x, int y)
- : m_page(page)
- , m_x(x)
- , m_y(y)
+BaseTile::BaseTile()
+ : m_page(0)
+ , m_x(-1)
+ , m_y(-1)
, m_texture(0)
, m_scale(1)
, m_dirty(true)
@@ -91,6 +91,14 @@ BaseTile::~BaseTile()
// All the following functions must be called from the main GL thread.
+void BaseTile::setContents(TiledPage* page, int x, int y)
+{
+ android::AutoMutex lock(m_atomicSync);
+ m_page = page;
+ m_x = x;
+ m_y = y;
+}
+
void BaseTile::reserveTexture()
{
BackedDoubleBufferedTexture* texture = TilesManager::instance()->getAvailableTexture(this);
diff --git a/WebCore/platform/graphics/android/BaseTile.h b/WebCore/platform/graphics/android/BaseTile.h
index 8870cbf..8f095e3 100644
--- a/WebCore/platform/graphics/android/BaseTile.h
+++ b/WebCore/platform/graphics/android/BaseTile.h
@@ -64,9 +64,12 @@ public:
#ifdef DEBUG_COUNT
static int count();
#endif
- BaseTile(TiledPage* page, int x, int y);
+ BaseTile();
~BaseTile();
+ void setContents(TiledPage* page, int x, int y);
+ bool isAvailable() const { return !m_texture; }
+
void reserveTexture();
void removeTexture();
void setUsedLevel(int);
diff --git a/WebCore/platform/graphics/android/GLWebViewState.cpp b/WebCore/platform/graphics/android/GLWebViewState.cpp
index 4ad22d8..617690c 100644
--- a/WebCore/platform/graphics/android/GLWebViewState.cpp
+++ b/WebCore/platform/graphics/android/GLWebViewState.cpp
@@ -217,9 +217,9 @@ void GLWebViewState::setViewport(SkRect& viewport, float scale)
return;
m_viewport = viewport;
- float fnbw = m_viewport.width() * scale / TilesManager::instance()->tileWidth();
+ float fnbw = m_viewport.width() * scale / TilesManager::tileWidth();
int nbw = static_cast<int>(ceilf(fnbw));
- float fnbh = m_viewport.height() * scale / TilesManager::instance()->tileHeight();
+ float fnbh = m_viewport.height() * scale / TilesManager::tileHeight();
int nbh = static_cast<int>(ceilf(fnbh));
m_nbTilesWidth = nbw + 1;
m_nbTilesHeight = nbh + 1;
@@ -227,8 +227,8 @@ void GLWebViewState::setViewport(SkRect& viewport, float scale)
m_viewport.fLeft, m_viewport.fTop, m_viewport.fRight, m_viewport.fBottom,
m_viewport.width(), m_viewport.height(), scale,
m_nbTilesWidth, m_nbTilesHeight);
- m_firstTileX = static_cast<int>(m_viewport.fLeft * scale / TilesManager::instance()->tileWidth());
- m_firstTileY = static_cast<int>(m_viewport.fTop * scale / TilesManager::instance()->tileHeight());
+ m_firstTileX = static_cast<int>(m_viewport.fLeft * scale / TilesManager::tileWidth());
+ m_firstTileY = static_cast<int>(m_viewport.fTop * scale / TilesManager::tileHeight());
}
} // namespace WebCore
diff --git a/WebCore/platform/graphics/android/TiledPage.cpp b/WebCore/platform/graphics/android/TiledPage.cpp
index 358c1a8..eb500ac 100644
--- a/WebCore/platform/graphics/android/TiledPage.cpp
+++ b/WebCore/platform/graphics/android/TiledPage.cpp
@@ -67,41 +67,47 @@ TiledPage::TiledPage(int id, GLWebViewState* state)
, m_glWebViewState(state)
, m_latestPictureInval(0)
{
+ // This value must be at least 1 greater than the max number of allowed
+ // textures. This is because prepare() asks for a tile before it reserves
+ // a texture for that tile. If all textures are currently in use by the
+ // page then there will be no available tile and having the extra tile
+ // ensures that this does not happen. After claiming the extra tile the call
+ // to reserveTexture() will cause some other tile in the page to lose it's
+ // texture and become available, thus ensuring that we always have at least
+ // one tile that is available.
+ m_baseTileSize = TilesManager::maxTextureCount() + 1;
+ m_baseTiles = new BaseTile[m_baseTileSize];
+
#ifdef DEBUG_COUNT
gTilePageCount++;
#endif
}
TiledPage::~TiledPage() {
- // Stop any pixmap generation
- if (m_baseTiles.size()) {
- TilesManager::instance()->removeSetsWithPage(this);
- }
- m_glWebViewState = 0;
- // At this point, we can safely deallocate the BaseTiles, as
- // there is no more BaseTile painting or scheduled to be painted
- // by the TextureGenerator, and as we did reset the BaseLayer in GLWebViewState,
- // in WebView's destructor (so no additional painting can be scheduled)
- deleteAllValues(m_baseTiles);
+ // In order to delete the page we must ensure that none of its BaseTiles are
+ // currently painting or scheduled to be painted by the TextureGenerator
+ TilesManager::instance()->removeSetsWithPage(this);
+ delete[] m_baseTiles;
#ifdef DEBUG_COUNT
gTilePageCount--;
#endif
}
-BaseTile* TiledPage::getBaseTile(int x, int y)
+BaseTile* TiledPage::getBaseTile(int x, int y) const
{
- // if (x,y) is (0,0) the HashMap will treat the key as a null value and will
- // not store the tile so we increment the key values by 1
- TileKey key(x+1, y+1);
- return m_baseTiles.get(key);
+ for (int j = 0; j < m_baseTileSize; j++) {
+ BaseTile& tile = m_baseTiles[j];
+ if (tile.x() == x && tile.y() == y && !tile.isAvailable())
+ return &tile;
+ }
+ return 0;
}
void TiledPage::invalidateRect(const IntRect& inval, const unsigned int pictureCount)
{
// Given the current scale level we need to mark the appropriate tiles as dirty
- TilesManager* manager = TilesManager::instance();
- const float invTileContentWidth = m_scale / manager->tileWidth();
- const float invTileContentHeight = m_scale / manager->tileHeight();
+ const float invTileContentWidth = m_scale / TilesManager::tileWidth();
+ const float invTileContentHeight = m_scale / TilesManager::tileHeight();
const int firstDirtyTileX = static_cast<int>(floorf(inval.x() * invTileContentWidth));
const int firstDirtyTileY = static_cast<int>(floorf(inval.y() * invTileContentHeight));
@@ -131,20 +137,31 @@ void TiledPage::prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y
else
x += (tilesInRow - 1) - i;
- TileKey key(x+1, y+1);
- BaseTile* tile = 0;
- if (!m_baseTiles.contains(key)) {
- tile = new BaseTile(this, x, y);
- m_baseTiles.set(key, tile);
+
+ BaseTile* currentTile = 0;
+ BaseTile* availableTile = 0;
+ for (int j = 0; j < m_baseTileSize; j++) {
+ BaseTile& tile = m_baseTiles[j];
+ if (tile.x() == x && tile.y() == y) {
+ currentTile = &tile;
+ break;
+ }
+ if (!availableTile && tile.isAvailable())
+ availableTile = &tile;
+ }
+
+ if (!currentTile) {
+ currentTile = availableTile;
+ currentTile->setContents(this, x, y);
}
- tile = m_baseTiles.get(key);
- tile->setScale(m_scale);
+
+ currentTile->setScale(m_scale);
// ensure there is a texture associated with the tile and then check to
// see if the texture is dirty and in need of repainting
- tile->reserveTexture();
- if(tile->isDirty())
- set->add(tile);
+ currentTile->reserveTexture();
+ if(currentTile->isDirty())
+ set->add(currentTile);
}
}
@@ -156,35 +173,36 @@ void TiledPage::updateTileState(int firstTileX, int firstTileY)
const int nbTilesWidth = m_glWebViewState->nbTilesWidth();
const int nbTilesHeight = m_glWebViewState->nbTilesHeight();
- TileMap::const_iterator end = m_baseTiles.end();
- for (TileMap::const_iterator it = m_baseTiles.begin(); it != end; ++it) {
- BaseTile* tile = it->second;
+ for (int x = 0; x < m_baseTileSize; x++) {
+
+ BaseTile& tile = m_baseTiles[x];
- if(!tile)
+ // if the tile no longer has a texture then proceed to the next tile
+ if (tile.isAvailable())
continue;
// if the tile is in the dirty region then we must invalidate it
- if (m_invalRegion.contains(tile->x(), tile->y()))
- tile->markAsDirty(m_latestPictureInval);
+ if (m_invalRegion.contains(tile.x(), tile.y()))
+ tile.markAsDirty(m_latestPictureInval);
// set the used level of the tile (e.g. distance from the viewport)
int dx = 0;
int dy = 0;
- if (firstTileX > tile->x())
- dx = firstTileX - tile->x();
- else if (firstTileX + (nbTilesWidth - 1) < tile->x())
- dx = tile->x() - firstTileX - (nbTilesWidth - 1);
+ if (firstTileX > tile.x())
+ dx = firstTileX - tile.x();
+ else if (firstTileX + (nbTilesWidth - 1) < tile.x())
+ dx = tile.x() - firstTileX - (nbTilesWidth - 1);
- if (firstTileY > tile->y())
- dy = firstTileY - tile->y();
- else if (firstTileY + (nbTilesHeight - 1) < tile->y())
- dy = tile->y() - firstTileY - (nbTilesHeight - 1);
+ if (firstTileY > tile.y())
+ dy = firstTileY - tile.y();
+ else if (firstTileY + (nbTilesHeight - 1) < tile.y())
+ dy = tile.y() - firstTileY - (nbTilesHeight - 1);
int d = std::max(dx, dy);
XLOG("setTileLevel tile: %x, fxy(%d, %d), level: %d", tile, firstTileX, firstTileY, d);
- tile->setUsedLevel(d);
+ tile.setUsedLevel(d);
}
// clear the invalidated region as all tiles within that region have now
@@ -245,32 +263,28 @@ void TiledPage::draw(float transparency, SkRect& viewport, int firstTileX, int f
if (!m_glWebViewState)
return;
- float w = TilesManager::instance()->tileWidth() * m_invScale;
- float h = TilesManager::instance()->tileHeight() * m_invScale;
- int nbTilesWidth = m_glWebViewState->nbTilesWidth();
- int nbTilesHeight = m_glWebViewState->nbTilesHeight();
-
- XLOG("WE DRAW %x (%.2f) with transparency %.2f", this, scale(), transparency);
- for (int i = 0; i < nbTilesHeight; i++) {
- for (int j = 0; j < nbTilesWidth; j++) {
- int x = j + firstTileX;
- int y = i + firstTileY;
+ const float tileWidth = TilesManager::tileWidth() * m_invScale;
+ const float tileHeight = TilesManager::tileHeight() * m_invScale;
- BaseTile* tile = getBaseTile(x, y);
+ SkIRect viewportTilesRect;
+ viewportTilesRect.fLeft = firstTileX;
+ viewportTilesRect.fTop = firstTileY;
+ viewportTilesRect.fRight = firstTileY + m_glWebViewState->nbTilesWidth() + 1;
+ viewportTilesRect.fBottom = firstTileY + m_glWebViewState->nbTilesHeight() + 1;
- if (!tile) {
- XLOG("NO TILE AT %d, %d", x, y);
- continue;
- }
+ XLOG("WE DRAW %x (%.2f) with transparency %.2f", this, scale(), transparency);
+ for (int j = 0; j < m_baseTileSize; j++) {
+ BaseTile& tile = m_baseTiles[j];
+ if(viewportTilesRect.contains(tile.x(), tile.y())) {
SkRect rect;
- rect.fLeft = x * w;
- rect.fTop = y * h;
- rect.fRight = rect.fLeft + w;
- rect.fBottom = rect.fTop + h;
+ rect.fLeft = tile.x() * tileWidth;
+ rect.fTop = tile.y() * tileHeight;
+ rect.fRight = rect.fLeft + tileWidth;
+ rect.fBottom = rect.fTop + tileHeight;
TilesManager::instance()->shader()->setViewport(viewport);
- tile->draw(transparency, rect);
+ tile.draw(transparency, rect);
}
}
diff --git a/WebCore/platform/graphics/android/TiledPage.h b/WebCore/platform/graphics/android/TiledPage.h
index b532033..1edf5b4 100644
--- a/WebCore/platform/graphics/android/TiledPage.h
+++ b/WebCore/platform/graphics/android/TiledPage.h
@@ -38,9 +38,6 @@ namespace WebCore {
class GLWebViewState;
class IntRect;
-typedef std::pair<int, int> TileKey;
-typedef HashMap<TileKey, BaseTile*> TileMap;
-
/**
* The TiledPage represents a map of BaseTiles covering the viewport. Each
* GLWebViewState contains two TiledPages, one to display the page at the
@@ -83,9 +80,14 @@ private:
void updateTileState(int firstTileX, int firstTileY);
void prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y, TileSet* set);
- BaseTile* getBaseTile(int x, int y);
+ BaseTile* getBaseTile(int x, int y) const;
- TileMap m_baseTiles;
+ // array of tiles used to compose a page. The tiles are allocated in the
+ // constructor to prevent them from potentially being allocated on the stack
+ BaseTile* m_baseTiles;
+ // stores the number of tiles in the m_baseTiles array. This enables us to
+ // quickly iterate over the array without have to check it's size
+ int m_baseTileSize;
int m_id;
float m_scale;
float m_invScale;
diff --git a/WebCore/platform/graphics/android/TilesManager.cpp b/WebCore/platform/graphics/android/TilesManager.cpp
index 9ebfe02..38dd282 100644
--- a/WebCore/platform/graphics/android/TilesManager.cpp
+++ b/WebCore/platform/graphics/android/TilesManager.cpp
@@ -55,17 +55,17 @@
// second page used when scaling.
// In our case, we use 300x300 textures. On the tablet, this equals to
// at least 24 (6 * 4) textures, hence 48.
-#define DEFAULT_TEXTURES_ALLOCATION 48
-#define DEFAULT_TEXTURE_SIZE_WIDTH 300
-#define DEFAULT_TEXTURE_SIZE_HEIGHT 300
+#define MAX_TEXTURE_ALLOCATION 48
+#define TILE_WIDTH 300
+#define TILE_HEIGHT 300
namespace WebCore {
TilesManager::TilesManager()
: m_generatorReady(false)
{
- m_textures.reserveCapacity(DEFAULT_TEXTURES_ALLOCATION);
- for (int i = 0; i < DEFAULT_TEXTURES_ALLOCATION; i++) {
+ m_textures.reserveCapacity(MAX_TEXTURE_ALLOCATION);
+ for (int i = 0; i < MAX_TEXTURE_ALLOCATION; i++) {
BackedDoubleBufferedTexture* texture = new BackedDoubleBufferedTexture(
tileWidth(), tileHeight());
// the atomic load ensures that the texture has been fully initialized
@@ -217,14 +217,19 @@ BackedDoubleBufferedTexture* TilesManager::getAvailableTexture(BaseTile* owner)
return 0;
}
-float TilesManager::tileWidth() const
+int TilesManager::maxTextureCount()
{
- return DEFAULT_TEXTURE_SIZE_WIDTH;
+ return MAX_TEXTURE_ALLOCATION;
}
-float TilesManager::tileHeight() const
+float TilesManager::tileWidth()
{
- return DEFAULT_TEXTURE_SIZE_HEIGHT;
+ return TILE_WIDTH;
+}
+
+float TilesManager::tileHeight()
+{
+ return TILE_HEIGHT;
}
TilesManager* TilesManager::instance()
diff --git a/WebCore/platform/graphics/android/TilesManager.h b/WebCore/platform/graphics/android/TilesManager.h
index 1f9cd38..86f6ce0 100644
--- a/WebCore/platform/graphics/android/TilesManager.h
+++ b/WebCore/platform/graphics/android/TilesManager.h
@@ -69,8 +69,9 @@ public:
void resetTextureUsage(TiledPage* page);
void paintTexturesDefault();
- float tileWidth() const;
- float tileHeight() const;
+ static int maxTextureCount();
+ static float tileWidth();
+ static float tileHeight();
private: