From 1338d44578fe97a74e4b57b6f00005b9bed72682 Mon Sep 17 00:00:00 2001 From: Teng-Hui Zhu Date: Wed, 16 May 2012 15:08:47 -0700 Subject: Fix the tile dirty and framework inval when in single Surface mode bug:6457191 Change-Id: Icaef168e16aa26c9a09c6f99e5a498fc1948d2bc --- .../platform/graphics/android/GLWebViewState.cpp | 19 +++--- .../android/rendering/SurfaceCollection.cpp | 7 +++ .../graphics/android/rendering/SurfaceCollection.h | 1 + .../android/rendering/SurfaceCollectionManager.cpp | 67 +++++++++++++++++----- .../android/rendering/SurfaceCollectionManager.h | 11 +++- 5 files changed, 82 insertions(+), 23 deletions(-) diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp index 1fe30de..f6be593 100644 --- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp +++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp @@ -60,7 +60,7 @@ namespace WebCore { -using namespace android; +using namespace android::uirenderer; GLWebViewState::GLWebViewState() : m_frameworkLayersInval(0, 0, 0, 0) @@ -338,7 +338,7 @@ int GLWebViewState::drawGL(IntRect& invScreenRect, SkRect& visibleContentRect, // TODO: upload as many textures as possible within a certain time limit int returnFlags = 0; if (ImagesManager::instance()->prepareTextures(this)) - returnFlags |= uirenderer::DrawGlInfo::kStatusDraw; + returnFlags |= DrawGlInfo::kStatusDraw; if (scale < MIN_SCALE_WARNING || scale > MAX_SCALE_WARNING) { ALOGW("WARNING, scale seems corrupted after update: %e", scale); @@ -352,11 +352,14 @@ int GLWebViewState::drawGL(IntRect& invScreenRect, SkRect& visibleContentRect, titleBarHeight, screenClip, scale); TexturesResult nbTexturesNeeded; - bool fastSwap = isScrolling() || m_layersRenderingMode == kSingleSurfaceRendering; + bool scrolling = isScrolling(); + bool singleSurfaceMode = m_layersRenderingMode == kSingleSurfaceRendering; m_glExtras.setVisibleContentRect(visibleContentRect); + returnFlags |= m_surfaceCollectionManager.drawGL(currentTime, invScreenRect, visibleContentRect, - scale, fastSwap, + scale, scrolling, + singleSurfaceMode, collectionsSwappedPtr, newCollectionHasAnimPtr, &nbTexturesNeeded, shouldDraw); @@ -371,12 +374,12 @@ int GLWebViewState::drawGL(IntRect& invScreenRect, SkRect& visibleContentRect, if (setLayersRenderingMode(nbTexturesNeeded)) { TilesManager::instance()->dirtyAllTiles(); - returnFlags |= uirenderer::DrawGlInfo::kStatusDraw | uirenderer::DrawGlInfo::kStatusInvoke; + returnFlags |= DrawGlInfo::kStatusDraw | DrawGlInfo::kStatusInvoke; } glBindBuffer(GL_ARRAY_BUFFER, 0); - if (returnFlags & uirenderer::DrawGlInfo::kStatusDraw) { + if (returnFlags & DrawGlInfo::kStatusDraw) { // returnFlags & kStatusDraw && empty inval region means we've inval'd everything, // but don't have new content. Keep redrawing full view (0,0,0,0) // until tile generation catches up and we swap pages. @@ -390,8 +393,8 @@ int GLWebViewState::drawGL(IntRect& invScreenRect, SkRect& visibleContentRect, invalRect->setWidth(m_frameworkLayersInval.width()); invalRect->setHeight(m_frameworkLayersInval.height()); - ALOGV("invalRect(%d, %d, %d, %d)", inval.x(), - inval.y(), inval.width(), inval.height()); + ALOGV("invalRect(%d, %d, %d, %d)", invalRect->x(), + invalRect->y(), invalRect->width(), invalRect->height()); if (!invalRect->intersects(invScreenRect)) { // invalidate is occurring offscreen, do full inval to guarantee redraw diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp index 3b6b306..558d720 100644 --- a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp @@ -156,6 +156,13 @@ bool SurfaceCollection::isReady() return true; } +bool SurfaceCollection::isBaseSurfaceReady() +{ + if (!m_compositedRoot || !m_surfaces[0]) + return false; + return m_surfaces[0]->isReady(); +} + bool SurfaceCollection::isMissingBackgroundContent() { if (!m_compositedRoot) diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h index 5967c70..8debd6a 100644 --- a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h +++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h @@ -53,6 +53,7 @@ public: Color getBackgroundColor(); void swapTiles(); bool isReady(); + bool isBaseSurfaceReady(); bool isMissingBackgroundContent(); void computeTexturesAmount(TexturesResult* result); diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp index 7c42bd9..8f2dcba 100644 --- a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp @@ -36,11 +36,15 @@ namespace WebCore { +using namespace android::uirenderer; + SurfaceCollectionManager::SurfaceCollectionManager() : m_drawingCollection(0) , m_paintingCollection(0) , m_queuedCollection(0) , m_fastSwapMode(false) + , m_previouslyScrolling(false) + , m_newPaintingCollection(false) { } @@ -95,6 +99,13 @@ void SurfaceCollectionManager::clearCollections() m_queuedCollection = 0; } +void SurfaceCollectionManager::updatePaintingCollection(SurfaceCollection* newCollection) +{ + m_paintingCollection = newCollection; + m_paintingCollection->setIsPainting(m_drawingCollection); + m_newPaintingCollection = true; +} + // a new layer collection has arrived, queue it if we're painting something already, // or start painting it if we aren't. Returns true if the manager has two collections // already queued. @@ -106,10 +117,8 @@ bool SurfaceCollectionManager::updateWithSurfaceCollection(SurfaceCollection* ne if (!newCollection || brandNew) { clearCollections(); - if (brandNew) { - m_paintingCollection = newCollection; - m_paintingCollection->setIsPainting(m_drawingCollection); - } + if (brandNew) + updatePaintingCollection(newCollection); return false; } @@ -137,8 +146,7 @@ bool SurfaceCollectionManager::updateWithSurfaceCollection(SurfaceCollection* ne m_queuedCollection = newCollection; } else { // don't have painting collection, paint this one! - m_paintingCollection = newCollection; - m_paintingCollection->setIsPainting(m_drawingCollection); + updatePaintingCollection(newCollection); } return m_drawingCollection && TilesManager::instance()->useDoubleBuffering(); } @@ -153,13 +161,43 @@ void SurfaceCollectionManager::updateScrollableLayer(int layerId, int x, int y) m_drawingCollection->updateScrollableLayer(layerId, x, y); } + +int SurfaceCollectionManager::singleSurfaceModeInvalidation(bool scrolling, + bool shouldDraw) +{ + int returnFlags = 0; + // In single surface mode, we need to dirty all the tiles when we are finishing + // scrolling or have an incoming painting tree. + bool requireDirtyAll = (m_previouslyScrolling && !scrolling) + || m_newPaintingCollection; + if (requireDirtyAll) + TilesManager::instance()->dirtyAllTiles(); + + // We also need to tell the framework to continue to invoke until + // the base layer is ready. + bool drawingBaseSurfaceReady = m_drawingCollection + && m_drawingCollection->isBaseSurfaceReady(); + bool requireInvoke = requireDirtyAll || !drawingBaseSurfaceReady; + if (requireInvoke) + returnFlags |= DrawGlInfo::kStatusInvoke; + + // When the base layer is ready, we can ask the framework to draw. + if (!shouldDraw && drawingBaseSurfaceReady) + returnFlags |= DrawGlInfo::kStatusDraw; + + m_newPaintingCollection = false; + m_previouslyScrolling = scrolling; + + return returnFlags; +} + int SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect, SkRect& visibleContentRect, float scale, - bool enterFastSwapMode, + bool scrolling, bool singleSurfaceMode, bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr, TexturesResult* texturesResultPtr, bool shouldDraw) { - m_fastSwapMode |= enterFastSwapMode; + m_fastSwapMode |= scrolling || singleSurfaceMode; ALOGV("drawGL, D %p, P %p, Q %p, fastSwap %d shouldDraw %d", m_drawingCollection, m_paintingCollection, @@ -196,7 +234,10 @@ int SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect, int returnFlags = 0; if (m_paintingCollection) - returnFlags |= uirenderer::DrawGlInfo::kStatusInvoke; + returnFlags |= DrawGlInfo::kStatusInvoke; + + if (singleSurfaceMode) + returnFlags |= singleSurfaceModeInvalidation(scrolling, shouldDraw); if (!shouldDraw) { if (didCollectionSwap @@ -205,11 +246,11 @@ int SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect, && m_drawingCollection->isReady())) { // either a swap just occurred, or there is no more work to be done: do a full draw m_drawingCollection->swapTiles(); - returnFlags |= uirenderer::DrawGlInfo::kStatusDraw; + returnFlags |= DrawGlInfo::kStatusDraw; } else { // current collection not ready - invoke functor in process mode // until either drawing or painting collection is ready - returnFlags |= uirenderer::DrawGlInfo::kStatusInvoke; + returnFlags |= DrawGlInfo::kStatusInvoke; } return returnFlags; @@ -234,7 +275,7 @@ int SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect, m_fastSwapMode = false; } else { // drawing isn't ready, must redraw - returnFlags |= uirenderer::DrawGlInfo::kStatusInvoke; + returnFlags |= DrawGlInfo::kStatusInvoke; } m_drawingCollection->evaluateAnimations(currentTime); @@ -256,7 +297,7 @@ int SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect, } if (m_drawingCollection && m_drawingCollection->drawGL(visibleContentRect)) - returnFlags |= uirenderer::DrawGlInfo::kStatusDraw; + returnFlags |= DrawGlInfo::kStatusDraw; ALOGV("returnFlags %d, m_paintingCollection %d ", returnFlags, m_paintingCollection); return returnFlags; diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.h b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.h index be4fbca..6aed060 100644 --- a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.h +++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.h @@ -51,18 +51,25 @@ public: int drawGL(double currentTime, IntRect& viewRect, SkRect& visibleContentRect, float scale, - bool enterFastSwapMode, bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr, + bool scrolling, bool singleSurfaceMode, + bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr, TexturesResult* texturesResultPtr, bool shouldDraw); private: void swap(); void clearCollections(); - + void updatePaintingCollection(SurfaceCollection* newCollection); + int singleSurfaceModeInvalidation(bool scrolling, bool shouldDraw); SurfaceCollection* m_drawingCollection; SurfaceCollection* m_paintingCollection; SurfaceCollection* m_queuedCollection; bool m_fastSwapMode; + // Used in single surface mode only. True if the previous frame is scrolling. + bool m_previouslyScrolling; + // Used in single surface mode only. True if there is a new painting tree + // added for the current frame. + bool m_newPaintingCollection; }; } // namespace WebCore -- cgit v1.1