diff options
Diffstat (limited to 'Source/WebCore')
12 files changed, 380 insertions, 114 deletions
diff --git a/Source/WebCore/Android.mk b/Source/WebCore/Android.mk index 4884e5b..816b163 100644 --- a/Source/WebCore/Android.mk +++ b/Source/WebCore/Android.mk @@ -672,6 +672,8 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ platform/graphics/android/PaintTileOperation.cpp \ platform/graphics/android/PathAndroid.cpp \ platform/graphics/android/PatternAndroid.cpp \ + platform/graphics/android/PictureLayerContent.cpp \ + platform/graphics/android/PictureSetLayerContent.cpp \ platform/graphics/android/PlatformGraphicsContext.cpp \ platform/graphics/android/PerformanceMonitor.cpp \ platform/graphics/android/RasterRenderer.cpp \ diff --git a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp index ded25a7..c9a8b9a 100644 --- a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.cpp @@ -68,6 +68,7 @@ using namespace android; BaseLayerAndroid::BaseLayerAndroid() #if USE(ACCELERATED_COMPOSITING) : m_color(Color::white) + , m_content(0) , m_scrollState(NotScrolling) #endif { @@ -78,23 +79,17 @@ BaseLayerAndroid::BaseLayerAndroid() BaseLayerAndroid::~BaseLayerAndroid() { - m_content.clear(); + SkSafeUnref(m_content); #ifdef DEBUG_COUNT ClassTracker::instance()->decrement("BaseLayerAndroid"); #endif } -void BaseLayerAndroid::setContent(const PictureSet& src) +void BaseLayerAndroid::setContent(LayerContent* content) { -#if USE(ACCELERATED_COMPOSITING) - // FIXME: We lock here because we do not want - // to paint and change the m_content concurrently. - // We should instead refactor PictureSet to use - // an atomic refcounting scheme and use atomic operations - // to swap PictureSets. - android::Mutex::Autolock lock(m_drawLock); -#endif - m_content.set(src); + SkSafeRef(content); + SkSafeUnref(m_content); + m_content = content; // FIXME: We cannot set the size of the base layer because it will screw up // the matrix used. We need to fix matrix computation for the base layer // and then we can set the size. @@ -103,11 +98,9 @@ void BaseLayerAndroid::setContent(const PictureSet& src) bool BaseLayerAndroid::drawCanvas(SkCanvas* canvas) { -#if USE(ACCELERATED_COMPOSITING) android::Mutex::Autolock lock(m_drawLock); -#endif - if (!m_content.isEmpty()) - m_content.draw(canvas); + if (m_content && !m_content->isEmpty()) + m_content->draw(canvas); return true; } diff --git a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.h b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.h index e7d0471..a807b8b 100644 --- a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.h +++ b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.h @@ -29,6 +29,7 @@ #include "Color.h" #include "Layer.h" #include "PictureSet.h" +#include "LayerContent.h" namespace WebCore { @@ -50,8 +51,9 @@ public: void setBackgroundColor(Color& color) { m_color = color; } Color getBackgroundColor() { return m_color; } #endif - void setContent(const android::PictureSet& src); - android::PictureSet* content() { return &m_content; } + void setContent(LayerContent* content); + LayerContent* content() { return m_content; } + // This method will paint using the current PictureSet onto // the passed canvas. We used it to paint the GL tiles as well as // WebView::copyBaseContentToPicture(), so a lock is necessary as @@ -78,7 +80,7 @@ private: android::Mutex m_drawLock; Color m_color; #endif - android::PictureSet m_content; + LayerContent* m_content; ScrollState m_scrollState; }; diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp index c6a69b7..6bc2dc7 100644 --- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp @@ -31,6 +31,7 @@ #include "Layer.h" #include "Length.h" #include "MediaLayer.h" +#include "PictureLayerContent.h" #include "PlatformBridge.h" #include "PlatformGraphicsContext.h" #include "RenderLayerBacking.h" @@ -603,9 +604,8 @@ bool GraphicsLayerAndroid::repaint() PaintingPhase phase(this); // Paint the background into a separate context. phase.set(GraphicsLayerPaintBackground); - if (!paintContext(m_contentLayer->recordContext(), layerBounds)) + if (!paintContext(m_contentLayer, layerBounds)) return false; - m_contentLayer->checkForPictureOptimizations(); // Construct the foreground layer and draw. RenderBox* box = layer->renderBox(); @@ -625,8 +625,7 @@ bool GraphicsLayerAndroid::repaint() IntSize scroll = layer->scrolledContentOffset(); layer->scrollToOffset(0, 0); // At this point, it doesn't matter if painting failed. - (void) paintContext(m_foregroundLayer->recordContext(), contentsRect); - m_foregroundLayer->checkForPictureOptimizations(); + (void) paintContext(m_foregroundLayer, contentsRect); layer->scrollToOffset(scroll.width(), scroll.height()); // Construct the clip layer for masking the contents. @@ -661,11 +660,9 @@ bool GraphicsLayerAndroid::repaint() } else { // If there is no contents clip, we can draw everything into one // picture. - bool painting = paintContext(m_contentLayer->recordContext(), layerBounds); + bool painting = paintContext(m_contentLayer, layerBounds); if (!painting) return false; - // We painted new content - m_contentLayer->checkForPictureOptimizations(); // Check for a scrollable iframe and report the scrolling // limits based on the view size. if (m_contentLayer->isIFrameContent()) { @@ -703,19 +700,32 @@ bool GraphicsLayerAndroid::repaint() return false; } -bool GraphicsLayerAndroid::paintContext(SkPicture* context, +bool GraphicsLayerAndroid::paintContext(LayerAndroid* layer, const IntRect& rect) { - SkAutoPictureRecord arp(context, rect.width(), rect.height()); - SkCanvas* canvas = arp.getRecordingCanvas(); + if (!layer) + return false; - if (!canvas) + SkPicture* picture = new SkPicture(); + SkCanvas* canvas = picture->beginRecording(rect.width(), rect.height(), 0); + if (!canvas) { + picture->endRecording(); + SkSafeUnref(picture); return false; + } PlatformGraphicsContext platformContext(canvas); GraphicsContext graphicsContext(&platformContext); paintGraphicsLayerContents(graphicsContext, rect); + + picture->endRecording(); + + PictureLayerContent* layerContent = new PictureLayerContent(picture); + layerContent->checkForOptimisations(); + layer->setContent(layerContent); + SkSafeUnref(layerContent); + SkSafeUnref(picture); return true; } diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h index 4c049cd..1eb77d6 100644 --- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h +++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h @@ -24,6 +24,7 @@ #include "GraphicsLayer.h" #include "GraphicsLayerClient.h" #include "LayerAndroid.h" +#include "LayerContent.h" #include "RefPtr.h" #include "ScrollableLayerAndroid.h" #include "SkBitmapRef.h" @@ -143,7 +144,7 @@ private: bool repaint(); void needsNotifyClient(); - bool paintContext(SkPicture* context, const IntRect& rect); + bool paintContext(LayerAndroid* layer, const IntRect& rect); bool m_needsSyncChildren; bool m_needsSyncMask; diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp index cef3d1c..7886d7b 100644 --- a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp @@ -11,9 +11,11 @@ #include "GLUtils.h" #include "ImagesManager.h" #include "InspectorCanvas.h" +#include "LayerContent.h" #include "LayerGroup.h" #include "MediaLayer.h" #include "ParseCanvas.h" +#include "PictureLayerContent.h" #include "SkBitmapRef.h" #include "SkDrawFilter.h" #include "SkPaint.h" @@ -72,15 +74,14 @@ LayerAndroid::LayerAndroid(RenderLayer* owner) : Layer(), m_preserves3D(false), m_anchorPointZ(0), m_fixedPosition(0), - m_recordingPicture(0), m_zValue(0), m_uniqueId(++gUniqueId), + m_content(0), m_imageCRC(0), m_scale(1), m_lastComputeTextureSize(0), m_owningLayer(owner), m_type(LayerAndroid::WebCoreLayer), - m_hasText(true), m_intrinsicallyComposited(true), m_layerGroup(0) { @@ -101,7 +102,6 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer), m_uniqueId(layer.m_uniqueId), m_owningLayer(layer.m_owningLayer), m_type(LayerAndroid::UILayer), - m_hasText(layer.m_hasText), m_intrinsicallyComposited(layer.m_intrinsicallyComposited), m_layerGroup(0) { @@ -115,8 +115,9 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer), m_backgroundColor = layer.m_backgroundColor; m_offset = layer.m_offset; - m_recordingPicture = layer.m_recordingPicture; - SkSafeRef(m_recordingPicture); + + m_content = layer.m_content; + SkSafeRef(m_content); m_preserves3D = layer.m_preserves3D; m_anchorPointZ = layer.m_anchorPointZ; @@ -146,33 +147,9 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer), #endif } -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! - InspectorBounder inspectorBounder; - InspectorCanvas checker(&inspectorBounder, m_recordingPicture); - SkBitmap bitmap; - bitmap.setConfig(SkBitmap::kARGB_8888_Config, - m_recordingPicture->width(), - m_recordingPicture->height()); - 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; - } - } -} - LayerAndroid::LayerAndroid(SkPicture* picture) : Layer(), m_haveClip(false), m_fixedPosition(0), - m_recordingPicture(picture), m_zValue(0), m_uniqueId(++gUniqueId), m_imageCRC(0), @@ -180,12 +157,11 @@ LayerAndroid::LayerAndroid(SkPicture* picture) : Layer(), m_lastComputeTextureSize(0), m_owningLayer(0), m_type(LayerAndroid::NavCacheLayer), - m_hasText(true), m_intrinsicallyComposited(true), m_layerGroup(0) { m_backgroundColor = 0; - SkSafeRef(m_recordingPicture); + m_content = new PictureLayerContent(picture); m_dirtyRegion.setEmpty(); #ifdef DEBUG_COUNT ClassTracker::instance()->increment("LayerAndroid - from picture"); @@ -200,7 +176,7 @@ LayerAndroid::~LayerAndroid() if (m_fixedPosition) delete m_fixedPosition; - SkSafeUnref(m_recordingPicture); + SkSafeUnref(m_content); // Don't unref m_layerGroup, owned by BaseLayerAndroid m_animations.clear(); #ifdef DEBUG_COUNT @@ -214,6 +190,11 @@ LayerAndroid::~LayerAndroid() #endif } +bool LayerAndroid::hasText() +{ + return m_content && m_content->hasText(); +} + static int gDebugNbAnims = 0; bool LayerAndroid::evaluateAnimations() @@ -381,7 +362,7 @@ void LayerAndroid::clipInner(SkTDArray<SkRect>* region, localBounds.intersect(local); if (localBounds.isEmpty()) return; - if (m_recordingPicture && boundsIsUnique(*region, localBounds)) + if (m_content && boundsIsUnique(*region, localBounds)) *region->append() = localBounds; for (int i = 0; i < countChildren(); i++) getChild(i)->clipInner(region, m_haveClip ? localBounds : local); @@ -536,10 +517,16 @@ void LayerAndroid::setContentsImage(SkBitmapRef* img) m_imageCRC = image ? image->imageCRC() : 0; } +void LayerAndroid::setContent(LayerContent* content) +{ + SkSafeRef(content); + SkSafeUnref(m_content); + m_content = content; +} + bool LayerAndroid::needsTexture() { - return (m_recordingPicture - && m_recordingPicture->width() && m_recordingPicture->height()); + return m_content && !m_content->isEmpty(); } IntRect LayerAndroid::clippedRect() const @@ -592,7 +579,7 @@ void LayerAndroid::showLayer(int indent) IntRect clip(m_clippingRect.x(), m_clippingRect.y(), m_clippingRect.width(), m_clippingRect.height()); XLOGC("%s %s (%d) [%d:0x%x] - %s %s - area (%d, %d, %d, %d) - visible (%d, %d, %d, %d) " - "clip (%d, %d, %d, %d) %s %s prepareContext(%x), pic w: %d h: %d", + "clip (%d, %d, %d, %d) %s %s m_content(%x), pic w: %d h: %d", spaces, subclassName().latin1().data(), subclassType(), uniqueId(), m_owningLayer, needsTexture() ? "needs a texture" : "no texture", m_imageCRC ? "has an image" : "no image", @@ -601,9 +588,9 @@ void LayerAndroid::showLayer(int indent) clip.x(), clip.y(), clip.width(), clip.height(), contentIsScrollable() ? "SCROLLABLE" : "", isFixed() ? "FIXED" : "", - m_recordingPicture, - m_recordingPicture ? m_recordingPicture->width() : -1, - m_recordingPicture ? m_recordingPicture->height() : -1); + m_content, + m_content ? m_content->width() : -1, + m_content ? m_content->height() : -1); int count = this->countChildren(); for (int i = 0; i < count; i++) @@ -658,7 +645,7 @@ bool LayerAndroid::updateWithLayer(LayerAndroid* layer) if (m_imageCRC != layer->m_imageCRC) m_visible = false; - if ((m_recordingPicture != layer->m_recordingPicture) + if ((m_content != layer->m_content) || (m_imageCRC != layer->m_imageCRC)) return true; @@ -703,7 +690,7 @@ bool LayerAndroid::canJoinGroup(LayerGroup* group) // currently, we don't group zoomable with non-zoomable layers (unless the // group or the layer doesn't need a texture) - if (group->needsTexture() && needsTexture() && m_hasText != group->hasText()) + if (group->needsTexture() && needsTexture() && m_content->hasText() != group->hasText()) return false; // TODO: compare other layer properties - fixed? overscroll? transformed? @@ -893,8 +880,8 @@ bool LayerAndroid::drawChildrenCanvas(SkCanvas* canvas, PaintStyle style) void LayerAndroid::contentDraw(SkCanvas* canvas, PaintStyle style) { - if (m_recordingPicture) - canvas->drawPicture(*m_recordingPicture); + if (m_content) + m_content->draw(canvas); if (TilesManager::instance()->getShowVisualIndicator()) { float w = getSize().width(); @@ -931,7 +918,7 @@ void LayerAndroid::onDraw(SkCanvas* canvas, SkScalar opacity, return; } - if (!prepareContext()) + if (masksToBounds() || !m_content) return; // we just have this save/restore for opacity... @@ -956,29 +943,6 @@ void LayerAndroid::onDraw(SkCanvas* canvas, SkScalar opacity, extra->draw(canvas, this); } -SkPicture* LayerAndroid::recordContext() -{ - if (prepareContext(true)) - return m_recordingPicture; - return 0; -} - -bool LayerAndroid::prepareContext(bool force) -{ - if (masksToBounds()) - return false; - - if (force || !m_recordingPicture || - (m_recordingPicture && - ((m_recordingPicture->width() != (int) getSize().width()) || - (m_recordingPicture->height() != (int) getSize().height())))) { - SkSafeUnref(m_recordingPicture); - m_recordingPicture = new SkPicture(); - } - - return m_recordingPicture; -} - void LayerAndroid::setFixedPosition(FixedPositioning* position) { if (m_fixedPosition && m_fixedPosition != position) delete m_fixedPosition; @@ -1001,9 +965,9 @@ void LayerAndroid::dumpLayer(FILE* file, int indentLevel) const writeMatrix(file, indentLevel + 1, "transformMatrix", m_transform); writeRect(file, indentLevel + 1, "clippingRect", SkRect(m_clippingRect)); - if (m_recordingPicture) { - writeIntVal(file, indentLevel + 1, "m_recordingPicture.width", m_recordingPicture->width()); - writeIntVal(file, indentLevel + 1, "m_recordingPicture.height", m_recordingPicture->height()); + if (m_content) { + writeIntVal(file, indentLevel + 1, "m_content.width", m_content->width()); + writeIntVal(file, indentLevel + 1, "m_content.height", m_content->height()); } if (m_fixedPosition) diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.h b/Source/WebCore/platform/graphics/android/LayerAndroid.h index 2b8ad5d..459c159 100644 --- a/Source/WebCore/platform/graphics/android/LayerAndroid.h +++ b/Source/WebCore/platform/graphics/android/LayerAndroid.h @@ -48,6 +48,7 @@ class SkPicture; namespace WebCore { class LayerAndroid; +class LayerContent; class LayerGroup; class ImageTexture; } @@ -170,7 +171,8 @@ public: } bool masksToBounds() const { return m_haveClip; } - SkPicture* recordContext(); + LayerContent* content() { return m_content; } + void setContent(LayerContent* content); void addAnimation(PassRefPtr<AndroidAnimation> anim); void removeAnimationsForProperty(AnimatedPropertyID property); @@ -181,8 +183,6 @@ public: bool hasAnimations() const; void addDirtyArea(); - SkPicture* picture() const { return m_recordingPicture; } - virtual void dumpLayer(FILE*, int indentLevel) const; void dumpLayers(FILE*, int indentLevel) const; void dumpToLog() const; @@ -261,8 +261,7 @@ public: LayerType type() { return m_type; } virtual SubclassType subclassType() { return LayerAndroid::StandardLayer; } - bool hasText() { return m_hasText; } - void checkForPictureOptimizations(); + bool hasText(); void copyAnimationStartTimesRecursive(LayerAndroid* oldTree); @@ -308,14 +307,6 @@ private: FixedPositioning* m_fixedPosition; - // Note that m_recordingPicture and m_imageRef are mutually exclusive; - // m_recordingPicture is used when WebKit is asked to paint the layer's - // content, while m_imageRef contains an image that we directly - // composite, using the layer's dimensions as a destination rect. - // We do this as if the layer only contains an image, directly compositing - // it is a much faster method than using m_recordingPicture. - SkPicture* m_recordingPicture; - typedef HashMap<pair<String, int>, RefPtr<AndroidAnimation> > KeyframesMap; KeyframesMap m_animations; @@ -332,6 +323,13 @@ private: int m_uniqueId; + // Note that m_content and m_imageCRC are mutually exclusive; + // m_content is used when WebKit is asked to paint the layer's + // content, while m_imageCRC references an image that we directly + // composite, using the layer's dimensions as a destination rect. + // We do this as if the layer only contains an image, directly compositing + // it is a much faster method than using m_content. + LayerContent* m_content; unsigned m_imageCRC; // used to signal the framework we need a repaint @@ -353,7 +351,6 @@ private: LayerType m_type; SubclassType m_subclassType; - bool m_hasText; bool m_intrinsicallyComposited; LayerGroup* m_layerGroup; diff --git a/Source/WebCore/platform/graphics/android/LayerContent.h b/Source/WebCore/platform/graphics/android/LayerContent.h new file mode 100644 index 0000000..32108ec --- /dev/null +++ b/Source/WebCore/platform/graphics/android/LayerContent.h @@ -0,0 +1,51 @@ +/* + * 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 LayerContent_h +#define LayerContent_h + +#include "SkRefCnt.h" + +class SkCanvas; +class SkPicture; +class SkWStream; + +namespace WebCore { + +class LayerContent : public SkRefCnt { +public: + virtual int width() = 0; + virtual int height() = 0; + virtual bool isEmpty() = 0; + virtual void checkForOptimisations() = 0; + virtual bool hasText() = 0; + virtual void draw(SkCanvas* canvas) = 0; + + virtual void serialize(SkWStream* stream) = 0; +}; + +} // WebCore + +#endif // LayerContent_h diff --git a/Source/WebCore/platform/graphics/android/PictureLayerContent.cpp b/Source/WebCore/platform/graphics/android/PictureLayerContent.cpp new file mode 100644 index 0000000..cf2e569 --- /dev/null +++ b/Source/WebCore/platform/graphics/android/PictureLayerContent.cpp @@ -0,0 +1,103 @@ +#include "config.h" +#include "PictureLayerContent.h" + +#include "InspectorCanvas.h" +#include "SkPicture.h" + +namespace WebCore { + +PictureLayerContent::PictureLayerContent(SkPicture* picture) + : m_picture(picture) + , m_checkedContent(false) + , m_hasText(true) +{ + SkSafeRef(m_picture); +} + +PictureLayerContent::PictureLayerContent(const PictureLayerContent& content) + : m_picture(content.m_picture) + , m_checkedContent(content.m_checkedContent) + , m_hasText(content.m_hasText) +{ + SkSafeRef(m_picture); +} + +PictureLayerContent::~PictureLayerContent() +{ + SkSafeUnref(m_picture); +} + +int PictureLayerContent::width() +{ + if (!m_picture) + return 0; + return m_picture->width(); +} + +int PictureLayerContent::height() +{ + if (!m_picture) + return 0; + return m_picture->height(); +} + +bool PictureLayerContent::isEmpty() +{ + if (!m_picture) + return true; + if (m_picture->width() == 0 + || m_picture->height() == 0) + return true; + return false; +} + +void PictureLayerContent::checkForOptimisations() +{ + if (!m_checkedContent) + hasText(); // for now only check the presence of text +} + +bool PictureLayerContent::hasText() +{ + if (m_checkedContent) + return m_hasText; + + // Let's check if we have text or not. If we don't, we can limit + // ourselves to scale 1! + InspectorBounder inspectorBounder; + InspectorCanvas checker(&inspectorBounder, m_picture); + SkBitmap bitmap; + bitmap.setConfig(SkBitmap::kARGB_8888_Config, + m_picture->width(), + m_picture->height()); + checker.setBitmapDevice(bitmap); + checker.drawPicture(*m_picture); + m_hasText = checker.hasText(); + if (!checker.hasContent()) { + // no content to draw, discard picture so UI / tile generation + // doesn't bother with it + SkSafeUnref(m_picture); + m_picture = 0; + } + + m_checkedContent = true; + + return m_hasText; +} + +void PictureLayerContent::draw(SkCanvas* canvas) +{ + if (!m_picture) + return; + + canvas->drawPicture(*m_picture); +} + +void PictureLayerContent::serialize(SkWStream* stream) +{ + if (!m_picture) + return; + m_picture->serialize(stream); +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/PictureLayerContent.h b/Source/WebCore/platform/graphics/android/PictureLayerContent.h new file mode 100644 index 0000000..94bdfac --- /dev/null +++ b/Source/WebCore/platform/graphics/android/PictureLayerContent.h @@ -0,0 +1,55 @@ +/* + * 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 PictureLayerContent_h +#define PictureLayerContent_h + +#include "LayerContent.h" + +namespace WebCore { + +class PictureLayerContent : public LayerContent { +public: + PictureLayerContent(SkPicture* picture); + PictureLayerContent(const PictureLayerContent& content); + ~PictureLayerContent(); + + virtual int width(); + virtual int height(); + virtual bool isEmpty(); + virtual void checkForOptimisations(); + virtual bool hasText(); + virtual void draw(SkCanvas* canvas); + virtual void serialize(SkWStream* stream); + +private: + SkPicture* m_picture; + bool m_checkedContent; + bool m_hasText; +}; + +} // WebCore + +#endif // PictureLayerContent_h diff --git a/Source/WebCore/platform/graphics/android/PictureSetLayerContent.cpp b/Source/WebCore/platform/graphics/android/PictureSetLayerContent.cpp new file mode 100644 index 0000000..bc024eb --- /dev/null +++ b/Source/WebCore/platform/graphics/android/PictureSetLayerContent.cpp @@ -0,0 +1,35 @@ +#include "config.h" +#include "PictureSetLayerContent.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()) + 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/PictureSetLayerContent.h b/Source/WebCore/platform/graphics/android/PictureSetLayerContent.h new file mode 100644 index 0000000..61fc3f4 --- /dev/null +++ b/Source/WebCore/platform/graphics/android/PictureSetLayerContent.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 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 |