From 8f7bdaae7030fbbfd3c3cde0a8b0e8d489d0b14f Mon Sep 17 00:00:00 2001 From: John Reck Date: Tue, 24 Jul 2012 20:16:08 -0700 Subject: Push everything into an R-Tree Change-Id: Ifbfd0b91eb9fab057c2a91d740325b598b2d617a --- Source/WebCore/Android.mk | 1 - .../graphics/android/context/GraphicsOperation.h | 282 +------------------ .../context/GraphicsOperationCollection.cpp | 84 ------ .../android/context/GraphicsOperationCollection.h | 61 ----- .../context/PlatformGraphicsContextRecording.cpp | 305 ++++++++++++++------- .../context/PlatformGraphicsContextRecording.h | 34 +-- .../platform/graphics/android/context/RTree.h | 4 +- .../graphics/android/fonts/FontAndroid.cpp | 1 - Source/WebKit/android/jni/PicturePile.cpp | 1 - Source/WebKit/android/jni/WebViewCore.cpp | 1 - 10 files changed, 233 insertions(+), 541 deletions(-) delete mode 100644 Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.cpp delete mode 100644 Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.h diff --git a/Source/WebCore/Android.mk b/Source/WebCore/Android.mk index 98c1a63..dcef645 100644 --- a/Source/WebCore/Android.mk +++ b/Source/WebCore/Android.mk @@ -642,7 +642,6 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ platform/graphics/android/SharedBufferStream.cpp \ \ platform/graphics/android/context/GraphicsContextAndroid.cpp \ - platform/graphics/android/context/GraphicsOperationCollection.cpp \ platform/graphics/android/context/PlatformGraphicsContext.cpp \ platform/graphics/android/context/PlatformGraphicsContextRecording.cpp \ platform/graphics/android/context/PlatformGraphicsContextSkia.cpp \ diff --git a/Source/WebCore/platform/graphics/android/context/GraphicsOperation.h b/Source/WebCore/platform/graphics/android/context/GraphicsOperation.h index 1cfb094..2a7369c 100644 --- a/Source/WebCore/platform/graphics/android/context/GraphicsOperation.h +++ b/Source/WebCore/platform/graphics/android/context/GraphicsOperation.h @@ -29,7 +29,6 @@ #include "Color.h" #include "FloatRect.h" #include "GlyphBuffer.h" -#include "GraphicsOperationCollection.h" #include "Font.h" #include "IntRect.h" #include "PlatformGraphicsContext.h" @@ -45,29 +44,13 @@ namespace WebCore { +class CanvasState; + namespace GraphicsOperation { class Operation { public: typedef enum { UndefinedOperation - // State management - , TransparencyLayerOperation - , SaveOperation - // State setters - , SetAlphaOperation - , SetCompositeOpOperation - , SetFillColorOperation - , SetFillShaderOperation - , SetLineCapOperation - , SetLineDashOperation - , SetLineJoinOperation - , SetMiterLimitOperation - , SetShadowOperation - , SetShouldAntialiasOperation - , SetStrokeColorOperation - , SetStrokeShaderOperation - , SetStrokeStyleOperation - , SetStrokeThicknessOperation // Matrix operations , ConcatCTMOperation , ScaleOperation @@ -102,13 +85,15 @@ public: Operation() : m_state(0) - , m_matrix(0) + , m_canvasState(0) {} // This m_state is applied by ourselves PlatformGraphicsContext::State* m_state; - // This m_matrix is applied by Recording::draw - SkMatrix* m_matrix; + // This is the canvas state that this operation needs + // Only used for drawing operations, state operations will be undefined + CanvasState* m_canvasState; + IntRect m_globalBounds; bool apply(PlatformGraphicsContext* context) { if (m_state) @@ -119,28 +104,11 @@ public: virtual ~Operation() {} virtual OperationType type() { return UndefinedOperation; } virtual String parameters() { return ""; } + virtual void subtractOpaqueClip(FloatRect& clip) {} const char* name() { switch (type()) { TYPE_CASE(UndefinedOperation) - // State management - TYPE_CASE(TransparencyLayerOperation) - TYPE_CASE(SaveOperation) - // State setters - TYPE_CASE(SetAlphaOperation) - TYPE_CASE(SetCompositeOpOperation) - TYPE_CASE(SetFillColorOperation) - TYPE_CASE(SetFillShaderOperation) - TYPE_CASE(SetLineCapOperation) - TYPE_CASE(SetLineDashOperation) - TYPE_CASE(SetLineJoinOperation) - TYPE_CASE(SetMiterLimitOperation) - TYPE_CASE(SetShadowOperation) - TYPE_CASE(SetShouldAntialiasOperation) - TYPE_CASE(SetStrokeColorOperation) - TYPE_CASE(SetStrokeShaderOperation) - TYPE_CASE(SetStrokeStyleOperation) - TYPE_CASE(SetStrokeThicknessOperation) // Matrix operations TYPE_CASE(ConcatCTMOperation) TYPE_CASE(ScaleOperation) @@ -177,235 +145,6 @@ public: }; //************************************** -// State management -//************************************** - -class Save : public Operation { -public: - Save() : m_saveMatrix(true) {} - virtual bool applyImpl(PlatformGraphicsContext* context) { - context->save(); - m_operations.apply(context); - context->restore(); - return true; - } - virtual OperationType type() { return SaveOperation; } - GraphicsOperationCollection* operations() { return &m_operations; } - bool saveMatrix() { return m_saveMatrix; } - FloatRect bounds; -protected: - GraphicsOperationCollection m_operations; - bool m_saveMatrix : 1; -}; - -class TransparencyLayer : public Save { -public: - TransparencyLayer(const float opacity) : m_opacity(opacity) { - m_saveMatrix = false; - } - virtual bool applyImpl(PlatformGraphicsContext* context) { - context->beginTransparencyLayer(m_opacity); - m_operations.apply(context); - context->endTransparencyLayer(); - return true; - } - virtual OperationType type() { return TransparencyLayerOperation; } -private: - float m_opacity; -}; - -//************************************** -// State setters -//************************************** - -class SetAlpha : public Operation { -public: - SetAlpha(const float alpha) : m_alpha(alpha) {} - virtual bool applyImpl(PlatformGraphicsContext* context) { - context->setAlpha(m_alpha); - return true; - } - virtual OperationType type() { return SetAlphaOperation; } -private: - float m_alpha; -}; - -class SetCompositeOperation : public Operation { -public: - SetCompositeOperation(CompositeOperator op) : m_operator(op) {} - virtual bool applyImpl(PlatformGraphicsContext* context) { - context->setCompositeOperation(m_operator); - return true; - } - virtual OperationType type() { return SetCompositeOpOperation; } -private: - CompositeOperator m_operator; -}; - -class SetFillColor : public Operation { -public: - SetFillColor(Color color) : m_color(color) {} - virtual bool applyImpl(PlatformGraphicsContext* context) { - context->setFillColor(m_color); - return true; - } - virtual OperationType type() { return SetFillColorOperation; } - virtual String parameters() { - return String::format("r: %d g: %d b: %d a: %d", - m_color.red(), - m_color.green(), - m_color.blue(), - m_color.alpha()); - } -private: - Color m_color; -}; - -class SetFillShader : public Operation { -public: - SetFillShader(SkShader* shader) : m_shader(shader) { - SkSafeRef(m_shader); - } - ~SetFillShader() { SkSafeUnref(m_shader); } - virtual bool applyImpl(PlatformGraphicsContext* context) { - context->setFillShader(m_shader); - return true; - } - virtual OperationType type() { return SetFillShaderOperation; } -private: - SkShader* m_shader; -}; - -class SetLineCap : public Operation { -public: - SetLineCap(LineCap cap) : m_cap(cap) {} - virtual bool applyImpl(PlatformGraphicsContext* context) { - context->setLineCap(m_cap); - return true; - } - virtual OperationType type() { return SetLineCapOperation; } -private: - LineCap m_cap; -}; - -class SetLineDash : public Operation { -public: - SetLineDash(const DashArray& dashes, float dashOffset) - : m_dashes(dashes), m_dashOffset(dashOffset) {} - virtual bool applyImpl(PlatformGraphicsContext* context) { - context->setLineDash(m_dashes, m_dashOffset); - return true; - } - virtual OperationType type() { return SetLineDashOperation; } -private: - DashArray m_dashes; - float m_dashOffset; -}; - -class SetLineJoin : public Operation { -public: - SetLineJoin(LineJoin join) : m_join(join) {} - virtual bool applyImpl(PlatformGraphicsContext* context) { - context->setLineJoin(m_join); - return true; - } - virtual OperationType type() { return SetLineJoinOperation; } -private: - LineJoin m_join; -}; - -class SetMiterLimit : public Operation { -public: - SetMiterLimit(float limit) : m_limit(limit) {} - virtual bool applyImpl(PlatformGraphicsContext* context) { - context->setMiterLimit(m_limit); - return true; - } - virtual OperationType type() { return SetMiterLimitOperation; } -private: - float m_limit; -}; - -class SetShadow : public Operation { -public: - SetShadow(int radius, int dx, int dy, SkColor c) - : m_radius(radius), m_dx(dx), m_dy(dy), m_color(c) {} - virtual bool applyImpl(PlatformGraphicsContext* context) { - context->setShadow(m_radius, m_dx, m_dy, m_color); - return true; - } - virtual OperationType type() { return SetShadowOperation; } -private: - int m_radius; - int m_dx; - int m_dy; - SkColor m_color; -}; - -class SetShouldAntialias : public Operation { -public: - SetShouldAntialias(bool useAA) : m_useAA(useAA) {} - virtual bool applyImpl(PlatformGraphicsContext* context) { - context->setShouldAntialias(m_useAA); - return true; - } - virtual OperationType type() { return SetShouldAntialiasOperation; } -private: - bool m_useAA; -}; - -class SetStrokeColor : public Operation { -public: - SetStrokeColor(const Color& c) : m_color(c) {} - virtual bool applyImpl(PlatformGraphicsContext* context) { - context->setStrokeColor(m_color); - return true; - } - virtual OperationType type() { return SetStrokeColorOperation; } -private: - Color m_color; -}; - -class SetStrokeShader : public Operation { -public: - SetStrokeShader(SkShader* strokeShader) : m_shader(strokeShader) { - SkSafeRef(m_shader); - } - ~SetStrokeShader() { SkSafeUnref(m_shader); } - virtual bool applyImpl(PlatformGraphicsContext* context) { - context->setStrokeShader(m_shader); - return true; - } - virtual OperationType type() { return SetStrokeShaderOperation; } -private: - SkShader* m_shader; -}; - -class SetStrokeStyle : public Operation { -public: - SetStrokeStyle(StrokeStyle style) : m_style(style) {} - virtual bool applyImpl(PlatformGraphicsContext* context) { - context->setStrokeStyle(m_style); - return true; - } - virtual OperationType type() { return SetStrokeStyleOperation; } -private: - StrokeStyle m_style; -}; - -class SetStrokeThickness : public Operation { -public: - SetStrokeThickness(float thickness) : m_thickness(thickness) {} - virtual bool applyImpl(PlatformGraphicsContext* context) { - context->setStrokeThickness(m_thickness); - return true; - } - virtual OperationType type() { return SetStrokeThicknessOperation; } -private: - float m_thickness; -}; - -//************************************** // Matrix operations //************************************** @@ -552,8 +291,7 @@ public: } virtual OperationType type() { return DrawBitmapPatternOperation; } private: - // TODO: use refcounted bitmap - const SkBitmap m_bitmap; + SkBitmap m_bitmap; SkMatrix m_matrix; CompositeOperator m_operator; FloatRect m_destRect; @@ -575,7 +313,7 @@ public: m_dstR.width(), m_dstR.height()); } private: - const SkBitmap& m_bitmap; + SkBitmap m_bitmap; SkIRect m_srcR; SkRect m_dstR; CompositeOperator m_operator; diff --git a/Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.cpp b/Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.cpp deleted file mode 100644 index a24f829..0000000 --- a/Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.cpp +++ /dev/null @@ -1,84 +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. - */ - -#define LOG_TAG "GraphicsOperationCollection" -#define LOG_NDEBUG 1 - -#include "config.h" -#include "GraphicsOperationCollection.h" - -#include "AndroidLog.h" -#include "GraphicsContext.h" -#include "GraphicsOperation.h" -#include "PlatformGraphicsContext.h" -#include "PlatformGraphicsContextRecording.h" - -namespace WebCore { - -GraphicsOperationCollection::GraphicsOperationCollection() -{ -} - -GraphicsOperationCollection::~GraphicsOperationCollection() -{ - clear(); -} - -void GraphicsOperationCollection::apply(PlatformGraphicsContext* context) const -{ - size_t size = m_operations.size(); - for (size_t i = 0; i < size; i++) - if (!m_operations[i]->apply(context)) - return; -} - -void GraphicsOperationCollection::adoptAndAppend(GraphicsOperation::Operation* operation) -{ - m_operations.append(operation); -} - -void GraphicsOperationCollection::transferFrom(GraphicsOperationCollection& moveFrom) -{ - size_t size = moveFrom.m_operations.size(); - m_operations.reserveCapacity(m_operations.size() + size); - for (size_t i = 0; i < size; i++) - m_operations.append(moveFrom.m_operations[i]); - moveFrom.m_operations.clear(); -} - -bool GraphicsOperationCollection::isEmpty() -{ - return !m_operations.size(); -} - -void GraphicsOperationCollection::clear() -{ - size_t size = m_operations.size(); - for (size_t i = 0; i < size; i++) - delete m_operations[i]; - m_operations.clear(); -} - -} // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.h b/Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.h deleted file mode 100644 index d2c18ab..0000000 --- a/Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.h +++ /dev/null @@ -1,61 +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 GraphicsOperationCollection_h -#define GraphicsOperationCollection_h - -#include "SkRefCnt.h" -#include "wtf/Vector.h" - -namespace WebCore { - -namespace GraphicsOperation { -class Operation; -} - -class PlatformGraphicsContext; - -class GraphicsOperationCollection : public SkRefCnt { -public: - GraphicsOperationCollection(); - ~GraphicsOperationCollection(); - - void apply(PlatformGraphicsContext* context) const; - void adoptAndAppend(GraphicsOperation::Operation* operation); - - // Moves all the operations from moveFrom into this collection - // moveFrom will be empty after this call - void transferFrom(GraphicsOperationCollection& moveFrom); - - bool isEmpty(); - void clear(); - -private: - Vector m_operations; -}; - -} - -#endif // GraphicsOperationCollection_h diff --git a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp index 4a14513..1e5aada 100644 --- a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp +++ b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp @@ -9,7 +9,6 @@ #include "FloatQuad.h" #include "Font.h" #include "GraphicsContext.h" -#include "GraphicsOperationCollection.h" #include "GraphicsOperation.h" #include "PlatformGraphicsContextSkia.h" #include "RTree.h" @@ -38,6 +37,82 @@ public: typedef HashSet StateHashSet; +class CanvasState { +public: + CanvasState(CanvasState* parent) + : m_parent(parent) + , m_isTransparencyLayer(false) + {} + + CanvasState(CanvasState* parent, float opacity) + : m_parent(parent) + , m_isTransparencyLayer(true) + , m_opacity(opacity) + {} + + ~CanvasState() { + ALOGV("Delete %p", this); + for (size_t i = 0; i < m_operations.size(); i++) + delete m_operations[i]; + m_operations.clear(); + } + + bool isParentOf(CanvasState* other) { + while (other->m_parent) { + if (other->m_parent == this) + return true; + other = other->m_parent; + } + return false; + } + + void playback(PlatformGraphicsContext* context, size_t fromId, size_t toId) const { + ALOGV("playback %p from %d->%d", this, fromId, toId); + for (size_t i = 0; i < m_operations.size(); i++) { + RecordingData *data = m_operations[i]; + if (data->m_orderBy < fromId) + continue; + if (data->m_orderBy > toId) + break; + ALOGV("Applying operation[%d] %p->%s()", i, data->m_operation, + data->m_operation->name()); + data->m_operation->apply(context); + } + } + + CanvasState* parent() { return m_parent; } + + void enterState(PlatformGraphicsContext* context) { + ALOGV("enterState %p", this); + if (m_isTransparencyLayer) + context->beginTransparencyLayer(m_opacity); + else + context->save(); + } + + void exitState(PlatformGraphicsContext* context) { + ALOGV("exitState %p", this); + if (m_isTransparencyLayer) + context->endTransparencyLayer(); + else + context->restore(); + } + + void adoptAndAppend(RecordingData* data) { + m_operations.append(data); + } + + bool isTransparencyLayer() { + return m_isTransparencyLayer; + } + +private: + CanvasState *m_parent; + bool m_isTransparencyLayer; + float m_opacity; + Vector m_operations; +}; + class RecordingImpl { public: RecordingImpl() @@ -47,7 +122,7 @@ public: ~RecordingImpl() { clearStates(); - clearMatrixes(); + clearCanvasStates(); } PlatformGraphicsContext::State* getState(PlatformGraphicsContext::State* inState) { @@ -60,9 +135,47 @@ public: return state; } - SkMatrix* cloneMatrix(const SkMatrix& matrix) { - m_matrixes.append(new SkMatrix(matrix)); - return m_matrixes.last(); + void addCanvasState(CanvasState* state) { + m_canvasStates.append(state); + } + + void removeCanvasState(const CanvasState* state) { + if (m_canvasStates.last() == state) + m_canvasStates.removeLast(); + else { + size_t indx = m_canvasStates.find(state); + m_canvasStates.remove(indx); + } + } + + void applyState(PlatformGraphicsContext* context, + CanvasState* fromState, size_t fromId, + CanvasState* toState, size_t toId) { + ALOGV("applyState(%p->%p, %d-%d)", fromState, toState, fromId, toId); + if (fromState != toState && fromState) { + if (fromState->isParentOf(toState)) { + // Going down the tree, playback any parent operations then save + // before playing back our current operations + applyState(context, fromState, fromId, toState->parent(), toId); + toState->enterState(context); + } else if (toState->isParentOf(fromState)) { + // Going up the tree, pop some states + while (fromState != toState) { + fromState->exitState(context); + fromState = fromState->parent(); + } + } else { + // Siblings in the tree + fromState->exitState(context); + applyState(context, fromState->parent(), fromId, toState, toId); + return; + } + } else if (!fromState) { + if (toState->parent()) + applyState(context, fromState, fromId, toState->parent(), toId); + toState->enterState(context); + } + toState->playback(context, fromId, toId); } RTree::RTree m_tree; @@ -77,15 +190,15 @@ private: m_states.clear(); } - void clearMatrixes() { - for (size_t i = 0; i < m_matrixes.size(); i++) - delete m_matrixes[i]; - m_matrixes.clear(); + void clearCanvasStates() { + for (size_t i = 0; i < m_canvasStates.size(); i++) + delete m_canvasStates[i]; + m_canvasStates.clear(); } // TODO: Use a global pool? StateHashSet m_states; - Vector m_matrixes; + Vector m_canvasStates; }; Recording::~Recording() @@ -115,31 +228,29 @@ void Recording::draw(SkCanvas* canvas) m_recording->m_tree.search(iclip, nodes); size_t count = nodes.size(); - ALOGV("Drawing %d nodes out of %d (state storage=%d)", count, - m_recording->m_nodeCount, sizeof(PlatformGraphicsContext::State) * m_recording->m_states.size()); + ALOGV("Drawing %d nodes out of %d", count, m_recording->m_nodeCount); if (count) { + int saveCount = canvas->getSaveCount(); nonCopyingSort(nodes.begin(), nodes.end(), CompareRecordingDataOrder); PlatformGraphicsContextSkia context(canvas); - SkMatrix* matrix = 0; - int saveCount = 0; + CanvasState* currState = 0; + size_t lastOperationId = 0; for (size_t i = 0; i < count; i++) { GraphicsOperation::Operation* op = nodes[i]->m_operation; - SkMatrix* opMatrix = op->m_matrix; - if (opMatrix != matrix) { - matrix = opMatrix; - if (saveCount) { - canvas->restoreToCount(saveCount); - saveCount = 0; - } - if (!matrix->isIdentity()) { - saveCount = canvas->save(SkCanvas::kMatrix_SaveFlag); - canvas->concat(*matrix); - } - } + m_recording->applyState(&context, currState, lastOperationId, + op->m_canvasState, nodes[i]->m_orderBy); + currState = op->m_canvasState; + lastOperationId = nodes[i]->m_orderBy; + ALOGV("apply: %p->%s(%s)", op, op->name(), op->parameters().ascii().data()); op->apply(&context); } - if (saveCount) - canvas->restoreToCount(saveCount); + while (currState) { + currState->exitState(&context); + currState = currState->parent(); + } + if (saveCount != canvas->getSaveCount()) { + ALOGW("Save/restore mismatch! %d vs. %d", saveCount, canvas->getSaveCount()); + } } } @@ -161,13 +272,14 @@ PlatformGraphicsContextRecording::PlatformGraphicsContextRecording(Recording* re , mPicture(0) , mRecording(recording) , mOperationState(0) - , mOperationMatrix(0) , m_hasText(false) , m_isEmpty(true) { - pushMatrix(); if (mRecording) mRecording->setRecording(new RecordingImpl()); + mMatrixStack.append(SkMatrix::I()); + mCurrentMatrix = &(mMatrixStack.last()); + pushStateOperation(new CanvasState(0)); } bool PlatformGraphicsContextRecording::isPaintingDisabled() @@ -200,24 +312,28 @@ void PlatformGraphicsContextRecording::endRecording(const SkRect& bounds) void PlatformGraphicsContextRecording::beginTransparencyLayer(float opacity) { - pushSaveOperation(new GraphicsOperation::TransparencyLayer(opacity)); + CanvasState* parent = mRecordingStateStack.last().mCanvasState; + pushStateOperation(new CanvasState(parent, opacity)); } void PlatformGraphicsContextRecording::endTransparencyLayer() { - popSaveOperation(); + popStateOperation(); } void PlatformGraphicsContextRecording::save() { PlatformGraphicsContext::save(); - pushSaveOperation(new GraphicsOperation::Save()); + CanvasState* parent = mRecordingStateStack.last().mCanvasState; + pushStateOperation(new CanvasState(parent)); + pushMatrix(); } void PlatformGraphicsContextRecording::restore() { PlatformGraphicsContext::restore(); - popSaveOperation(); + popMatrix(); + popStateOperation(); } //************************************** @@ -227,19 +343,19 @@ void PlatformGraphicsContextRecording::restore() void PlatformGraphicsContextRecording::setAlpha(float alpha) { PlatformGraphicsContext::setAlpha(alpha); - appendStateOperation(new GraphicsOperation::SetAlpha(alpha)); + mOperationState = 0; } void PlatformGraphicsContextRecording::setCompositeOperation(CompositeOperator op) { PlatformGraphicsContext::setCompositeOperation(op); - appendStateOperation(new GraphicsOperation::SetCompositeOperation(op)); + mOperationState = 0; } bool PlatformGraphicsContextRecording::setFillColor(const Color& c) { if (PlatformGraphicsContext::setFillColor(c)) { - appendStateOperation(new GraphicsOperation::SetFillColor(c)); + mOperationState = 0; return true; } return false; @@ -248,7 +364,7 @@ bool PlatformGraphicsContextRecording::setFillColor(const Color& c) bool PlatformGraphicsContextRecording::setFillShader(SkShader* fillShader) { if (PlatformGraphicsContext::setFillShader(fillShader)) { - appendStateOperation(new GraphicsOperation::SetFillShader(fillShader)); + mOperationState = 0; return true; } return false; @@ -257,44 +373,44 @@ bool PlatformGraphicsContextRecording::setFillShader(SkShader* fillShader) void PlatformGraphicsContextRecording::setLineCap(LineCap cap) { PlatformGraphicsContext::setLineCap(cap); - appendStateOperation(new GraphicsOperation::SetLineCap(cap)); + mOperationState = 0; } void PlatformGraphicsContextRecording::setLineDash(const DashArray& dashes, float dashOffset) { PlatformGraphicsContext::setLineDash(dashes, dashOffset); - appendStateOperation(new GraphicsOperation::SetLineDash(dashes, dashOffset)); + mOperationState = 0; } void PlatformGraphicsContextRecording::setLineJoin(LineJoin join) { PlatformGraphicsContext::setLineJoin(join); - appendStateOperation(new GraphicsOperation::SetLineJoin(join)); + mOperationState = 0; } void PlatformGraphicsContextRecording::setMiterLimit(float limit) { PlatformGraphicsContext::setMiterLimit(limit); - appendStateOperation(new GraphicsOperation::SetMiterLimit(limit)); + mOperationState = 0; } void PlatformGraphicsContextRecording::setShadow(int radius, int dx, int dy, SkColor c) { PlatformGraphicsContext::setShadow(radius, dx, dy, c); - appendStateOperation(new GraphicsOperation::SetShadow(radius, dx, dy, c)); + mOperationState = 0; } void PlatformGraphicsContextRecording::setShouldAntialias(bool useAA) { m_state->useAA = useAA; PlatformGraphicsContext::setShouldAntialias(useAA); - appendStateOperation(new GraphicsOperation::SetShouldAntialias(useAA)); + mOperationState = 0; } bool PlatformGraphicsContextRecording::setStrokeColor(const Color& c) { if (PlatformGraphicsContext::setStrokeColor(c)) { - appendStateOperation(new GraphicsOperation::SetStrokeColor(c)); + mOperationState = 0; return true; } return false; @@ -303,7 +419,7 @@ bool PlatformGraphicsContextRecording::setStrokeColor(const Color& c) bool PlatformGraphicsContextRecording::setStrokeShader(SkShader* strokeShader) { if (PlatformGraphicsContext::setStrokeShader(strokeShader)) { - appendStateOperation(new GraphicsOperation::SetStrokeShader(strokeShader)); + mOperationState = 0; return true; } return false; @@ -312,13 +428,13 @@ bool PlatformGraphicsContextRecording::setStrokeShader(SkShader* strokeShader) void PlatformGraphicsContextRecording::setStrokeStyle(StrokeStyle style) { PlatformGraphicsContext::setStrokeStyle(style); - appendStateOperation(new GraphicsOperation::SetStrokeStyle(style)); + mOperationState = 0; } void PlatformGraphicsContextRecording::setStrokeThickness(float f) { PlatformGraphicsContext::setStrokeThickness(f); - appendStateOperation(new GraphicsOperation::SetStrokeThickness(f)); + mOperationState = 0; } //************************************** @@ -328,7 +444,6 @@ void PlatformGraphicsContextRecording::setStrokeThickness(float f) void PlatformGraphicsContextRecording::concatCTM(const AffineTransform& affine) { mCurrentMatrix->preConcat(affine); - onCurrentMatrixChanged(); appendStateOperation(new GraphicsOperation::ConcatCTM(affine)); } @@ -336,31 +451,24 @@ void PlatformGraphicsContextRecording::rotate(float angleInRadians) { float value = angleInRadians * (180.0f / 3.14159265f); mCurrentMatrix->preRotate(SkFloatToScalar(value)); - onCurrentMatrixChanged(); appendStateOperation(new GraphicsOperation::Rotate(angleInRadians)); } void PlatformGraphicsContextRecording::scale(const FloatSize& size) { mCurrentMatrix->preScale(SkFloatToScalar(size.width()), SkFloatToScalar(size.height())); - onCurrentMatrixChanged(); appendStateOperation(new GraphicsOperation::Scale(size)); } void PlatformGraphicsContextRecording::translate(float x, float y) { mCurrentMatrix->preTranslate(SkFloatToScalar(x), SkFloatToScalar(y)); - onCurrentMatrixChanged(); appendStateOperation(new GraphicsOperation::Translate(x, y)); } const SkMatrix& PlatformGraphicsContextRecording::getTotalMatrix() { - // Each RecordingState tracks the delta from its "parent" SkMatrix - mTotalMatrix = mMatrixStack.first(); - for (size_t i = 1; i < mMatrixStack.size(); i++) - mTotalMatrix.preConcat(mMatrixStack[i]); - return mTotalMatrix; + return *mCurrentMatrix; } //************************************** @@ -578,28 +686,33 @@ void PlatformGraphicsContextRecording::clipState(const FloatRect& clip) } } -void PlatformGraphicsContextRecording::pushSaveOperation(GraphicsOperation::Save* saveOp) +void PlatformGraphicsContextRecording::pushStateOperation(CanvasState* canvasState) { - mRecordingStateStack.append(saveOp); - if (saveOp->saveMatrix()) - pushMatrix(); + ALOGV("pushStateOperation: %p(isLayer=%d)", canvasState, canvasState->isTransparencyLayer()); + mRecordingStateStack.append(canvasState); + mRecording->recording()->addCanvasState(canvasState); } -void PlatformGraphicsContextRecording::popSaveOperation() +void PlatformGraphicsContextRecording::popStateOperation() { RecordingState state = mRecordingStateStack.last(); mRecordingStateStack.removeLast(); - if (state.mSaveOperation->saveMatrix()) - popMatrix(); - if (state.mHasDrawing) - appendDrawingOperation(state.mSaveOperation, state.mBounds); - else - delete state.mSaveOperation; + if (!state.mHasDrawing) { + ALOGV("popStateOperation is deleting %p(isLayer=%d)", + state.mCanvasState, state.mCanvasState->isTransparencyLayer()); + mRecording->recording()->removeCanvasState(state.mCanvasState); + delete state.mCanvasState; + } else { + ALOGV("popStateOperation: %p(isLayer=%d)", + state.mCanvasState, state.mCanvasState->isTransparencyLayer()); + // Make sure we propagate drawing upwards so we don't delete our parent + mRecordingStateStack.last().mHasDrawing = true; + } } void PlatformGraphicsContextRecording::pushMatrix() { - mMatrixStack.append(SkMatrix::I()); + mMatrixStack.append(mMatrixStack.last()); mCurrentMatrix = &(mMatrixStack.last()); } @@ -611,6 +724,10 @@ void PlatformGraphicsContextRecording::popMatrix() IntRect PlatformGraphicsContextRecording::calculateFinalBounds(FloatRect bounds) { + if (bounds.isEmpty() && mRecordingStateStack.last().mHasClip) { + ALOGV("Empty bounds, but has clip so using that"); + return enclosingIntRect(mRecordingStateStack.last().mBounds); + } if (m_gc->hasShadow()) { const ShadowRec& shadow = m_state->shadow; if (shadow.blur > 0) @@ -628,51 +745,45 @@ IntRect PlatformGraphicsContextRecording::calculateFinalBounds(FloatRect bounds) bounds.inflate(std::min(1.0f, m_state->strokeThickness)); SkRect translated; mCurrentMatrix->mapRect(&translated, bounds); + FloatRect ftrect = translated; + if (mRecordingStateStack.last().mHasClip + && !translated.intersect(mRecordingStateStack.last().mBounds)) { + ALOGV("Operation bounds=" FLOAT_RECT_FORMAT " clipped out by clip=" FLOAT_RECT_FORMAT, + FLOAT_RECT_ARGS(ftrect), FLOAT_RECT_ARGS(mRecordingStateStack.last().mBounds)); + return IntRect(); + } return enclosingIntRect(translated); } void PlatformGraphicsContextRecording::appendDrawingOperation( GraphicsOperation::Operation* operation, const FloatRect& untranslatedBounds) { - if (untranslatedBounds.isEmpty()) { - ALOGW("Empty bounds for %s(%s)!", operation->name(), operation->parameters().ascii().data()); - return; - } m_isEmpty = false; - if (mRecordingStateStack.size()) { - RecordingState& state = mRecordingStateStack.last(); - state.mHasDrawing = true; - if (!state.mHasClip) - state.addBounds(calculateFinalBounds(untranslatedBounds)); - state.mSaveOperation->operations()->adoptAndAppend(operation); - return; - } + RecordingState& state = mRecordingStateStack.last(); + state.mHasDrawing = true; if (!mOperationState) mOperationState = mRecording->recording()->getState(m_state); - if (!mOperationMatrix) - mOperationMatrix = mRecording->recording()->cloneMatrix(mMatrixStack.first()); operation->m_state = mOperationState; - operation->m_matrix = mOperationMatrix; - RecordingData* data = new RecordingData(operation, mRecording->recording()->m_nodeCount++); + operation->m_canvasState = state.mCanvasState; WebCore::IntRect ibounds = calculateFinalBounds(untranslatedBounds); - mRecording->recording()->m_tree.insert(ibounds, data); -} - -void PlatformGraphicsContextRecording::appendStateOperation(GraphicsOperation::Operation* operation) -{ - if (mRecordingStateStack.size()) - mRecordingStateStack.last().mSaveOperation->operations()->adoptAndAppend(operation); - else { + if (ibounds.isEmpty()) { + ALOGV("Operation %s(%s) was clipped out", operation->name(), + operation->parameters().ascii().data()); delete operation; - mOperationState = 0; + return; } + ALOGV("appendOperation %p->%s()", operation, operation->name()); + operation->m_globalBounds = ibounds; + RecordingData* data = new RecordingData(operation, mRecording->recording()->m_nodeCount++); + mRecording->recording()->m_tree.insert(ibounds, data); } -void PlatformGraphicsContextRecording::onCurrentMatrixChanged() +void PlatformGraphicsContextRecording::appendStateOperation(GraphicsOperation::Operation* operation) { - if (mCurrentMatrix == &(mMatrixStack.first())) - mOperationMatrix = 0; + ALOGV("appendOperation %p->%s()", operation, operation->name()); + RecordingData* data = new RecordingData(operation, mRecording->recording()->m_nodeCount++); + mRecordingStateStack.last().mCanvasState->adoptAndAppend(data); } } // WebCore diff --git a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.h b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.h index fd6fb5e..c06c9bc 100644 --- a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.h +++ b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.h @@ -28,7 +28,6 @@ #include "PlatformGraphicsContext.h" -#include "GraphicsOperationCollection.h" #include "SkRefCnt.h" class SkCanvas; @@ -36,9 +35,9 @@ class SkCanvas; namespace WebCore { namespace GraphicsOperation { class Operation; -class Save; } +class CanvasState; class RecordingImpl; class Recording : public SkRefCnt { public: @@ -147,48 +146,42 @@ private: void clipState(const FloatRect& clip); void appendDrawingOperation(GraphicsOperation::Operation* operation, const FloatRect& bounds); void appendStateOperation(GraphicsOperation::Operation* operation); - void onCurrentMatrixChanged(); - void pushSaveOperation(GraphicsOperation::Save* saveOp); - void popSaveOperation(); + void pushStateOperation(CanvasState* canvasState); + void popStateOperation(); void pushMatrix(); void popMatrix(); IntRect calculateFinalBounds(FloatRect bounds); SkPicture* mPicture; SkMatrix* mCurrentMatrix; - // Used for getTotalMatrix, is not valid elsewhere - SkMatrix mTotalMatrix; Recording* mRecording; class RecordingState { public: - RecordingState(GraphicsOperation::Save* saveOp) - : mSaveOperation(saveOp) + RecordingState(CanvasState* state) + : mCanvasState(state) , mHasDrawing(false) , mHasClip(false) {} RecordingState(const RecordingState& other) - : mSaveOperation(other.mSaveOperation) + : mCanvasState(other.mCanvasState) , mHasDrawing(other.mHasDrawing) , mHasClip(other.mHasClip) , mBounds(other.mBounds) {} - void addBounds(const FloatRect& bounds) - { - if (mHasClip) - return; - mBounds.unite(bounds); - } - void clip(const FloatRect& rect) { - addBounds(rect); - mHasClip = true; + if (mHasClip) + mBounds.intersect(rect); + else { + mBounds = rect; + mHasClip = true; + } } - GraphicsOperation::Save* mSaveOperation; + CanvasState* mCanvasState; bool mHasDrawing; bool mHasClip; FloatRect mBounds; @@ -196,7 +189,6 @@ private: Vector mRecordingStateStack; Vector mMatrixStack; State* mOperationState; - SkMatrix* mOperationMatrix; bool m_hasText; bool m_isEmpty; diff --git a/Source/WebCore/platform/graphics/android/context/RTree.h b/Source/WebCore/platform/graphics/android/context/RTree.h index 6b53d55..4ad8986 100644 --- a/Source/WebCore/platform/graphics/android/context/RTree.h +++ b/Source/WebCore/platform/graphics/android/context/RTree.h @@ -36,7 +36,7 @@ class LinearAllocator; class RecordingData { public: - RecordingData(GraphicsOperation::Operation* ops, int orderBy) + RecordingData(GraphicsOperation::Operation* ops, size_t orderBy) : m_orderBy(orderBy) , m_operation(ops) {} @@ -44,7 +44,7 @@ public: delete m_operation; } - unsigned int m_orderBy; + size_t m_orderBy; GraphicsOperation::Operation* m_operation; }; diff --git a/Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp b/Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp index 114247a..6388325 100644 --- a/Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp @@ -30,7 +30,6 @@ #include "AndroidLog.h" #include "EmojiFont.h" -#include "GraphicsOperationCollection.h" #include "GraphicsOperation.h" #include "Font.h" #include "FontData.h" diff --git a/Source/WebKit/android/jni/PicturePile.cpp b/Source/WebKit/android/jni/PicturePile.cpp index 554bd1b..0731977 100644 --- a/Source/WebKit/android/jni/PicturePile.cpp +++ b/Source/WebKit/android/jni/PicturePile.cpp @@ -40,7 +40,6 @@ #include "SkRegion.h" #if USE_RECORDING_CONTEXT -#include "GraphicsOperationCollection.h" #include "PlatformGraphicsContextRecording.h" #else #include "SkPicture.h" diff --git a/Source/WebKit/android/jni/WebViewCore.cpp b/Source/WebKit/android/jni/WebViewCore.cpp index ec027cd..79019cb 100644 --- a/Source/WebKit/android/jni/WebViewCore.cpp +++ b/Source/WebKit/android/jni/WebViewCore.cpp @@ -63,7 +63,6 @@ #include "Geolocation.h" #include "GraphicsContext.h" #include "GraphicsJNI.h" -#include "GraphicsOperationCollection.h" #include "HTMLAnchorElement.h" #include "HTMLAreaElement.h" #include "HTMLElement.h" -- cgit v1.1 From 3f90f816703cdd04faefa355606c1b4635e8fb04 Mon Sep 17 00:00:00 2001 From: John Reck Date: Mon, 13 Aug 2012 15:32:16 -0700 Subject: Null check Bug: 6975836 Change-Id: I085e2099d016730ba1fdcce71e0452b2026c9617 --- .../platform/graphics/android/context/GraphicsContextAndroid.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/WebCore/platform/graphics/android/context/GraphicsContextAndroid.cpp b/Source/WebCore/platform/graphics/android/context/GraphicsContextAndroid.cpp index 23b22e6..957040b 100644 --- a/Source/WebCore/platform/graphics/android/context/GraphicsContextAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/context/GraphicsContextAndroid.cpp @@ -59,7 +59,7 @@ public: : m_context(platformContext) { } ~GraphicsContextPlatformPrivate() { - if (m_context->deleteUs()) + if (m_context && m_context->deleteUs()) delete m_context; } -- cgit v1.1