summaryrefslogtreecommitdiffstats
path: root/WebCore/platform
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 /WebCore/platform
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
Diffstat (limited to 'WebCore/platform')
-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
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();