summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Reck <jreck@google.com>2012-07-24 20:16:08 -0700
committerJohn Reck <jreck@google.com>2012-07-26 17:18:15 -0700
commit8f7bdaae7030fbbfd3c3cde0a8b0e8d489d0b14f (patch)
treeef5b80aabc262486b83f66830a9726a5a01e8aaa
parent2bbb442aa27ea29ef6337eba9021ea509400cb84 (diff)
downloadexternal_webkit-8f7bdaae7030fbbfd3c3cde0a8b0e8d489d0b14f.zip
external_webkit-8f7bdaae7030fbbfd3c3cde0a8b0e8d489d0b14f.tar.gz
external_webkit-8f7bdaae7030fbbfd3c3cde0a8b0e8d489d0b14f.tar.bz2
Push everything into an R-Tree
Change-Id: Ifbfd0b91eb9fab057c2a91d740325b598b2d617a
-rw-r--r--Source/WebCore/Android.mk1
-rw-r--r--Source/WebCore/platform/graphics/android/context/GraphicsOperation.h282
-rw-r--r--Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.cpp84
-rw-r--r--Source/WebCore/platform/graphics/android/context/GraphicsOperationCollection.h61
-rw-r--r--Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp305
-rw-r--r--Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.h34
-rw-r--r--Source/WebCore/platform/graphics/android/context/RTree.h4
-rw-r--r--Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp1
-rw-r--r--Source/WebKit/android/jni/PicturePile.cpp1
-rw-r--r--Source/WebKit/android/jni/WebViewCore.cpp1
10 files changed, 233 insertions, 541 deletions
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<GraphicsOperation::Operation*> 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<PlatformGraphicsContext::State*, StateHash> 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<RecordingData*> 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<SkMatrix*> m_matrixes;
+ Vector<CanvasState*> 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<RecordingState> mRecordingStateStack;
Vector<SkMatrix> 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"