summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Reck <jreck@google.com>2012-08-14 11:13:34 -0700
committerJohn Reck <jreck@google.com>2012-08-14 11:24:14 -0700
commitb0a56fa335e9435238de5f2cde15076488057c52 (patch)
tree40d559862fe06c55273a8c03482a9c48d0096ee9
parentfcadd7a73d414109c41d46fcad0d199ddc656a34 (diff)
downloadexternal_webkit-b0a56fa335e9435238de5f2cde15076488057c52.zip
external_webkit-b0a56fa335e9435238de5f2cde15076488057c52.tar.gz
external_webkit-b0a56fa335e9435238de5f2cde15076488057c52.tar.bz2
Memory usage improvements
Share SkPaints between drawPosText calls Change-Id: Idf25c937a70e2969a864c829e566688b977720c0
-rw-r--r--Source/WebCore/platform/graphics/android/context/GraphicsOperation.h8
-rw-r--r--Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp51
2 files changed, 49 insertions, 10 deletions
diff --git a/Source/WebCore/platform/graphics/android/context/GraphicsOperation.h b/Source/WebCore/platform/graphics/android/context/GraphicsOperation.h
index c9c382a..c70c295 100644
--- a/Source/WebCore/platform/graphics/android/context/GraphicsOperation.h
+++ b/Source/WebCore/platform/graphics/android/context/GraphicsOperation.h
@@ -586,11 +586,11 @@ private:
class DrawPosText : public Operation {
public:
DrawPosText(const void* text, size_t byteLength,
- const SkPoint pos[], const SkPaint& paint)
+ const SkPoint pos[], const SkPaint* paint)
: m_byteLength(byteLength)
, m_paint(paint)
{
- size_t points = paint.countText(text, byteLength);
+ size_t points = m_paint->countText(text, byteLength);
m_pos = new SkPoint[points];
memcpy(m_pos, pos, sizeof(SkPoint) * points);
m_text = malloc(byteLength);
@@ -598,7 +598,7 @@ public:
}
~DrawPosText() { delete m_pos; free(m_text); }
virtual bool applyImpl(PlatformGraphicsContext* context) {
- context->drawPosText(m_text, m_byteLength, m_pos, m_paint);
+ context->drawPosText(m_text, m_byteLength, m_pos, *m_paint);
return true;
}
TYPE(DrawPosTextOperation)
@@ -606,7 +606,7 @@ private:
void* m_text;
size_t m_byteLength;
SkPoint* m_pos;
- SkPaint m_paint;
+ const SkPaint* m_paint;
};
}
diff --git a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp
index 5efecd8..24ee47e 100644
--- a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp
+++ b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp
@@ -98,7 +98,24 @@ public:
static const bool safeToCompareToEmptyOrDeleted = false;
};
+class SkPaintHash {
+public:
+ static unsigned hash(const SkPaint* const& paint)
+ {
+ return StringHasher::hashMemory(paint, sizeof(SkPaint));
+ }
+
+ static bool equal(const SkPaint* const& a,
+ const SkPaint* const& b)
+ {
+ return a && b && (*a == *b);
+ }
+
+ static const bool safeToCompareToEmptyOrDeleted = false;
+};
+
typedef HashSet<PlatformGraphicsContext::State*, StateHash> StateHashSet;
+typedef HashSet<const SkPaint*, SkPaintHash> SkPaintHashSet;
class CanvasState {
public:
@@ -187,11 +204,13 @@ private:
// the last thing destroyed.
LinearAllocator m_operationHeap;
LinearAllocator m_canvasStateHeap;
+ // Used by both PlatformGraphicsContext::State and SkPaint, as both are
+ // roughly the same size (72 bytes vs. 76 bytes, respectively)
LinearAllocator m_stateHeap;
public:
RecordingImpl()
: m_canvasStateHeap(sizeof(CanvasState))
- , m_stateHeap(sizeof(PlatformGraphicsContext::State))
+ , m_stateHeap(sizeof(SkPaint))
, m_nodeCount(0)
{
}
@@ -199,6 +218,7 @@ public:
~RecordingImpl() {
clearStates();
clearCanvasStates();
+ clearSkPaints();
}
PlatformGraphicsContext::State* getState(PlatformGraphicsContext::State* inState) {
@@ -211,6 +231,16 @@ public:
return state;
}
+ const SkPaint* getSkPaint(const SkPaint& inPaint) {
+ SkPaintHashSet::iterator it = m_paints.find(&inPaint);
+ if (it != m_paints.end())
+ return (*it);
+ void* buf = m_stateHeap.alloc(sizeof(SkPaint));
+ SkPaint* paint = new (buf) SkPaint(inPaint);
+ m_paints.add(paint);
+ return paint;
+ }
+
void addCanvasState(CanvasState* state) {
m_canvasStates.append(state);
}
@@ -269,14 +299,21 @@ private:
m_states.clear();
}
+ void clearSkPaints() {
+ SkPaintHashSet::iterator end = m_paints.end();
+ for (SkPaintHashSet::iterator it = m_paints.begin(); it != end; ++it)
+ (*it)->~SkPaint();
+ m_paints.clear();
+ }
+
void clearCanvasStates() {
for (size_t i = 0; i < m_canvasStates.size(); i++)
m_canvasStates[i]->~CanvasState();
m_canvasStates.clear();
}
- // TODO: Use a global pool?
StateHashSet m_states;
+ SkPaintHashSet m_paints;
Vector<CanvasState*> m_canvasStates;
};
@@ -855,12 +892,14 @@ void PlatformGraphicsContextRecording::strokeRect(const FloatRect& rect, float l
}
void PlatformGraphicsContextRecording::drawPosText(const void* text, size_t byteLength,
- const SkPoint pos[], const SkPaint& paint)
+ const SkPoint pos[], const SkPaint& inPaint)
{
- if (paint.getTextEncoding() != SkPaint::kGlyphID_TextEncoding) {
- ALOGE("Unsupported text encoding! %d", paint.getTextEncoding());
+ if (inPaint.getTextEncoding() != SkPaint::kGlyphID_TextEncoding) {
+ ALOGE("Unsupported text encoding! %d", inPaint.getTextEncoding());
+ return;
}
- FloatRect bounds = approximateTextBounds(byteLength / sizeof(uint16_t), pos, paint);
+ FloatRect bounds = approximateTextBounds(byteLength / sizeof(uint16_t), pos, inPaint);
+ const SkPaint* paint = mRecording->recording()->getSkPaint(inPaint);
appendDrawingOperation(NEW_OP(DrawPosText)(text, byteLength, pos, paint), bounds);
}