summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Reck <jreck@google.com>2012-08-17 18:18:00 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-08-17 18:18:00 -0700
commitd4389e24221d2c1c202990256f138c75effaa41b (patch)
tree790bd4babf4315453c1c60bafa369156a6b6b50f
parent1bf7d7a2d1abb6e625e3bc7168c7cf3ced009ea7 (diff)
parentd38abfbac01ae23acad018d42382d604a45bc005 (diff)
downloadexternal_webkit-d4389e24221d2c1c202990256f138c75effaa41b.zip
external_webkit-d4389e24221d2c1c202990256f138c75effaa41b.tar.gz
external_webkit-d4389e24221d2c1c202990256f138c75effaa41b.tar.bz2
Merge "Support partial invals on layers" into jb-mr1-dev
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp49
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h9
-rw-r--r--Source/WebKit/android/jni/PicturePile.cpp38
-rw-r--r--Source/WebKit/android/jni/PicturePile.h2
4 files changed, 39 insertions, 59 deletions
diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
index 7f4352b..9cb81e6 100644
--- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
@@ -116,7 +116,6 @@ GraphicsLayerAndroid::GraphicsLayerAndroid(GraphicsLayerClient* client) :
static_cast<HTMLCanvasElement*>(renderLayer->renderer()->node()));
} else
m_contentLayer = new LayerAndroid(renderLayer);
- m_dirtyRegion.setEmpty();
gDebugGraphicsLayerAndroidInstances++;
}
@@ -695,7 +694,7 @@ bool GraphicsLayerAndroid::repaint()
PaintingPhase phase(this);
// Paint the background into a separate context.
phase.set(GraphicsLayerPaintBackground);
- if (!paintContext(m_contentLayer, layerBounds))
+ if (!paintContext(m_contentLayer, m_contentLayerContent))
return false;
// Construct the foreground layer and draw.
@@ -712,11 +711,17 @@ bool GraphicsLayerAndroid::repaint()
// Paint everything else into the main recording canvas.
phase.clear(GraphicsLayerPaintBackground);
+ // Invalidate the entire layer for now, as webkit will only send the
+ // setNeedsDisplayInRect() for the visible (clipped) scrollable area,
+ // offsetting the invals by the scroll position would not be enough.
+ // TODO: have webkit send us invals even for non visible area
+ m_foregroundLayerContent.invalidate(IntRect(0, 0, contentsRect.width(), contentsRect.height()));
+
// Paint at 0,0.
IntSize scroll = layer->scrolledContentOffset();
layer->scrollToOffset(0, 0);
// At this point, it doesn't matter if painting failed.
- (void) paintContext(m_foregroundLayer, contentsRect);
+ (void) paintContext(m_foregroundLayer, m_foregroundLayerContent);
layer->scrollToOffset(scroll.width(), scroll.height());
// Construct the clip layer for masking the contents.
@@ -741,13 +746,8 @@ bool GraphicsLayerAndroid::repaint()
// Set the scrollable bounds of the layer.
setScrollLimits(static_cast<ScrollableLayerAndroid*>(m_foregroundLayer), layer);
- // Invalidate the entire layer for now, as webkit will only send the
- // setNeedsDisplayInRect() for the visible (clipped) scrollable area,
- // offsetting the invals by the scroll position would not be enough.
- // TODO: have webkit send us invals even for non visible area
- SkRegion region;
- region.setRect(0, 0, contentsRect.width(), contentsRect.height());
- m_foregroundLayer->markAsDirty(region);
+ m_foregroundLayer->markAsDirty(m_foregroundLayerContent.dirtyRegion());
+ m_foregroundLayerContent.dirtyRegion().setEmpty();
} else if (m_contentLayer->isFixedBackground()) {
SkPicture* picture = new SkPicture();
SkCanvas* canvas = picture->beginRecording(layerBounds.width(),
@@ -784,13 +784,13 @@ bool GraphicsLayerAndroid::repaint()
GraphicsLayerAndroid* replicatedLayer = static_cast<GraphicsLayerAndroid*>(replicaLayer());
if (replicatedLayer->maskLayer()) {
GraphicsLayerAndroid* mask = static_cast<GraphicsLayerAndroid*>(replicatedLayer->maskLayer());
- mask->paintContext(mask->m_contentLayer, layerBounds, false);
+ mask->paintContext(mask->m_contentLayer, m_contentLayerContent);
}
}
// If there is no contents clip, we can draw everything into one
// picture.
- bool painting = paintContext(m_contentLayer, layerBounds);
+ bool painting = paintContext(m_contentLayer, m_contentLayerContent);
if (!painting)
return false;
// Check for a scrollable iframe and report the scrolling
@@ -811,8 +811,8 @@ bool GraphicsLayerAndroid::repaint()
m_contentLayer->getSize().width(),
m_contentLayer->getSize().height());
- m_contentLayer->markAsDirty(m_dirtyRegion);
- m_dirtyRegion.setEmpty();
+ m_contentLayer->markAsDirty(m_contentLayerContent.dirtyRegion());
+ m_contentLayerContent.dirtyRegion().setEmpty();
m_needsRepaint = false;
return true;
@@ -820,8 +820,8 @@ bool GraphicsLayerAndroid::repaint()
if (m_needsRepaint && m_image && m_newImage) {
// We need to tell the GL thread that we will need to repaint the
// texture. Only do so if we effectively have a new image!
- m_contentLayer->markAsDirty(m_dirtyRegion);
- m_dirtyRegion.setEmpty();
+ m_contentLayer->markAsDirty(m_contentLayerContent.dirtyRegion());
+ m_contentLayerContent.dirtyRegion().setEmpty();
m_newImage = false;
m_needsRepaint = false;
return true;
@@ -835,19 +835,14 @@ void GraphicsLayerAndroid::paintContents(GraphicsContext* gc, IntRect& dirty)
}
bool GraphicsLayerAndroid::paintContext(LayerAndroid* layer,
- const IntRect& rect,
- bool checkOptimisations)
+ PicturePile& picture)
{
if (!layer)
return false;
TRACE_METHOD();
- // TODO: we might be able to reuse an existing picture instead of recreating it.
- // we can't do that because of transparency -- for now, we just create
- // a new picture every time.
- WebCore::PicturePile picture;
- picture.setSize(IntSize(rect.width(), rect.height()));
+ picture.setSize(IntSize(layer->getWidth(), layer->getHeight()));
// TODO: add content checks (text, opacity, etc.)
picture.updatePicturesIfNeeded(this);
@@ -870,11 +865,9 @@ void GraphicsLayerAndroid::setNeedsDisplayInRect(const FloatRect& rect)
return;
}
- SkRegion region;
- region.setRect(rect.x(), rect.y(),
- rect.x() + rect.width(),
- rect.y() + rect.height());
- m_dirtyRegion.op(region, SkRegion::kUnion_Op);
+ m_contentLayerContent.invalidate(enclosingIntRect(rect));
+ if (m_foregroundLayer)
+ m_foregroundLayerContent.invalidate(enclosingIntRect(rect));
m_needsRepaint = true;
askForSync();
diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
index b40459d..28d4b09 100644
--- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
@@ -154,9 +154,7 @@ private:
bool repaint();
void needsNotifyClient();
- bool paintContext(LayerAndroid* layer,
- const IntRect& rect,
- bool checkOptimisations = true);
+ bool paintContext(LayerAndroid* layer, PicturePile& picture);
bool m_needsSyncChildren;
bool m_needsSyncMask;
@@ -167,12 +165,13 @@ private:
bool m_newImage;
Image* m_image;
- SkRegion m_dirtyRegion;
-
LayerAndroid* m_contentLayer;
FixedBackgroundImageLayerAndroid* m_fixedBackgroundLayer;
LayerAndroid* m_foregroundLayer;
LayerAndroid* m_foregroundClipLayer;
+
+ PicturePile m_contentLayerContent;
+ PicturePile m_foregroundLayerContent;
};
} // namespace WebCore
diff --git a/Source/WebKit/android/jni/PicturePile.cpp b/Source/WebKit/android/jni/PicturePile.cpp
index 91f3e74..f995e92 100644
--- a/Source/WebKit/android/jni/PicturePile.cpp
+++ b/Source/WebKit/android/jni/PicturePile.cpp
@@ -55,16 +55,6 @@ static SkIRect toSkIRect(const IntRect& rect) {
return SkIRect::MakeXYWH(rect.x(), rect.y(), rect.width(), rect.height());
}
-static IntRect extractClipBounds(SkCanvas* canvas, const IntSize& size) {
- SkRect clip;
- if (!canvas->getClipBounds(&clip)) {
- ALOGW("Empty clip!");
- return IntRect();
- }
- clip.intersect(0, 0, size.width(), size.height());
- return enclosingIntRect(clip);
-}
-
PictureContainer::PictureContainer(const PictureContainer& other)
: picture(other.picture)
, area(other.area)
@@ -94,11 +84,10 @@ void PicturePile::draw(SkCanvas* canvas)
* the rect bounds of the SkRegion for the clip, so this still can't be
* used for translucent surfaces
*/
- IntRect clipBounds = extractClipBounds(canvas, m_size);
- if (clipBounds.isEmpty())
+ if (canvas->quickReject(SkRect::MakeWH(m_size.width(), m_size.height()),
+ SkCanvas::kBW_EdgeType))
return;
- SkRegion clipRegion(toSkIRect(clipBounds));
- drawWithClipRecursive(canvas, clipRegion, m_pile.size() - 1);
+ drawWithClipRecursive(canvas, m_pile.size() - 1);
}
void PicturePile::clearPrerenders()
@@ -107,24 +96,23 @@ void PicturePile::clearPrerenders()
m_pile[i].prerendered.clear();
}
-void PicturePile::drawWithClipRecursive(SkCanvas* canvas, SkRegion& clipRegion,
- int index)
+void PicturePile::drawWithClipRecursive(SkCanvas* canvas, int index)
{
// TODO: Add some debug visualizations of this
- if (index < 0 || clipRegion.isEmpty())
+ if (index < 0)
return;
PictureContainer& pc = m_pile[index];
- IntRect intersection = clipRegion.getBounds();
- intersection.intersect(pc.area);
- if (pc.picture && !intersection.isEmpty()) {
- clipRegion.op(intersection, SkRegion::kDifference_Op);
- drawWithClipRecursive(canvas, clipRegion, index - 1);
- int saved = canvas->save();
- if (canvas->clipRect(intersection))
+ if (pc.picture && !canvas->quickReject(pc.area, SkCanvas::kBW_EdgeType)) {
+ int saved = canvas->save(SkCanvas::kClip_SaveFlag);
+ if (canvas->clipRect(pc.area, SkRegion::kDifference_Op))
+ drawWithClipRecursive(canvas, index - 1);
+ canvas->restoreToCount(saved);
+ saved = canvas->save(SkCanvas::kClip_SaveFlag);
+ if (canvas->clipRect(pc.area))
drawPicture(canvas, pc);
canvas->restoreToCount(saved);
} else
- drawWithClipRecursive(canvas, clipRegion, index - 1);
+ drawWithClipRecursive(canvas, index - 1);
}
// Used by WebViewCore
diff --git a/Source/WebKit/android/jni/PicturePile.h b/Source/WebKit/android/jni/PicturePile.h
index 6e3e46d..1f99054 100644
--- a/Source/WebKit/android/jni/PicturePile.h
+++ b/Source/WebKit/android/jni/PicturePile.h
@@ -113,7 +113,7 @@ private:
void updatePicture(PicturePainter* painter, PictureContainer& container);
Picture* recordPicture(PicturePainter* painter, PictureContainer& container);
void appendToPile(const IntRect& inval, const IntRect& originalInval = IntRect());
- void drawWithClipRecursive(SkCanvas* canvas, SkRegion& clipRegion, int index);
+ void drawWithClipRecursive(SkCanvas* canvas, int index);
void drawPicture(SkCanvas* canvas, PictureContainer& pc);
IntSize m_size;