From e859a34171f2a36877d95197d118d962078f8aa0 Mon Sep 17 00:00:00 2001 From: John Reck Date: Fri, 27 Apr 2012 08:13:38 -0700 Subject: Rewrite PictureSet with TURBO! This changes how partial invals are done by adding a hybrid mode. What we used to do is generate a SkPicture for the new area. This SkPicture would possibly be larger than the actual inval, depending on various merge rules (more SkPictures == slower to draw a tile) The new code rewrites PictureSet entirely, preserving many of the old rules but cleans up the code and adds the concept of a "PrerenderedInval". This is a partial inval that WebKit has rasterized. By having WebKit produce both a SkPicture and a SkBitmap, we avoid needing to play back the picture and avoid overdrawing. We take this SkBitmap, and simply update the front textures with it. This gives us full partial invals through the entire system without hitting any driver bugs, and with minimal copies. And while the SkPicture may be larger than the inval, the SkBitmap that is rasterized is not - it matches the area webkit has said is dirty. Change-Id: Ieb7ecc9db0d4f679102fda004a43399f9b319ebc --- .../graphics/android/layers/LayerAndroid.cpp | 15 ++++++ .../graphics/android/layers/LayerAndroid.h | 3 ++ .../graphics/android/layers/LayerContent.h | 7 ++- .../android/layers/PicturePileLayerContent.cpp | 41 +++++++++++++++ .../android/layers/PicturePileLayerContent.h | 53 ++++++++++++++++++++ .../android/layers/PictureSetLayerContent.cpp | 41 --------------- .../android/layers/PictureSetLayerContent.h | 53 -------------------- .../graphics/android/layers/PrerenderedInval.h | 58 ++++++++++++++++++++++ 8 files changed, 176 insertions(+), 95 deletions(-) create mode 100644 Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.cpp create mode 100644 Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.h delete mode 100644 Source/WebCore/platform/graphics/android/layers/PictureSetLayerContent.cpp delete mode 100644 Source/WebCore/platform/graphics/android/layers/PictureSetLayerContent.h create mode 100644 Source/WebCore/platform/graphics/android/layers/PrerenderedInval.h (limited to 'Source/WebCore/platform/graphics/android/layers') diff --git a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp index 69c597f..535d211 100644 --- a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp @@ -20,6 +20,7 @@ #include "MediaLayer.h" #include "ParseCanvas.h" #include "PictureLayerContent.h" +#include "PrerenderedInval.h" #include "SkBitmapRef.h" #include "SkDrawFilter.h" #include "SkPaint.h" @@ -524,6 +525,20 @@ void LayerAndroid::setContent(LayerContent* content) m_content = content; } +bool LayerAndroid::canUpdateWithBlit() +{ + if (!m_content || !m_scale) + return false; + PrerenderedInval* prerendered = m_content->prerenderForRect(m_dirtyRegion.getBounds()); + if (!prerendered) + return false; + // Check that the scales are "close enough" to produce the same rects + FloatRect screenArea = prerendered->screenArea; + screenArea.scale(1 / m_scale); + IntRect enclosingDocArea = enclosingIntRect(screenArea); + return enclosingDocArea == prerendered->area; +} + bool LayerAndroid::needsTexture() { return m_content && !m_content->isEmpty(); diff --git a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h index 4f94698..ca833f7 100644 --- a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h +++ b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h @@ -185,6 +185,9 @@ public: LayerContent* content() { return m_content; } void setContent(LayerContent* content); + // Check to see if the dirty area of this layer can be updated with a blit + // from the prerender instead of needing to generate tiles from the LayerContent + bool canUpdateWithBlit(); void addAnimation(PassRefPtr anim); void removeAnimationsForProperty(AnimatedPropertyID property); diff --git a/Source/WebCore/platform/graphics/android/layers/LayerContent.h b/Source/WebCore/platform/graphics/android/layers/LayerContent.h index 97bc32a..2cd90a90 100644 --- a/Source/WebCore/platform/graphics/android/layers/LayerContent.h +++ b/Source/WebCore/platform/graphics/android/layers/LayerContent.h @@ -26,6 +26,7 @@ #ifndef LayerContent_h #define LayerContent_h +#include "IntRect.h" #include "SkRefCnt.h" #include @@ -35,14 +36,18 @@ class SkWStream; namespace WebCore { +class PrerenderedInval; + class LayerContent : public SkRefCnt { public: virtual int width() = 0; virtual int height() = 0; - virtual bool isEmpty() = 0; + virtual bool isEmpty() { return !width() || !height(); } virtual void checkForOptimisations() = 0; virtual bool hasText() = 0; virtual void draw(SkCanvas* canvas) = 0; + virtual PrerenderedInval* prerenderForRect(const IntRect& dirty) { return 0; } + virtual void clearPrerenders() { }; virtual void serialize(SkWStream* stream) = 0; diff --git a/Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.cpp b/Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.cpp new file mode 100644 index 0000000..b648e72 --- /dev/null +++ b/Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.cpp @@ -0,0 +1,41 @@ +#include "config.h" +#include "PicturePileLayerContent.h" + +#include "SkCanvas.h" +#include "SkPicture.h" + +namespace WebCore { + +PicturePileLayerContent::PicturePileLayerContent(const PicturePile& picturePile) + : m_picturePile(picturePile) +{ +} + +void PicturePileLayerContent::draw(SkCanvas* canvas) +{ + android::Mutex::Autolock lock(m_drawLock); + m_picturePile.draw(canvas); +} + +void PicturePileLayerContent::serialize(SkWStream* stream) +{ + if (!stream) + return; + SkPicture picture; + draw(picture.beginRecording(width(), height(), + SkPicture::kUsePathBoundsForClip_RecordingFlag)); + picture.endRecording(); + picture.serialize(stream); +} + +PrerenderedInval* PicturePileLayerContent::prerenderForRect(const IntRect& dirty) +{ + return m_picturePile.prerenderedInvalForArea(dirty); +} + +void PicturePileLayerContent::clearPrerenders() +{ + m_picturePile.clearPrerenders(); +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.h b/Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.h new file mode 100644 index 0000000..4216617 --- /dev/null +++ b/Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.h @@ -0,0 +1,53 @@ +/* + * Copyright 2012, The Android Open Source Project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PicturePileLayerContent_h +#define PicturePileLayerContent_h + +#include "LayerContent.h" +#include "PicturePile.h" + +namespace WebCore { + +class PicturePileLayerContent : public LayerContent { +public: + PicturePileLayerContent(const PicturePile& picturePile); + + virtual int width() { return m_picturePile.size().width(); } + virtual int height() { return m_picturePile.size().height(); } + virtual void checkForOptimisations() {} + virtual bool hasText() { return true; } + virtual void draw(SkCanvas* canvas); + virtual void serialize(SkWStream* stream); + virtual PrerenderedInval* prerenderForRect(const IntRect& dirty); + virtual void clearPrerenders(); + +private: + PicturePile m_picturePile; +}; + +} // WebCore + +#endif // PicturePileLayerContent_h diff --git a/Source/WebCore/platform/graphics/android/layers/PictureSetLayerContent.cpp b/Source/WebCore/platform/graphics/android/layers/PictureSetLayerContent.cpp deleted file mode 100644 index 8b72b0a..0000000 --- a/Source/WebCore/platform/graphics/android/layers/PictureSetLayerContent.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include "config.h" -#include "PictureSetLayerContent.h" - -#include "SkCanvas.h" -#include "SkPicture.h" - -namespace WebCore { - -PictureSetLayerContent::PictureSetLayerContent(const android::PictureSet& pictureSet) -{ - m_pictureSet.set(pictureSet); -} - -PictureSetLayerContent::~PictureSetLayerContent() -{ - m_pictureSet.clear(); -} - -void PictureSetLayerContent::draw(SkCanvas* canvas) -{ - if (m_pictureSet.isEmpty()) - return; - - android::Mutex::Autolock lock(m_drawLock); - SkRect r = SkRect::MakeWH(width(), height()); - canvas->clipRect(r); - m_pictureSet.draw(canvas); -} - -void PictureSetLayerContent::serialize(SkWStream* stream) -{ - if (!stream) - return; - SkPicture picture; - draw(picture.beginRecording(m_pictureSet.width(), m_pictureSet.height(), - SkPicture::kUsePathBoundsForClip_RecordingFlag)); - picture.endRecording(); - picture.serialize(stream); -} - -} // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/layers/PictureSetLayerContent.h b/Source/WebCore/platform/graphics/android/layers/PictureSetLayerContent.h deleted file mode 100644 index 61fc3f4..0000000 --- a/Source/WebCore/platform/graphics/android/layers/PictureSetLayerContent.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2012, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef PictureSetLayerContent_h -#define PictureSetLayerContent_h - -#include "LayerContent.h" -#include "PictureSet.h" - -namespace WebCore { - -class PictureSetLayerContent : public LayerContent { -public: - PictureSetLayerContent(const android::PictureSet& pictureSet); - ~PictureSetLayerContent(); - - virtual int width() { return m_pictureSet.width(); } - virtual int height() { return m_pictureSet.height(); } - virtual bool isEmpty() { return m_pictureSet.isEmpty(); } - virtual void checkForOptimisations() {} - virtual bool hasText() { return true; } - virtual void draw(SkCanvas* canvas); - virtual void serialize(SkWStream* stream); - -private: - android::PictureSet m_pictureSet; -}; - -} // WebCore - -#endif // PictureLayerContent_h diff --git a/Source/WebCore/platform/graphics/android/layers/PrerenderedInval.h b/Source/WebCore/platform/graphics/android/layers/PrerenderedInval.h new file mode 100644 index 0000000..91f385d --- /dev/null +++ b/Source/WebCore/platform/graphics/android/layers/PrerenderedInval.h @@ -0,0 +1,58 @@ +/* + * Copyright 2012, The Android Open Source Project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PrerenderedInval_h +#define PrerenderedInval_h + +#include "IntRect.h" +#include "SkBitmap.h" + +#include +#include +#include + +namespace WebCore { + +class PrerenderedInval : public ThreadSafeRefCounted { + WTF_MAKE_NONCOPYABLE(PrerenderedInval); +public: + SkBitmap bitmap; + IntRect area; + IntRect screenArea; + + static PassRefPtr create(const IntRect& ir) + { + return adoptRef(new PrerenderedInval(ir)); + } + +private: + PrerenderedInval(const IntRect& ir) + : area(ir) + {} +}; + +} // namespace WebCore + +#endif // PrerenderedInval_h -- cgit v1.1