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 | |
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
-rw-r--r-- | WebCore/platform/graphics/android/BaseLayerAndroid.cpp | 30 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/GLWebViewState.cpp | 55 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/GLWebViewState.h | 8 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/LayerAndroid.cpp | 31 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/LayerAndroid.h | 12 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/MediaLayer.cpp | 4 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/MediaLayer.h | 2 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/VideoLayerAndroid.cpp | 4 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/VideoLayerAndroid.h | 2 | ||||
-rw-r--r-- | WebKit/android/nav/WebView.cpp | 36 |
10 files changed, 145 insertions, 39 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(); diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp index 8cc5810..6e85873 100644 --- a/WebKit/android/nav/WebView.cpp +++ b/WebKit/android/nav/WebView.cpp @@ -428,7 +428,7 @@ void drawCursorPostamble() } } -bool drawGL(WebCore::IntRect& viewRect, float scale, int extras) +bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect, float scale, int extras) { #if USE(ACCELERATED_COMPOSITING) if (!m_baseLayer || inFullScreenMode()) @@ -499,7 +499,7 @@ bool drawGL(WebCore::IntRect& viewRect, float scale, int extras) SkRect visibleRect; calcOurContentVisibleRect(&visibleRect); - bool ret = m_glWebViewState->drawGL(viewRect, visibleRect, scale); + bool ret = m_glWebViewState->drawGL(viewRect, visibleRect, invalRect, scale); if (ret || m_glWebViewState->currentPictureCounter() != pic) return true; #endif @@ -1473,7 +1473,7 @@ private: // local state for WebView class GLDrawFunctor : Functor { public: GLDrawFunctor(WebView* _wvInstance, - bool(WebView::*_funcPtr)(WebCore::IntRect&, jfloat, jint), + bool(WebView::*_funcPtr)(WebCore::IntRect&, WebCore::IntRect*, jfloat, jint), WebCore::IntRect _viewRect, float _scale, int _extras) { wvInstance = _wvInstance; funcPtr = _funcPtr; @@ -1501,13 +1501,26 @@ class GLDrawFunctor : Functor { float dirtyBottom; }; - bool retVal = (*wvInstance.*funcPtr)(viewRect, scale, extras); + WebCore::IntRect inval; + int titlebarHeight = webViewRect.height() - viewRect.height(); + bool retVal = (*wvInstance.*funcPtr)(viewRect, &inval, scale, extras); if (retVal) { DrawConstraints* constraints = reinterpret_cast<DrawConstraints*>(data); - constraints->dirtyLeft = webViewRect.x(); - constraints->dirtyTop = webViewRect.y(); - constraints->dirtyRight = webViewRect.right(); - constraints->dirtyBottom = webViewRect.bottom(); + IntRect finalInval; + if (inval.isEmpty()) { + finalInval = webViewRect; + retVal = false; + } else { + finalInval.setX(webViewRect.x() + inval.x()); + finalInval.setY(webViewRect.y() + inval.y() + titlebarHeight); + finalInval.setWidth(inval.width()); + finalInval.setHeight(inval.height()); + finalInval.intersect(webViewRect); + } + constraints->dirtyLeft = finalInval.x(); + constraints->dirtyTop = finalInval.y(); + constraints->dirtyRight = finalInval.right(); + constraints->dirtyBottom = finalInval.bottom(); } // return 1 if invalidation needed, 0 otherwise return retVal ? 1 : 0; @@ -1520,7 +1533,7 @@ class GLDrawFunctor : Functor { } private: WebView* wvInstance; - bool (WebView::*funcPtr)(WebCore::IntRect&, float, int); + bool (WebView::*funcPtr)(WebCore::IntRect&, WebCore::IntRect*, float, int); WebCore::IntRect viewRect; WebCore::IntRect webViewRect; jfloat scale; @@ -1805,13 +1818,14 @@ static bool nativeDrawGL(JNIEnv *env, jobject obj, jobject jrect, jfloat scale, jint extras) { WebCore::IntRect viewRect = jrect_to_webrect(env, jrect); - return GET_NATIVE_VIEW(env, obj)->drawGL(viewRect, scale, extras); + WebCore::IntRect invalRect; + return GET_NATIVE_VIEW(env, obj)->drawGL(viewRect, &invalRect, scale, extras); } static bool nativeEvaluateLayersAnimations(JNIEnv *env, jobject obj) { #if USE(ACCELERATED_COMPOSITING) - const LayerAndroid* root = GET_NATIVE_VIEW(env, obj)->compositeRoot(); + LayerAndroid* root = GET_NATIVE_VIEW(env, obj)->compositeRoot(); if (root) return root->evaluateAnimations(); #endif |