diff options
author | Nicolas Roard <nicolasroard@google.com> | 2011-03-22 14:29:12 -0700 |
---|---|---|
committer | Nicolas Roard <nicolasroard@google.com> | 2011-03-22 23:56:44 -0700 |
commit | 772742124c1e5c700120019397dc8af29ced74c0 (patch) | |
tree | b3a1d15332445f13f7a174d78587bc990dafd699 /WebCore/platform/graphics | |
parent | 55c8e9b1b75caff31e804a6f4da404da9f67af93 (diff) | |
download | external_webkit-772742124c1e5c700120019397dc8af29ced74c0.zip external_webkit-772742124c1e5c700120019397dc8af29ced74c0.tar.gz external_webkit-772742124c1e5c700120019397dc8af29ced74c0.tar.bz2 |
Fix performance problems with layers
We were preventing the layers' positions to be updated
while waiting for the base surface to render.
This also fix some repainting issues.
bug:4136077
Change-Id: I6870faf8296e205c6ee58e80b1cf95833a67814b
Diffstat (limited to 'WebCore/platform/graphics')
5 files changed, 62 insertions, 22 deletions
diff --git a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp index 4ab0774..5c63117 100644 --- a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp +++ b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp @@ -258,7 +258,8 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale, double } #endif // USE(ACCELERATED_COMPOSITING) -bool BaseLayerAndroid::drawGL(IntRect& viewRect, SkRect& visibleRect, +bool BaseLayerAndroid::drawGL(LayerAndroid* compositedRoot, + IntRect& viewRect, SkRect& visibleRect, float scale, SkColor color) { bool needsRedraw = false; @@ -293,8 +294,7 @@ bool BaseLayerAndroid::drawGL(IntRect& viewRect, SkRect& visibleRect, if (!needsRedraw) m_glWebViewState->resetFrameworkInval(); - if (countChildren() >= 1) { - LayerAndroid* compositedRoot = static_cast<LayerAndroid*>(getChild(0)); + if (compositedRoot) { TransformationMatrix ident; bool animsRunning = compositedRoot->evaluateAnimations(); @@ -324,23 +324,31 @@ bool BaseLayerAndroid::drawGL(IntRect& viewRect, SkRect& visibleRect, if (m_glWebViewState->scaleRequestState() == GLWebViewState::kReceivedNewScale) { scale = m_glWebViewState->futureScale(); } + bool fullSetup = true; + if ((m_glWebViewState->previouslyUsedRoot() == compositedRoot) && + (compositedRoot->getScale() == scale) && + (!m_glWebViewState->moving())) + fullSetup = false; + compositedRoot->setScale(scale); - compositedRoot->computeTextureSize(currentTime); - compositedRoot->reserveGLTextures(); + + if (fullSetup) { + compositedRoot->computeTextureSize(currentTime); + compositedRoot->reserveGLTextures(); #ifdef DEBUG - int size = compositedRoot->countTextureSize(); - int nbLayers = compositedRoot->nbLayers(); - XLOG("We are using %d Mb for %d layers", size / 1024 / 1024, nbLayers); - compositedRoot->showLayers(); + int size = compositedRoot->countTextureSize(); + int nbLayers = compositedRoot->nbLayers(); + XLOG("We are using %d Mb for %d layers", size / 1024 / 1024, nbLayers); + compositedRoot->showLayers(); #endif - - // Now that we marked the textures being used, we delete - // the unnecessary ones to make space... - TilesManager::instance()->cleanupLayersTextures(compositedRoot); - // Finally do another pass to create new textures and schedule - // repaints if needed - compositedRoot->createGLTextures(); + // Now that we marked the textures being used, we delete + // the unnecessary ones to make space... + TilesManager::instance()->cleanupLayersTextures(compositedRoot); + // Finally do another pass to create new textures and schedule + // repaints if needed + compositedRoot->createGLTextures(); + } if (compositedRoot->drawGL(m_glWebViewState, matrix)) needsRedraw = true; diff --git a/WebCore/platform/graphics/android/BaseLayerAndroid.h b/WebCore/platform/graphics/android/BaseLayerAndroid.h index cb1caef..8ff6ffd 100644 --- a/WebCore/platform/graphics/android/BaseLayerAndroid.h +++ b/WebCore/platform/graphics/android/BaseLayerAndroid.h @@ -54,7 +54,7 @@ public: // we are running in different threads. void drawCanvas(SkCanvas* canvas); - bool drawGL(IntRect& rect, SkRect& viewport, + bool drawGL(LayerAndroid* compositedRoot, IntRect& rect, SkRect& viewport, float scale, SkColor color = SK_ColorWHITE); void swapExtra(BaseLayerAndroid* base) { m_extra.swap(base->m_extra); } private: diff --git a/WebCore/platform/graphics/android/GLWebViewState.cpp b/WebCore/platform/graphics/android/GLWebViewState.cpp index dbbc633..189b3f0 100644 --- a/WebCore/platform/graphics/android/GLWebViewState.cpp +++ b/WebCore/platform/graphics/android/GLWebViewState.cpp @@ -69,6 +69,7 @@ GLWebViewState::GLWebViewState(android::Mutex* buttonMutex) , m_transitionTime(-1) , m_baseLayer(0) , m_currentBaseLayer(0) + , m_previouslyUsedRoot(0) , m_currentPictureCounter(0) , m_usePageA(true) , m_frameworkInval(0, 0, 0, 0) @@ -107,6 +108,9 @@ GLWebViewState::~GLWebViewState() delete m_tiledPageA; delete m_tiledPageB; SkSafeUnref(m_currentBaseLayer); + SkSafeUnref(m_baseLayer); + m_baseLayer = 0; + m_currentBaseLayer = 0; #ifdef DEBUG_COUNT ClassTracker::instance()->decrement("GLWebViewState"); #endif @@ -126,10 +130,13 @@ void GLWebViewState::setBaseLayer(BaseLayerAndroid* layer, const SkRegion& inval } if (m_baseLayer && layer) m_baseLayer->swapExtra(layer); + + SkSafeRef(layer); + SkSafeUnref(m_baseLayer); m_baseLayer = layer; - if (m_baseLayer) { + if (m_baseLayer) m_baseLayer->setGLWebViewState(this); - } + // We only update the layers if we are not currently // waiting for a tiledPage to be painted if (m_baseLayerUpdate) { @@ -404,16 +411,33 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, m_baseLayerLock.lock(); BaseLayerAndroid* baseLayer = m_currentBaseLayer; SkSafeRef(baseLayer); + BaseLayerAndroid* baseForComposited = m_baseLayer; + SkSafeRef(baseForComposited); m_baseLayerLock.unlock(); - if (!baseLayer) + if (!baseLayer) { + SkSafeUnref(baseForComposited); return false; + } XLOG("drawGL, rect(%d, %d, %d, %d), viewport(%.2f, %.2f, %.2f, %.2f)", rect.x(), rect.y(), rect.right(), rect.bottom(), viewport.fLeft, viewport.fTop, viewport.fRight, viewport.fBottom); resetLayersDirtyArea(); - bool ret = baseLayer->drawGL(rect, viewport, scale, color); + + if (!baseForComposited || + (baseForComposited && !baseForComposited->countChildren())) { + SkSafeRef(baseLayer); + SkSafeUnref(baseForComposited); + baseForComposited = baseLayer; + } + + LayerAndroid* compositedRoot = 0; + if (baseForComposited && baseForComposited->countChildren() >= 1) + compositedRoot = static_cast<LayerAndroid*>(baseForComposited->getChild(0)); + + bool ret = baseLayer->drawGL(compositedRoot, rect, viewport, scale, color); + m_previouslyUsedRoot = compositedRoot; if (ret) { IntRect inval = m_frameworkInval; inval.unite(m_frameworkLayersInval); @@ -437,6 +461,7 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, } #endif + SkSafeUnref(baseForComposited); SkSafeUnref(baseLayer); return ret; } diff --git a/WebCore/platform/graphics/android/GLWebViewState.h b/WebCore/platform/graphics/android/GLWebViewState.h index 854d8cc..091bedc 100644 --- a/WebCore/platform/graphics/android/GLWebViewState.h +++ b/WebCore/platform/graphics/android/GLWebViewState.h @@ -226,6 +226,7 @@ public: void resetFrameworkInval(); void addDirtyArea(const IntRect& rect); void resetLayersDirtyArea(); + LayerAndroid* previouslyUsedRoot() { return m_previouslyUsedRoot; } private: void inval(const IntRect& rect); // caller must hold m_baseLayerLock @@ -258,6 +259,8 @@ private: android::Mutex m_baseLayerLock; BaseLayerAndroid* m_baseLayer; BaseLayerAndroid* m_currentBaseLayer; + LayerAndroid* m_previouslyUsedRoot; + unsigned int m_currentPictureCounter; bool m_usePageA; TiledPage* m_tiledPageA; diff --git a/WebCore/platform/graphics/android/LayerAndroid.cpp b/WebCore/platform/graphics/android/LayerAndroid.cpp index 009915e..dc40fb1 100644 --- a/WebCore/platform/graphics/android/LayerAndroid.cpp +++ b/WebCore/platform/graphics/android/LayerAndroid.cpp @@ -928,8 +928,10 @@ bool LayerAndroid::drawGL(GLWebViewState* glWebViewState, SkMatrix& matrix) { TilesManager::instance()->shader()->clip(m_clippingRect); - if (prepareContext() && m_drawingTexture) { + if (m_drawingTexture) { TextureInfo* textureInfo = m_drawingTexture->consumerLock(); + if (!m_drawingTexture->readyFor(this)) + m_dirty = true; if (textureInfo) { SkRect bounds; bounds.set(m_drawingTexture->rect()); @@ -943,6 +945,8 @@ bool LayerAndroid::drawGL(GLWebViewState* glWebViewState, SkMatrix& matrix) m_drawOpacity, true); } m_drawingTexture->consumerRelease(); + } else { + m_dirty = true; } // When the layer is dirty, the UI thread should be notified to redraw. |