From c4718e6733cb345bafc3a95a9e1c234047bfde7e Mon Sep 17 00:00:00 2001 From: Nicolas Roard Date: Wed, 16 Nov 2011 18:25:59 -0800 Subject: [PATCH] Set the number of current textures depending on the layers' count, to avoid going to single drawing surface if we can. Also fix a crash when logging layers. bug:5279231 Change-Id: I1c3f2ce4bcedac1c172e87c7ec3c6692d8e35e14 --- .../platform/graphics/android/GLWebViewState.cpp | 8 ++- .../platform/graphics/android/LayerAndroid.cpp | 7 ++- .../platform/graphics/android/TilesManager.cpp | 64 ++++++++++++++++++---- .../platform/graphics/android/TilesManager.h | 8 +++ .../platform/graphics/android/TreeManager.cpp | 9 ++- 5 files changed, 79 insertions(+), 17 deletions(-) diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp index f00053200..0b7837358 100644 --- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp +++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp @@ -359,7 +359,13 @@ double GLWebViewState::setupDrawing(IntRect& viewRect, SkRect& visibleRect, bool GLWebViewState::setLayersRenderingMode(TexturesResult& nbTexturesNeeded) { bool invalBase = false; - int maxTextures = TilesManager::instance()->maxTextureCount(); + + if (!nbTexturesNeeded.full) + TilesManager::instance()->setMaxLayerTextureCount(0); + else + TilesManager::instance()->setMaxLayerTextureCount((2*nbTexturesNeeded.full)+1); + + int maxTextures = TilesManager::instance()->maxLayerTextureCount(); LayersRenderingMode layersRenderingMode = m_layersRenderingMode; m_layersRenderingMode = kSingleSurfaceRendering; diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp index b86be99b6..9e7626aa0 100644 --- a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp @@ -770,7 +770,7 @@ void LayerAndroid::setContentsImage(SkBitmapRef* img) bool LayerAndroid::needsTexture() { - return m_imageRef || (prepareContext() + return m_imageRef || (m_recordingPicture && m_recordingPicture->width() && m_recordingPicture->height()); } @@ -842,14 +842,15 @@ void LayerAndroid::showLayer(int indent) IntRect clip(m_clippingRect.x(), m_clippingRect.y(), m_clippingRect.width(), m_clippingRect.height()); XLOGC("%s [%d:0x%x] - %s - area (%d, %d, %d, %d) - visible (%d, %d, %d, %d) " - "clip (%d, %d, %d, %d) %s prepareContext(%d), pic w: %d h: %d", + "clip (%d, %d, %d, %d) %s %s prepareContext(%x), pic w: %d h: %d", spaces, uniqueId(), m_owningLayer, needsTexture() ? "needs a texture" : "no texture", tr.x(), tr.y(), tr.width(), tr.height(), visible.x(), visible.y(), visible.width(), visible.height(), clip.x(), clip.y(), clip.width(), clip.height(), contentIsScrollable() ? "SCROLLABLE" : "", - prepareContext(), + isFixed() ? "FIXED" : "", + m_recordingPicture, m_recordingPicture ? m_recordingPicture->width() : -1, m_recordingPicture ? m_recordingPicture->height() : -1); diff --git a/Source/WebCore/platform/graphics/android/TilesManager.cpp b/Source/WebCore/platform/graphics/android/TilesManager.cpp index ca484ce86..8339221d5 100644 --- a/Source/WebCore/platform/graphics/android/TilesManager.cpp +++ b/Source/WebCore/platform/graphics/android/TilesManager.cpp @@ -77,6 +77,8 @@ #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() @@ -95,12 +97,15 @@ int TilesManager::getMaxTextureAllocation() 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); @@ -128,9 +133,9 @@ 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( @@ -153,7 +158,6 @@ void TilesManager::allocateTiles() 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) { @@ -165,19 +169,19 @@ void TilesManager::deallocateTextures(bool allTextures) sparedDrawCount = std::max(sparedDrawCount, owner->drawCount()); } } + deallocateTexturesVector(sparedDrawCount, m_textures); + deallocateTexturesVector(sparedDrawCount, m_tilesTextures); +} +void TilesManager::deallocateTexturesVector(unsigned long long sparedDrawCount, + WTF::Vector& textures) +{ + const unsigned int max = textures.size(); int dealloc = 0; for (unsigned int i = 0; i < max; i++) { - TextureOwner* owner = m_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(); + TextureOwner* owner = textures[i]->owner(); if (!owner || owner->drawCount() < sparedDrawCount) { - m_tilesTextures[i]->discardGLTexture(); + textures[i]->discardGLTexture(); dealloc++; } } @@ -337,6 +341,12 @@ int TilesManager::maxTextureCount() 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)", @@ -355,6 +365,36 @@ void TilesManager::setMaxTextureCount(int max) 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; diff --git a/Source/WebCore/platform/graphics/android/TilesManager.h b/Source/WebCore/platform/graphics/android/TilesManager.h index cc66f1a28..0c3e9000e 100644 --- a/Source/WebCore/platform/graphics/android/TilesManager.h +++ b/Source/WebCore/platform/graphics/android/TilesManager.h @@ -105,7 +105,9 @@ public: void resetTextureUsage(TiledPage* page); int maxTextureCount(); + int maxLayerTextureCount(); void setMaxTextureCount(int max); + void setMaxLayerTextureCount(int max); static float tileWidth(); static float tileHeight(); static float layerTileWidth(); @@ -205,6 +207,9 @@ private: m_generatorReadyCond.wait(m_generatorLock); } + void deallocateTexturesVector(unsigned long long sparedDrawCount, + WTF::Vector& textures); + Vector m_textures; Vector m_availableTextures; @@ -215,6 +220,7 @@ private: Vector m_paintedSurfaces; int m_maxTextureCount; + int m_maxLayerTextureCount; bool m_generatorReady; @@ -240,6 +246,8 @@ private: TilesProfiler m_profiler; TilesTracker m_tilesTracker; unsigned long long m_drawGLCount; + double m_lastTimeLayersUsed; + bool m_hasLayerTextures; }; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/TreeManager.cpp b/Source/WebCore/platform/graphics/android/TreeManager.cpp index 5fbc89361..5fd3b7c4b 100644 --- a/Source/WebCore/platform/graphics/android/TreeManager.cpp +++ b/Source/WebCore/platform/graphics/android/TreeManager.cpp @@ -186,6 +186,10 @@ bool TreeManager::drawGL(double currentTime, IntRect& viewRect, ret |= m_paintingTree->prepare(currentTime, viewRect, visibleRect, scale); + if (m_paintingTree->countChildren()) { + LayerAndroid* laTree = static_cast(m_paintingTree->getChild(0)); + laTree->computeTexturesAmount(texturesResultPtr); + } if (/*!m_fastSwapMode && */ m_paintingTree->isReady()) { XLOG("have painting tree %p ready, swapping!", m_paintingTree); didTreeSwap = true; @@ -197,6 +201,10 @@ bool TreeManager::drawGL(double currentTime, IntRect& viewRect, XLOG("preparing drawing tree %p", m_drawingTree); ret |= m_drawingTree->prepare(currentTime, viewRect, visibleRect, scale); + if (m_drawingTree->countChildren()) { + LayerAndroid* laTree = static_cast(m_drawingTree->getChild(0)); + laTree->computeTexturesAmount(texturesResultPtr); + } } if (!m_isAnimating) { @@ -226,7 +234,6 @@ bool TreeManager::drawGL(double currentTime, IntRect& viewRect, m_drawingTree, m_animationOffset, m_isAnimating); #endif LayerAndroid* laTree = static_cast(m_drawingTree->getChild(0)); - laTree->computeTexturesAmount(texturesResultPtr); m_isAnimating = laTree->evaluateAnimations(currentTime - m_animationOffset); if (!m_isAnimating) m_animationOffset = 0; -- 2.11.0