summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Roard <nicolasroard@google.com>2011-03-15 18:20:42 -0700
committerNicolas Roard <nicolasroard@google.com>2011-03-16 23:43:46 -0700
commit9f5143f9ae49a8e5fdb7ea626c4efad66096b020 (patch)
treeb1d3eb92be0b354b8f662f50653da96c4d3cbdc8
parent8e1d10880da3108f7eb53ae81682a7c4192a2e3f (diff)
downloadexternal_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.cpp30
-rw-r--r--WebCore/platform/graphics/android/GLWebViewState.cpp55
-rw-r--r--WebCore/platform/graphics/android/GLWebViewState.h8
-rw-r--r--WebCore/platform/graphics/android/LayerAndroid.cpp31
-rw-r--r--WebCore/platform/graphics/android/LayerAndroid.h12
-rw-r--r--WebCore/platform/graphics/android/MediaLayer.cpp4
-rw-r--r--WebCore/platform/graphics/android/MediaLayer.h2
-rw-r--r--WebCore/platform/graphics/android/VideoLayerAndroid.cpp4
-rw-r--r--WebCore/platform/graphics/android/VideoLayerAndroid.h2
-rw-r--r--WebKit/android/nav/WebView.cpp36
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