// 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_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);
m_tilesTextures.reserveCapacity(MAX_TEXTURE_ALLOCATION);
m_availableTilesTextures.reserveCapacity(MAX_TEXTURE_ALLOCATION);
m_pixmapsGenerationThread = new TexturesGenerator();
- m_pixmapsGenerationThread->run("TexturesGenerator", android::PRIORITY_BACKGROUND);
+ m_pixmapsGenerationThread->run("TexturesGenerator");
}
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(
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]->discardGLTexture();
- dealloc++;
- }
- }
- for (unsigned int i = 0; i < maxLayer; i++) {
- TextureOwner* owner = m_tilesTextures[i]->owner();
- if (!owner || owner->drawCount() < sparedDrawCount) {
- m_tilesTextures[i]->discardGLTexture();
+ 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);
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);
}
}