// 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
#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()
}
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);
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(
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) {
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++;
}
}
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
#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);
{
android::Mutex::Autolock lock(m_texturesLock);
m_availableTilesTextures = m_tilesTextures;
+ m_layerTexturesRemain = true;
}
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
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
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",
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)",
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;
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);
}
}
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) {