diff options
6 files changed, 266 insertions, 89 deletions
diff --git a/Source/WebCore/Android.mk b/Source/WebCore/Android.mk index aa8ffe6..d731082 100644 --- a/Source/WebCore/Android.mk +++ b/Source/WebCore/Android.mk @@ -659,6 +659,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ platform/graphics/android/ImageSourceAndroid.cpp \ platform/graphics/android/ImagesManager.cpp \ platform/graphics/android/ImageTexture.cpp \ + platform/graphics/android/InspectorCanvas.cpp \ platform/graphics/android/Layer.cpp \ platform/graphics/android/LayerAndroid.cpp \ platform/graphics/android/MediaLayer.cpp \ diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp index ef74521..80819cc 100644 --- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp @@ -573,7 +573,7 @@ bool GraphicsLayerAndroid::repaint() phase.set(GraphicsLayerPaintBackground); if (!paintContext(m_contentLayer->recordContext(), layerBounds)) return false; - m_contentLayer->checkTextPresence(); + m_contentLayer->checkForPictureOptimizations(); // Construct the foreground layer and draw. RenderBox* box = layer->renderBox(); @@ -592,7 +592,7 @@ bool GraphicsLayerAndroid::repaint() layer->scrollToOffset(0, 0); // At this point, it doesn't matter if painting failed. (void) paintContext(m_foregroundLayer->recordContext(), contentsRect); - m_foregroundLayer->checkTextPresence(); + m_foregroundLayer->checkForPictureOptimizations(); layer->scrollToOffset(scroll.width(), scroll.height()); // Construct the clip layer for masking the contents. @@ -625,7 +625,7 @@ bool GraphicsLayerAndroid::repaint() // picture. if (!paintContext(m_contentLayer->recordContext(), layerBounds)) return false; - m_contentLayer->checkTextPresence(); + m_contentLayer->checkForPictureOptimizations(); // Check for a scrollable iframe and report the scrolling // limits based on the view size. if (m_contentLayer->contentIsScrollable()) { diff --git a/Source/WebCore/platform/graphics/android/InspectorCanvas.cpp b/Source/WebCore/platform/graphics/android/InspectorCanvas.cpp new file mode 100644 index 0000000..0137cec --- /dev/null +++ b/Source/WebCore/platform/graphics/android/InspectorCanvas.cpp @@ -0,0 +1,149 @@ +/* + * Copyright 2011, 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. + */ + +#include "config.h" +#include "InspectorCanvas.h" + +#include "SkPicture.h" + +#include <cutils/log.h> +#include <wtf/CurrentTime.h> +#include <wtf/text/CString.h> + +#undef XLOGC +#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "InspectorCanvas", __VA_ARGS__) + +#ifdef DEBUG + +#undef XLOG +#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "InspectorCanvas", __VA_ARGS__) + +#else + +#undef XLOG +#define XLOG(...) + +#endif // DEBUG + + +namespace WebCore { + + +void InspectorCanvas::setHasText() +{ + m_hasText = true; + setHasContent(); +} + +void InspectorCanvas::setHasContent() +{ + m_hasContent = true; + if (m_hasText) { + // has text. Have to paint properly, so no further + // information is useful + m_picture->abortPlayback(); + } +} + +void InspectorCanvas::setIsBackground(const SkPaint& paint) +{ + // TODO: if the paint is a solid color, opaque, and the last instruction in + // the picture, replace the picture with simple draw rect info + setHasContent(); +} + +void InspectorCanvas::commonDrawBitmap(const SkBitmap& bitmap, + const SkIRect* rect, + const SkMatrix&, + const SkPaint&) +{ + setHasContent(); +} + +void InspectorCanvas::drawPaint(const SkPaint& paint) +{ + setHasContent(); +} + +void InspectorCanvas::drawPath(const SkPath&, const SkPaint& paint) +{ + setHasContent(); +} +void InspectorCanvas::drawPoints(PointMode, size_t, + const SkPoint [], const SkPaint& paint) +{ + setHasContent(); +} + +void InspectorCanvas::drawRect(const SkRect& rect, const SkPaint& paint) +{ + if (rect.fLeft == 0 + && rect.fTop == 0 + && rect.width() >= m_picture->width() + && rect.height() >= m_picture->height()) { + // rect same size as canvas, treat layer as a single color rect until + // more content is drawn + setIsBackground(paint); + } else { + // regular rect drawing path + setHasContent(); + } + XLOG("draw rect at %f %f, size %f %f, picture size %d %d", + rect.fLeft, rect.fTop, rect.width(), rect.height(), + m_picture->width(), m_picture->height()); +} +void InspectorCanvas::drawSprite(const SkBitmap& , int , int , + const SkPaint* paint) +{ + setHasContent(); +} + +void InspectorCanvas::drawText(const void*, size_t byteLength, SkScalar, + SkScalar, const SkPaint& paint) +{ + setHasText(); +} + +void InspectorCanvas::drawPosText(const void* , size_t byteLength, + const SkPoint [], const SkPaint& paint) +{ + setHasText(); +} + +void InspectorCanvas::drawPosTextH(const void*, size_t byteLength, + const SkScalar [], SkScalar, + const SkPaint& paint) +{ + setHasText(); +} + +void InspectorCanvas::drawTextOnPath(const void*, size_t byteLength, + const SkPath&, const SkMatrix*, + const SkPaint& paint) +{ + setHasText(); +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/InspectorCanvas.h b/Source/WebCore/platform/graphics/android/InspectorCanvas.h new file mode 100644 index 0000000..415a579 --- /dev/null +++ b/Source/WebCore/platform/graphics/android/InspectorCanvas.h @@ -0,0 +1,102 @@ +/* + * Copyright 2011, 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 InspectorCanvas_h +#define InspectorCanvas_h + +#include "SkBounder.h" +#include "SkCanvas.h" + +namespace WebCore { + +class InspectorBounder : public SkBounder { + virtual bool onIRect(const SkIRect& rect) + { + return false; + } +}; + +class InspectorCanvas : public SkCanvas { +public: + InspectorCanvas(SkBounder* bounder, SkPicture* picture) + : m_picture(picture) + , m_hasText(false) + , m_hasContent(false) + { + setBounder(bounder); + } + + bool hasText() {return m_hasText;} + bool hasContent() {return m_hasContent;} + + virtual bool clipPath(const SkPath&, SkRegion::Op) { + return true; + } + + virtual void commonDrawBitmap(const SkBitmap& bitmap, + const SkIRect* rect, + const SkMatrix&, + const SkPaint&); + + virtual void drawPaint(const SkPaint& paint); + virtual void drawPath(const SkPath&, const SkPaint& paint); + virtual void drawPoints(PointMode, size_t, + const SkPoint [], const SkPaint& paint); + + virtual void drawRect(const SkRect& , const SkPaint& paint); + virtual void drawSprite(const SkBitmap& , int , int , + const SkPaint* paint = NULL); + + virtual void drawText(const void*, size_t byteLength, SkScalar, + SkScalar, const SkPaint& paint); + virtual void drawPosText(const void* , size_t byteLength, + const SkPoint [], const SkPaint& paint); + virtual void drawPosTextH(const void*, size_t byteLength, + const SkScalar [], SkScalar, + const SkPaint& paint); + virtual void drawTextOnPath(const void*, size_t byteLength, + const SkPath&, const SkMatrix*, + const SkPaint& paint); + +private: + + // vector instructions exist, must repaint at any scale + void setHasText(); + + // painting is required + void setHasContent(); + + // rect covering entire content, don't need to use a texture if nothing else + // is painted + void setIsBackground(const SkPaint& paint); + + SkPicture* m_picture; + bool m_hasText; + bool m_hasContent; +}; + +} // namespace WebCore + +#endif // InspectorCanvas_h diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp index 962bcdf..25c5e7b 100644 --- a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp @@ -8,11 +8,11 @@ #include "DrawExtra.h" #include "GLUtils.h" #include "ImagesManager.h" +#include "InspectorCanvas.h" #include "MediaLayer.h" #include "PaintedSurface.h" #include "ParseCanvas.h" #include "SkBitmapRef.h" -#include "SkBounder.h" #include "SkDrawFilter.h" #include "SkPaint.h" #include "SkPicture.h" @@ -55,87 +55,6 @@ private: int m_opacity; }; -class HasTextBounder : public SkBounder { - virtual bool onIRect(const SkIRect& rect) - { - return false; - } -}; - -class HasTextCanvas : public SkCanvas { -public: - HasTextCanvas(SkBounder* bounder, SkPicture* picture) - : m_picture(picture) - , m_hasText(false) - { - setBounder(bounder); - } - - void setHasText() - { - m_hasText = true; - m_picture->abortPlayback(); - } - - bool hasText() - { - return m_hasText; - } - - virtual bool clipPath(const SkPath&, SkRegion::Op) { - return true; - } - - virtual void commonDrawBitmap(const SkBitmap& bitmap, - const SkIRect* rect, - const SkMatrix&, - const SkPaint&) {} - - virtual void drawPaint(const SkPaint& paint) {} - virtual void drawPath(const SkPath&, const SkPaint& paint) {} - virtual void drawPoints(PointMode, size_t, - const SkPoint [], const SkPaint& paint) {} - - virtual void drawRect(const SkRect& , const SkPaint& paint) {} - virtual void drawSprite(const SkBitmap& , int , int , - const SkPaint* paint = NULL) {} - - virtual void drawText(const void*, size_t byteLength, SkScalar, - SkScalar, const SkPaint& paint) - { - setHasText(); - } - - virtual void drawPosText(const void* , size_t byteLength, - const SkPoint [], const SkPaint& paint) - { - setHasText(); - } - - virtual void drawPosTextH(const void*, size_t byteLength, - const SkScalar [], SkScalar, - const SkPaint& paint) - { - setHasText(); - } - - virtual void drawTextOnPath(const void*, size_t byteLength, - const SkPath&, const SkMatrix*, - const SkPaint& paint) - { - setHasText(); - } - - virtual void drawPicture(SkPicture& picture) { - SkCanvas::drawPicture(picture); - } - -private: - - SkPicture* m_picture; - bool m_hasText; -}; - /////////////////////////////////////////////////////////////////////////////// LayerAndroid::LayerAndroid(RenderLayer* owner) : Layer(), @@ -226,13 +145,13 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer), #endif } -void LayerAndroid::checkTextPresence() +void LayerAndroid::checkForPictureOptimizations() { if (m_recordingPicture) { // Let's check if we have text or not. If we don't, we can limit // ourselves to scale 1! - HasTextBounder hasTextBounder; - HasTextCanvas checker(&hasTextBounder, m_recordingPicture); + InspectorBounder inspectorBounder; + InspectorCanvas checker(&inspectorBounder, m_recordingPicture); SkBitmap bitmap; bitmap.setConfig(SkBitmap::kARGB_8888_Config, m_recordingPicture->width(), @@ -240,6 +159,12 @@ void LayerAndroid::checkTextPresence() checker.setBitmapDevice(bitmap); checker.drawPicture(*m_recordingPicture); m_hasText = checker.hasText(); + if (!checker.hasContent()) { + // no content to draw, discard picture so UI / tile generation + // doesn't bother with it + SkSafeUnref(m_recordingPicture); + m_recordingPicture = 0; + } } } diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.h b/Source/WebCore/platform/graphics/android/LayerAndroid.h index c1f1bc9..d6e1e9a 100644 --- a/Source/WebCore/platform/graphics/android/LayerAndroid.h +++ b/Source/WebCore/platform/graphics/android/LayerAndroid.h @@ -302,7 +302,7 @@ public: int type() { return m_type; } bool hasText() { return m_hasText; } - void checkTextPresence(); + void checkForPictureOptimizations(); void copyAnimationStartTimesRecursive(LayerAndroid* oldTree); |