diff options
author | Nicolas Roard <nicolasroard@google.com> | 2011-03-15 18:20:42 -0700 |
---|---|---|
committer | Nicolas Roard <nicolasroard@google.com> | 2011-03-16 23:43:46 -0700 |
commit | 9f5143f9ae49a8e5fdb7ea626c4efad66096b020 (patch) | |
tree | b1d3eb92be0b354b8f662f50653da96c4d3cbdc8 /WebCore/platform | |
parent | 8e1d10880da3108f7eb53ae81682a7c4192a2e3f (diff) | |
download | external_webkit-9f5143f9ae49a8e5fdb7ea626c4efad66096b020.zip external_webkit-9f5143f9ae49a8e5fdb7ea626c4efad66096b020.tar.gz external_webkit-9f5143f9ae49a8e5fdb7ea626c4efad66096b020.tar.bz2 |
Implement partial screen invalidations
bug:3461349
Change-Id: Id654d176c58027c67be7cb604b87c0ec68984525
Diffstat (limited to 'WebCore/platform')
9 files changed, 120 insertions, 28 deletions
diff --git a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp index 1f969be..4ab0774 100644 --- a/WebCore/platform/graphics/android/BaseLayerAndroid.cpp +++ b/WebCore/platform/graphics/android/BaseLayerAndroid.cpp @@ -211,6 +211,7 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale, double const SkIRect& preZoomBounds = m_glWebViewState->preZoomBounds(); TiledPage* nextTiledPage = m_glWebViewState->backPage(); + bool needsRedraw = false; // We are now using an hybrid model -- during scrolling, // we will display the current tiledPage even if some tiles are @@ -225,12 +226,16 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale, double } if (nextTiledPage->ready(preZoomBounds, m_glWebViewState->currentScale())) { nextTiledPage->draw(transparency, preZoomBounds); + m_glWebViewState->resetFrameworkInval(); m_glWebViewState->unlockBaseLayerUpdate(); doSwap = true; } else { tiledPage->draw(transparency, preZoomBounds); } } else { + if (tiledPage->ready(preZoomBounds, m_glWebViewState->currentScale())) + m_glWebViewState->resetFrameworkInval(); + // Ask for the tiles and draw -- tiles may be out of date. if (!zooming) m_glWebViewState->unlockBaseLayerUpdate(); @@ -239,10 +244,9 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale, double tiledPage->draw(transparency, preZoomBounds); } - bool ret = false; if (m_glWebViewState->scaleRequestState() != GLWebViewState::kNoScaleRequest || !tiledPage->ready(preZoomBounds, m_glWebViewState->currentScale())) - ret = true; + needsRedraw = true; if (doSwap) { m_glWebViewState->setCurrentScale(scale); @@ -250,14 +254,14 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale, double m_glWebViewState->unlockBaseLayerUpdate(); } - return ret; + return needsRedraw; } #endif // USE(ACCELERATED_COMPOSITING) bool BaseLayerAndroid::drawGL(IntRect& viewRect, SkRect& visibleRect, float scale, SkColor color) { - bool ret = false; + bool needsRedraw = false; #if USE(ACCELERATED_COMPOSITING) int left = viewRect.x(); int top = viewRect.y(); @@ -285,11 +289,18 @@ bool BaseLayerAndroid::drawGL(IntRect& viewRect, SkRect& visibleRect, shader->resetBlending(); double currentTime = WTF::currentTime(); - ret = drawBasePictureInGL(visibleRect, scale, currentTime); + needsRedraw = drawBasePictureInGL(visibleRect, scale, currentTime); + if (!needsRedraw) + m_glWebViewState->resetFrameworkInval(); if (countChildren() >= 1) { LayerAndroid* compositedRoot = static_cast<LayerAndroid*>(getChild(0)); TransformationMatrix ident; + + bool animsRunning = compositedRoot->evaluateAnimations(); + if (animsRunning) + needsRedraw = true; + compositedRoot->updateFixedLayersPositions(visibleRect); FloatRect clip(0, 0, viewRect.width(), viewRect.height()); compositedRoot->updateGLPositions(ident, clip, 1); @@ -331,8 +342,11 @@ bool BaseLayerAndroid::drawGL(IntRect& viewRect, SkRect& visibleRect, // repaints if needed compositedRoot->createGLTextures(); - if (compositedRoot->drawGL(matrix)) - ret = true; + if (compositedRoot->drawGL(m_glWebViewState, matrix)) + needsRedraw = true; + else if (!animsRunning) + m_glWebViewState->resetLayersDirtyArea(); + } else { TilesManager::instance()->cleanupLayersTextures(0); } @@ -344,7 +358,7 @@ bool BaseLayerAndroid::drawGL(IntRect& viewRect, SkRect& visibleRect, #ifdef DEBUG ClassTracker::instance()->show(); #endif - return ret; + return needsRedraw; } } // namespace WebCore diff --git a/WebCore/platform/graphics/android/GLWebViewState.cpp b/WebCore/platform/graphics/android/GLWebViewState.cpp index 62eab0f..dbbc633 100644 --- a/WebCore/platform/graphics/android/GLWebViewState.cpp +++ b/WebCore/platform/graphics/android/GLWebViewState.cpp @@ -71,6 +71,8 @@ GLWebViewState::GLWebViewState(android::Mutex* buttonMutex) , m_currentBaseLayer(0) , m_currentPictureCounter(0) , m_usePageA(true) + , m_frameworkInval(0, 0, 0, 0) + , m_frameworkLayersInval(0, 0, 0, 0) , m_globalButtonMutex(buttonMutex) , m_baseLayerUpdate(true) , m_backgroundColor(SK_ColorWHITE) @@ -198,6 +200,13 @@ void GLWebViewState::inval(const IntRect& rect) // find which tiles fall within the invalRect and mark them as dirty m_tiledPageA->invalidateRect(rect, m_currentPictureCounter); m_tiledPageB->invalidateRect(rect, m_currentPictureCounter); + if (m_frameworkInval.isEmpty()) + m_frameworkInval = rect; + else + m_frameworkInval.unite(rect); + XLOG("intermediate invalRect(%d, %d, %d, %d) after unite with rect %d %d %d %d", m_frameworkInval.x(), + m_frameworkInval.y(), m_frameworkInval.right(), m_frameworkInval.bottom(), + rect.x(), rect.y(), rect.right(), rect.bottom()); } } else { m_invalidateRegion.op(rect.x(), rect.y(), rect.right(), rect.bottom(), SkRegion::kUnion_Op); @@ -353,7 +362,32 @@ void GLWebViewState::dumpMeasures() } #endif // MEASURES_PERF -bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, float scale, SkColor color) +void GLWebViewState::resetFrameworkInval() +{ + m_frameworkInval.setX(0); + m_frameworkInval.setY(0); + m_frameworkInval.setWidth(0); + m_frameworkInval.setHeight(0); +} + +void GLWebViewState::addDirtyArea(const IntRect& rect) +{ + if (m_frameworkLayersInval.isEmpty()) + m_frameworkLayersInval = rect; + else + m_frameworkLayersInval.unite(rect); +} + +void GLWebViewState::resetLayersDirtyArea() +{ + m_frameworkLayersInval.setX(0); + m_frameworkLayersInval.setY(0); + m_frameworkLayersInval.setWidth(0); + m_frameworkLayersInval.setHeight(0); +} + +bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, + float scale, SkColor color) { glFinish(); @@ -374,7 +408,26 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, float scale, SkColo if (!baseLayer) 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 (ret) { + IntRect inval = m_frameworkInval; + inval.unite(m_frameworkLayersInval); + + invalRect->setX((- viewport.fLeft + inval.x()) * scale); + invalRect->setY((- viewport.fTop + inval.y()) * scale); + invalRect->setWidth(inval.width() * scale); + invalRect->setHeight(inval.height() * scale); + + XLOG("invalRect(%d, %d, %d, %d)", inval.x(), + inval.y(), inval.right(), inval.bottom()); + } else { + resetFrameworkInval(); + } #ifdef MEASURES_PERF if (m_measurePerfs) { diff --git a/WebCore/platform/graphics/android/GLWebViewState.h b/WebCore/platform/graphics/android/GLWebViewState.h index e3b33f2..854d8cc 100644 --- a/WebCore/platform/graphics/android/GLWebViewState.h +++ b/WebCore/platform/graphics/android/GLWebViewState.h @@ -213,7 +213,7 @@ public: return false; } - bool drawGL(IntRect& rect, SkRect& viewport, + bool drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, float scale, SkColor color = SK_ColorWHITE); void setBackgroundColor(SkColor color) { m_backgroundColor = color; } @@ -223,6 +223,10 @@ public: void dumpMeasures(); #endif + void resetFrameworkInval(); + void addDirtyArea(const IntRect& rect); + void resetLayersDirtyArea(); + private: void inval(const IntRect& rect); // caller must hold m_baseLayerLock void invalRegion(const SkRegion& region); @@ -259,6 +263,8 @@ private: TiledPage* m_tiledPageA; TiledPage* m_tiledPageB; IntRect m_lastInval; + IntRect m_frameworkInval; + IntRect m_frameworkLayersInval; android::Mutex* m_globalButtonMutex; bool m_baseLayerUpdate; diff --git a/WebCore/platform/graphics/android/LayerAndroid.cpp b/WebCore/platform/graphics/android/LayerAndroid.cpp index 839798d..89ce301 100644 --- a/WebCore/platform/graphics/android/LayerAndroid.cpp +++ b/WebCore/platform/graphics/android/LayerAndroid.cpp @@ -208,7 +208,7 @@ LayerAndroid::~LayerAndroid() static int gDebugNbAnims = 0; -bool LayerAndroid::evaluateAnimations() const +bool LayerAndroid::evaluateAnimations() { double time = WTF::currentTime(); gDebugNbAnims = 0; @@ -224,22 +224,35 @@ bool LayerAndroid::hasAnimations() const return !!m_animations.size(); } -bool LayerAndroid::evaluateAnimations(double time) const +bool LayerAndroid::evaluateAnimations(double time) { bool hasRunningAnimations = false; for (int i = 0; i < countChildren(); i++) { if (getChild(i)->evaluateAnimations(time)) hasRunningAnimations = true; } + + m_hasRunningAnimations = false; + int nbAnims = 0; KeyframesMap::const_iterator end = m_animations.end(); for (KeyframesMap::const_iterator it = m_animations.begin(); it != end; ++it) { gDebugNbAnims++; + nbAnims++; LayerAndroid* currentLayer = const_cast<LayerAndroid*>(this); if ((it->second)->evaluate(currentLayer, time)) - hasRunningAnimations = true; + m_hasRunningAnimations = true; } - return hasRunningAnimations; + return hasRunningAnimations || m_hasRunningAnimations; +} + +void LayerAndroid::addDirtyArea(GLWebViewState* glWebViewState) +{ + IntRect rect(0, 0, getWidth(), getHeight()); + IntRect dirtyArea = drawTransform().mapRect(rect); + IntRect clip(m_clippingRect.x(), m_clippingRect.y(), m_clippingRect.width(), m_clippingRect.height()); + dirtyArea.intersect(clip); + glWebViewState->addDirtyArea(dirtyArea); } void LayerAndroid::addAnimation(PassRefPtr<AndroidAnimation> prpAnim) @@ -894,7 +907,7 @@ static inline bool compareLayerZ(const LayerAndroid* a, const LayerAndroid* b) return transformA.m43() < transformB.m43(); } -bool LayerAndroid::drawGL(SkMatrix& matrix) +bool LayerAndroid::drawGL(GLWebViewState* glWebViewState, SkMatrix& matrix) { TilesManager::instance()->shader()->clip(m_clippingRect); @@ -916,15 +929,17 @@ bool LayerAndroid::drawGL(SkMatrix& matrix) } // When the layer is dirty, the UI thread should be notified to redraw. - bool askPaint = drawChildrenGL(matrix); + bool askPaint = drawChildrenGL(glWebViewState, matrix); m_atomicSync.lock(); askPaint |= m_dirty; + if (m_dirty || m_hasRunningAnimations) + addDirtyArea(glWebViewState); m_atomicSync.unlock(); return askPaint; } -bool LayerAndroid::drawChildrenGL(SkMatrix& matrix) +bool LayerAndroid::drawChildrenGL(GLWebViewState* glWebViewState, SkMatrix& matrix) { bool askPaint = false; int count = this->countChildren(); @@ -937,7 +952,7 @@ bool LayerAndroid::drawChildrenGL(SkMatrix& matrix) std::stable_sort(sublayers.begin(), sublayers.end(), compareLayerZ); for (int i = 0; i < count; i++) { LayerAndroid* layer = sublayers[i]; - askPaint |= layer->drawGL(matrix); + askPaint |= layer->drawGL(glWebViewState, matrix); } } diff --git a/WebCore/platform/graphics/android/LayerAndroid.h b/WebCore/platform/graphics/android/LayerAndroid.h index 3e00bfa..98a0a15 100644 --- a/WebCore/platform/graphics/android/LayerAndroid.h +++ b/WebCore/platform/graphics/android/LayerAndroid.h @@ -128,8 +128,8 @@ public: void setScale(float scale); float getScale() { return m_scale; } - virtual bool drawGL(SkMatrix&); - bool drawChildrenGL(SkMatrix&); + virtual bool drawGL(GLWebViewState*, SkMatrix&); + bool drawChildrenGL(GLWebViewState*, SkMatrix&); virtual void paintBitmapGL(); void updateGLPositions(const TransformationMatrix& parentMatrix, const FloatRect& clip, float opacity); @@ -182,9 +182,10 @@ public: void addAnimation(PassRefPtr<AndroidAnimation> anim); void removeAnimationsForProperty(AnimatedPropertyID property); void removeAnimationsForKeyframes(const String& name); - bool evaluateAnimations() const; - bool evaluateAnimations(double time) const; + bool evaluateAnimations(); + bool evaluateAnimations(double time); bool hasAnimations() const; + void addDirtyArea(GLWebViewState*); SkPicture* picture() const { return m_recordingPicture; } @@ -325,6 +326,9 @@ private: bool m_dirty; unsigned int m_pictureUsed; + // used to signal the framework we need a repaint + bool m_hasRunningAnimations; + // painting request sent bool m_requestSent; diff --git a/WebCore/platform/graphics/android/MediaLayer.cpp b/WebCore/platform/graphics/android/MediaLayer.cpp index 6c34585..40a0f11 100644 --- a/WebCore/platform/graphics/android/MediaLayer.cpp +++ b/WebCore/platform/graphics/android/MediaLayer.cpp @@ -73,7 +73,7 @@ MediaLayer::~MediaLayer() m_videoTexture->decStrong(this); } -bool MediaLayer::drawGL(SkMatrix& matrix) +bool MediaLayer::drawGL(GLWebViewState* glWebViewState, SkMatrix& matrix) { TilesManager::instance()->shader()->clip(drawClip()); @@ -112,7 +112,7 @@ bool MediaLayer::drawGL(SkMatrix& matrix) m_bufferedTexture->consumerRelease(); } - return drawChildrenGL(matrix); + return drawChildrenGL(glWebViewState, matrix); } ANativeWindow* MediaLayer::acquireNativeWindowForVideo() diff --git a/WebCore/platform/graphics/android/MediaLayer.h b/WebCore/platform/graphics/android/MediaLayer.h index 203ef93..46789cb 100644 --- a/WebCore/platform/graphics/android/MediaLayer.h +++ b/WebCore/platform/graphics/android/MediaLayer.h @@ -36,7 +36,7 @@ public: MediaLayer(const MediaLayer& layer); virtual ~MediaLayer(); - virtual bool drawGL(SkMatrix&); + virtual bool drawGL(GLWebViewState*, SkMatrix&); virtual void paintBitmapGL() const { }; virtual bool needsTexture() { return false; } diff --git a/WebCore/platform/graphics/android/VideoLayerAndroid.cpp b/WebCore/platform/graphics/android/VideoLayerAndroid.cpp index 2eced57..697281c 100644 --- a/WebCore/platform/graphics/android/VideoLayerAndroid.cpp +++ b/WebCore/platform/graphics/android/VideoLayerAndroid.cpp @@ -101,7 +101,7 @@ GLuint VideoLayerAndroid::createPauseTexture() return texture; } -bool VideoLayerAndroid::drawGL(SkMatrix& matrix) +bool VideoLayerAndroid::drawGL(GLWebViewState* glWebViewState, SkMatrix& matrix) { // Lazy allocated the paused texture. if (!m_createdPauseTexture) { @@ -127,7 +127,7 @@ bool VideoLayerAndroid::drawGL(SkMatrix& matrix) rect, m_textureId); } - return drawChildrenGL(matrix); + return drawChildrenGL(glWebViewState, matrix); } } diff --git a/WebCore/platform/graphics/android/VideoLayerAndroid.h b/WebCore/platform/graphics/android/VideoLayerAndroid.h index c2a962e..d291dda 100644 --- a/WebCore/platform/graphics/android/VideoLayerAndroid.h +++ b/WebCore/platform/graphics/android/VideoLayerAndroid.h @@ -48,7 +48,7 @@ public: virtual LayerAndroid* copy() const { return new VideoLayerAndroid(*this); } // The following 3 functions are called in UI thread only. - virtual bool drawGL(SkMatrix& matrix); + virtual bool drawGL(GLWebViewState*, SkMatrix& matrix); void setSurfaceTexture(sp<SurfaceTexture> texture, int textureName, bool updateTexture); GLuint createPauseTexture(); |