summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Reck <jreck@google.com>2012-07-30 16:45:46 -0700
committerJohn Reck <jreck@google.com>2012-07-31 17:02:41 -0700
commitd9779adc025ab665fde1c9983e7793e96ab56d4e (patch)
treedef08809ec911452fdbbb54ce6021facde00d788
parentc514bacb0f4890026568d104f85ebba563bbe930 (diff)
downloadexternal_webkit-d9779adc025ab665fde1c9983e7793e96ab56d4e.zip
external_webkit-d9779adc025ab665fde1c9983e7793e96ab56d4e.tar.gz
external_webkit-d9779adc025ab665fde1c9983e7793e96ab56d4e.tar.bz2
Switch GraphicsOperation to LinearAllocator
Change-Id: I9afb489c55a7acfdc35cfe8655d46ce47923b3df
-rw-r--r--Source/WebCore/Android.mk1
-rw-r--r--Source/WebCore/platform/graphics/android/context/GraphicsOperation.cpp55
-rw-r--r--Source/WebCore/platform/graphics/android/context/GraphicsOperation.h18
-rw-r--r--Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp112
-rw-r--r--Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.h4
-rw-r--r--Source/WebCore/platform/graphics/android/context/RTree.cpp6
-rw-r--r--Source/WebCore/platform/graphics/android/context/RTree.h2
-rw-r--r--Source/WebCore/platform/graphics/android/utils/LinearAllocator.cpp84
-rw-r--r--Source/WebCore/platform/graphics/android/utils/LinearAllocator.h11
9 files changed, 199 insertions, 94 deletions
diff --git a/Source/WebCore/Android.mk b/Source/WebCore/Android.mk
index cd5764f..10eb822 100644
--- a/Source/WebCore/Android.mk
+++ b/Source/WebCore/Android.mk
@@ -642,6 +642,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
platform/graphics/android/SharedBufferStream.cpp \
\
platform/graphics/android/context/GraphicsContextAndroid.cpp \
+ platform/graphics/android/context/GraphicsOperation.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.cpp b/Source/WebCore/platform/graphics/android/context/GraphicsOperation.cpp
new file mode 100644
index 0000000..ab6e676
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/context/GraphicsOperation.cpp
@@ -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.
+ */
+#define LOG_TAG "GraphicsOperation"
+
+#include "config.h"
+#include "GraphicsOperation.h"
+
+#include "AndroidLog.h"
+#include "LinearAllocator.h"
+
+namespace WebCore {
+namespace GraphicsOperation {
+
+void* Operation::operator new(size_t size, LinearAllocator* allocator)
+{
+ return allocator->alloc(size);
+}
+
+void* Operation::operator new(size_t size)
+{
+ ALOGE("Cannot allocate a new Operation directly!");
+ CRASH();
+ return (void*) 0xBADBEEF;
+}
+
+void Operation::operator delete(void*)
+{
+ ALOGE("Cannot call delete on an Operation!");
+ CRASH();
+}
+
+} // namespace GraphicsOperation
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/context/GraphicsOperation.h b/Source/WebCore/platform/graphics/android/context/GraphicsOperation.h
index 604206b..4d2c634 100644
--- a/Source/WebCore/platform/graphics/android/context/GraphicsOperation.h
+++ b/Source/WebCore/platform/graphics/android/context/GraphicsOperation.h
@@ -45,6 +45,7 @@
namespace WebCore {
class CanvasState;
+class LinearAllocator;
namespace GraphicsOperation {
@@ -87,6 +88,12 @@ public:
, m_canvasState(0)
{}
+ void* operator new(size_t size, LinearAllocator* allocator);
+
+ // Purposely not implemented - use a LinearAllocator please
+ void* operator new(size_t size);
+ void operator delete(void* ptr);
+
// This m_state is applied by ourselves
PlatformGraphicsContext::State* m_state;
// This is the canvas state that this operation needs
@@ -102,7 +109,6 @@ public:
virtual bool applyImpl(PlatformGraphicsContext* context) = 0;
virtual ~Operation() {}
virtual OperationType type() { return UndefinedOperation; }
- virtual String parameters() { return ""; }
virtual void subtractOpaqueClip(FloatRect& clip) {}
const char* name()
{
@@ -220,11 +226,6 @@ public:
return context->clip(m_rect);
}
virtual OperationType type() { return ClipOperation; }
- virtual String parameters() {
- return String::format("[x=%.2f,y=%.2f,w=%.2f,h=%.2f]",
- m_rect.x(), m_rect.y(),
- m_rect.width(), m_rect.height());
- }
private:
const FloatRect m_rect;
};
@@ -305,11 +306,6 @@ public:
return true;
}
virtual OperationType type() { return DrawBitmapRectOperation; }
- virtual String parameters() {
- return String::format("%.2f, %.2f - %.2f x %.2f",
- m_dstR.fLeft, m_dstR.fTop,
- m_dstR.width(), m_dstR.height());
- }
private:
SkBitmap m_bitmap;
SkIRect m_srcR;
diff --git a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp
index a2163ce..42f8400 100644
--- a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp
+++ b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp
@@ -35,6 +35,7 @@
#include "Font.h"
#include "GraphicsContext.h"
#include "GraphicsOperation.h"
+#include "LinearAllocator.h"
#include "PlatformGraphicsContextSkia.h"
#include "RTree.h"
@@ -42,6 +43,8 @@
#include "wtf/HashSet.h"
#include "wtf/StringHasher.h"
+#define NEW_OP(X) new (operationHeap()) GraphicsOperation::X
+
namespace WebCore {
static FloatRect approximateTextBounds(size_t numGlyphs,
@@ -164,6 +167,10 @@ public:
return m_isTransparencyLayer;
}
+ void* operator new(size_t size, LinearAllocator* la) {
+ return la->alloc(size);
+ }
+
private:
CanvasState *m_parent;
bool m_isTransparencyLayer;
@@ -172,9 +179,18 @@ private:
};
class RecordingImpl {
+private:
+ // Careful, ordering matters here. Ordering is first constructed == last destroyed,
+ // so we have to make sure our Heap is the first thing listed so that it is
+ // the last thing destroyed.
+ LinearAllocator m_operationHeap;
+ LinearAllocator m_canvasStateHeap;
+ LinearAllocator m_stateHeap;
public:
RecordingImpl()
- : m_nodeCount(0)
+ : m_canvasStateHeap(sizeof(CanvasState))
+ , m_stateHeap(sizeof(PlatformGraphicsContext::State))
+ , m_nodeCount(0)
{
}
@@ -187,8 +203,8 @@ public:
StateHashSet::iterator it = m_states.find(inState);
if (it != m_states.end())
return (*it);
- // TODO: Use a custom allocator
- PlatformGraphicsContext::State* state = new PlatformGraphicsContext::State(*inState);
+ void* buf = m_stateHeap.alloc(sizeof(PlatformGraphicsContext::State));
+ PlatformGraphicsContext::State* state = new (buf) PlatformGraphicsContext::State(*inState);
m_states.add(state);
return state;
}
@@ -236,6 +252,9 @@ public:
toState->playback(context, fromId, toId);
}
+ LinearAllocator* operationHeap() { return &m_operationHeap; }
+ LinearAllocator* canvasStateHeap() { return &m_canvasStateHeap; }
+
RTree::RTree m_tree;
int m_nodeCount;
@@ -244,13 +263,13 @@ private:
void clearStates() {
StateHashSet::iterator end = m_states.end();
for (StateHashSet::iterator it = m_states.begin(); it != end; ++it)
- delete (*it);
+ (*it)->~State();
m_states.clear();
}
void clearCanvasStates() {
for (size_t i = 0; i < m_canvasStates.size(); i++)
- delete m_canvasStates[i];
+ m_canvasStates[i]->~CanvasState();
m_canvasStates.clear();
}
@@ -299,7 +318,7 @@ void Recording::draw(SkCanvas* canvas)
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());
+ ALOGV("apply: %p->%s()", op, op->name());
op->apply(&context);
}
while (currState) {
@@ -338,7 +357,7 @@ PlatformGraphicsContextRecording::PlatformGraphicsContextRecording(Recording* re
mRecording->setRecording(new RecordingImpl());
mMatrixStack.append(SkMatrix::I());
mCurrentMatrix = &(mMatrixStack.last());
- pushStateOperation(new CanvasState(0));
+ pushStateOperation(new (canvasStateHeap()) CanvasState(0));
}
bool PlatformGraphicsContextRecording::isPaintingDisabled()
@@ -359,7 +378,7 @@ SkCanvas* PlatformGraphicsContextRecording::recordingCanvas()
void PlatformGraphicsContextRecording::beginTransparencyLayer(float opacity)
{
CanvasState* parent = mRecordingStateStack.last().mCanvasState;
- pushStateOperation(new CanvasState(parent, opacity));
+ pushStateOperation(new (canvasStateHeap()) CanvasState(parent, opacity));
}
void PlatformGraphicsContextRecording::endTransparencyLayer()
@@ -371,7 +390,7 @@ void PlatformGraphicsContextRecording::save()
{
PlatformGraphicsContext::save();
CanvasState* parent = mRecordingStateStack.last().mCanvasState;
- pushStateOperation(new CanvasState(parent));
+ pushStateOperation(new (canvasStateHeap()) CanvasState(parent));
pushMatrix();
}
@@ -490,26 +509,26 @@ void PlatformGraphicsContextRecording::setStrokeThickness(float f)
void PlatformGraphicsContextRecording::concatCTM(const AffineTransform& affine)
{
mCurrentMatrix->preConcat(affine);
- appendStateOperation(new GraphicsOperation::ConcatCTM(affine));
+ appendStateOperation(NEW_OP(ConcatCTM)(affine));
}
void PlatformGraphicsContextRecording::rotate(float angleInRadians)
{
float value = angleInRadians * (180.0f / 3.14159265f);
mCurrentMatrix->preRotate(SkFloatToScalar(value));
- appendStateOperation(new GraphicsOperation::Rotate(angleInRadians));
+ appendStateOperation(NEW_OP(Rotate)(angleInRadians));
}
void PlatformGraphicsContextRecording::scale(const FloatSize& size)
{
mCurrentMatrix->preScale(SkFloatToScalar(size.width()), SkFloatToScalar(size.height()));
- appendStateOperation(new GraphicsOperation::Scale(size));
+ appendStateOperation(NEW_OP(Scale)(size));
}
void PlatformGraphicsContextRecording::translate(float x, float y)
{
mCurrentMatrix->preTranslate(SkFloatToScalar(x), SkFloatToScalar(y));
- appendStateOperation(new GraphicsOperation::Translate(x, y));
+ appendStateOperation(NEW_OP(Translate)(x, y));
}
const SkMatrix& PlatformGraphicsContextRecording::getTotalMatrix()
@@ -524,7 +543,7 @@ const SkMatrix& PlatformGraphicsContextRecording::getTotalMatrix()
void PlatformGraphicsContextRecording::addInnerRoundedRectClip(const IntRect& rect,
int thickness)
{
- appendStateOperation(new GraphicsOperation::InnerRoundedRectClip(rect, thickness));
+ appendStateOperation(NEW_OP(InnerRoundedRectClip)(rect, thickness));
}
void PlatformGraphicsContextRecording::canvasClip(const Path& path)
@@ -535,14 +554,14 @@ void PlatformGraphicsContextRecording::canvasClip(const Path& path)
bool PlatformGraphicsContextRecording::clip(const FloatRect& rect)
{
clipState(rect);
- appendStateOperation(new GraphicsOperation::Clip(rect));
+ appendStateOperation(NEW_OP(Clip)(rect));
return true;
}
bool PlatformGraphicsContextRecording::clip(const Path& path)
{
clipState(path.boundingRect());
- appendStateOperation(new GraphicsOperation::ClipPath(path));
+ appendStateOperation(NEW_OP(ClipPath)(path));
return true;
}
@@ -555,20 +574,20 @@ bool PlatformGraphicsContextRecording::clipConvexPolygon(size_t numPoints,
bool PlatformGraphicsContextRecording::clipOut(const IntRect& r)
{
- appendStateOperation(new GraphicsOperation::ClipOut(r));
+ appendStateOperation(NEW_OP(ClipOut)(r));
return true;
}
bool PlatformGraphicsContextRecording::clipOut(const Path& path)
{
- appendStateOperation(new GraphicsOperation::ClipPath(path, true));
+ appendStateOperation(NEW_OP(ClipPath)(path, true));
return true;
}
bool PlatformGraphicsContextRecording::clipPath(const Path& pathToClip, WindRule clipRule)
{
clipState(pathToClip.boundingRect());
- GraphicsOperation::ClipPath* operation = new GraphicsOperation::ClipPath(pathToClip);
+ GraphicsOperation::ClipPath* operation = NEW_OP(ClipPath)(pathToClip);
operation->setWindRule(clipRule);
appendStateOperation(operation);
return true;
@@ -576,7 +595,7 @@ bool PlatformGraphicsContextRecording::clipPath(const Path& pathToClip, WindRule
void PlatformGraphicsContextRecording::clearRect(const FloatRect& rect)
{
- appendDrawingOperation(new GraphicsOperation::ClearRect(rect), rect);
+ appendDrawingOperation(NEW_OP(ClearRect)(rect), rect);
}
//**************************************
@@ -588,7 +607,7 @@ void PlatformGraphicsContextRecording::drawBitmapPattern(
CompositeOperator compositeOp, const FloatRect& destRect)
{
appendDrawingOperation(
- new GraphicsOperation::DrawBitmapPattern(bitmap, matrix, compositeOp, destRect),
+ NEW_OP(DrawBitmapPattern)(bitmap, matrix, compositeOp, destRect),
destRect);
}
@@ -596,7 +615,7 @@ void PlatformGraphicsContextRecording::drawBitmapRect(const SkBitmap& bitmap,
const SkIRect* src, const SkRect& dst,
CompositeOperator op)
{
- appendDrawingOperation(new GraphicsOperation::DrawBitmapRect(bitmap, *src, dst, op), dst);
+ appendDrawingOperation(NEW_OP(DrawBitmapRect)(bitmap, *src, dst, op), dst);
}
void PlatformGraphicsContextRecording::drawConvexPolygon(size_t numPoints,
@@ -611,12 +630,12 @@ void PlatformGraphicsContextRecording::drawConvexPolygon(size_t numPoints,
}
FloatRect bounds;
bounds.fitToPoints(points[0], points[1], points[2], points[3]);
- appendDrawingOperation(new GraphicsOperation::DrawConvexPolygonQuad(points, shouldAntialias), bounds);
+ appendDrawingOperation(NEW_OP(DrawConvexPolygonQuad)(points, shouldAntialias), bounds);
}
void PlatformGraphicsContextRecording::drawEllipse(const IntRect& rect)
{
- appendDrawingOperation(new GraphicsOperation::DrawEllipse(rect), rect);
+ appendDrawingOperation(NEW_OP(DrawEllipse)(rect), rect);
}
void PlatformGraphicsContextRecording::drawFocusRing(const Vector<IntRect>& rects,
@@ -628,7 +647,7 @@ void PlatformGraphicsContextRecording::drawFocusRing(const Vector<IntRect>& rect
IntRect bounds = rects[0];
for (size_t i = 1; i < rects.size(); i++)
bounds.unite(rects[i]);
- appendDrawingOperation(new GraphicsOperation::DrawFocusRing(rects, width, offset, color), bounds);
+ appendDrawingOperation(NEW_OP(DrawFocusRing)(rects, width, offset, color), bounds);
}
void PlatformGraphicsContextRecording::drawHighlightForText(
@@ -657,41 +676,41 @@ void PlatformGraphicsContextRecording::drawLine(const IntPoint& point1,
float width = m_state->strokeThickness;
if (!width) width = 1;
bounds.inflate(width);
- appendDrawingOperation(new GraphicsOperation::DrawLine(point1, point2), bounds);
+ appendDrawingOperation(NEW_OP(DrawLine)(point1, point2), bounds);
}
void PlatformGraphicsContextRecording::drawLineForText(const FloatPoint& pt, float width)
{
FloatRect bounds(pt.x(), pt.y(), width, m_state->strokeThickness);
- appendDrawingOperation(new GraphicsOperation::DrawLineForText(pt, width), bounds);
+ appendDrawingOperation(NEW_OP(DrawLineForText)(pt, width), bounds);
}
void PlatformGraphicsContextRecording::drawLineForTextChecking(const FloatPoint& pt,
float width, GraphicsContext::TextCheckingLineStyle lineStyle)
{
FloatRect bounds(pt.x(), pt.y(), width, m_state->strokeThickness);
- appendDrawingOperation(new GraphicsOperation::DrawLineForTextChecking(pt, width, lineStyle), bounds);
+ appendDrawingOperation(NEW_OP(DrawLineForTextChecking)(pt, width, lineStyle), bounds);
}
void PlatformGraphicsContextRecording::drawRect(const IntRect& rect)
{
- appendDrawingOperation(new GraphicsOperation::DrawRect(rect), rect);
+ appendDrawingOperation(NEW_OP(DrawRect)(rect), rect);
}
void PlatformGraphicsContextRecording::fillPath(const Path& pathToFill, WindRule fillRule)
{
- appendDrawingOperation(new GraphicsOperation::FillPath(pathToFill, fillRule), pathToFill.boundingRect());
+ appendDrawingOperation(NEW_OP(FillPath)(pathToFill, fillRule), pathToFill.boundingRect());
}
void PlatformGraphicsContextRecording::fillRect(const FloatRect& rect)
{
- appendDrawingOperation(new GraphicsOperation::FillRect(rect), rect);
+ appendDrawingOperation(NEW_OP(FillRect)(rect), rect);
}
void PlatformGraphicsContextRecording::fillRect(const FloatRect& rect,
const Color& color)
{
- GraphicsOperation::FillRect* operation = new GraphicsOperation::FillRect(rect);
+ GraphicsOperation::FillRect* operation = NEW_OP(FillRect)(rect);
operation->setColor(color);
appendDrawingOperation(operation, rect);
}
@@ -701,26 +720,26 @@ void PlatformGraphicsContextRecording::fillRoundedRect(
const IntSize& bottomLeft, const IntSize& bottomRight,
const Color& color)
{
- appendDrawingOperation(new GraphicsOperation::FillRoundedRect(rect, topLeft,
+ appendDrawingOperation(NEW_OP(FillRoundedRect)(rect, topLeft,
topRight, bottomLeft, bottomRight, color), rect);
}
void PlatformGraphicsContextRecording::strokeArc(const IntRect& r, int startAngle,
int angleSpan)
{
- appendDrawingOperation(new GraphicsOperation::StrokeArc(r, startAngle, angleSpan), r);
+ appendDrawingOperation(NEW_OP(StrokeArc)(r, startAngle, angleSpan), r);
}
void PlatformGraphicsContextRecording::strokePath(const Path& pathToStroke)
{
- appendDrawingOperation(new GraphicsOperation::StrokePath(pathToStroke), pathToStroke.boundingRect());
+ appendDrawingOperation(NEW_OP(StrokePath)(pathToStroke), pathToStroke.boundingRect());
}
void PlatformGraphicsContextRecording::strokeRect(const FloatRect& rect, float lineWidth)
{
FloatRect bounds = rect;
bounds.inflate(lineWidth);
- appendDrawingOperation(new GraphicsOperation::StrokeRect(rect, lineWidth), bounds);
+ appendDrawingOperation(NEW_OP(StrokeRect)(rect, lineWidth), bounds);
}
void PlatformGraphicsContextRecording::drawPosText(const void* text, size_t byteLength,
@@ -730,7 +749,7 @@ void PlatformGraphicsContextRecording::drawPosText(const void* text, size_t byte
ALOGE("Unsupported text encoding! %d", paint.getTextEncoding());
}
FloatRect bounds = approximateTextBounds(byteLength / sizeof(uint16_t), pos, paint);
- appendDrawingOperation(new GraphicsOperation::DrawPosText(text, byteLength, pos, paint), bounds);
+ appendDrawingOperation(NEW_OP(DrawPosText)(text, byteLength, pos, paint), bounds);
}
void PlatformGraphicsContextRecording::clipState(const FloatRect& clip)
@@ -757,7 +776,8 @@ void PlatformGraphicsContextRecording::popStateOperation()
ALOGV("popStateOperation is deleting %p(isLayer=%d)",
state.mCanvasState, state.mCanvasState->isTransparencyLayer());
mRecording->recording()->removeCanvasState(state.mCanvasState);
- delete state.mCanvasState;
+ state.mCanvasState->~CanvasState();
+ canvasStateHeap()->rewindTo(state.mCanvasState);
} else {
ALOGV("popStateOperation: %p(isLayer=%d)",
state.mCanvasState, state.mCanvasState->isTransparencyLayer());
@@ -824,9 +844,9 @@ void PlatformGraphicsContextRecording::appendDrawingOperation(
WebCore::IntRect ibounds = calculateFinalBounds(untranslatedBounds);
if (ibounds.isEmpty()) {
- ALOGV("Operation %s(%s) was clipped out", operation->name(),
- operation->parameters().ascii().data());
- delete operation;
+ ALOGV("Operation %s() was clipped out", operation->name());
+ operation->~Operation();
+ operationHeap()->rewindTo(operation);
return;
}
ALOGV("appendOperation %p->%s()", operation, operation->name());
@@ -842,4 +862,14 @@ void PlatformGraphicsContextRecording::appendStateOperation(GraphicsOperation::O
mRecordingStateStack.last().mCanvasState->adoptAndAppend(data);
}
+LinearAllocator* PlatformGraphicsContextRecording::operationHeap()
+{
+ return mRecording->recording()->operationHeap();
+}
+
+LinearAllocator* PlatformGraphicsContextRecording::canvasStateHeap()
+{
+ return mRecording->recording()->canvasStateHeap();
+}
+
} // WebCore
diff --git a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.h b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.h
index 3af1e2f..991e13f 100644
--- a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.h
+++ b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.h
@@ -37,7 +37,9 @@ class Operation;
}
class CanvasState;
+class LinearAllocator;
class RecordingImpl;
+
class Recording : public SkRefCnt {
public:
Recording()
@@ -152,6 +154,8 @@ private:
void pushMatrix();
void popMatrix();
IntRect calculateFinalBounds(FloatRect bounds);
+ LinearAllocator* operationHeap();
+ LinearAllocator* canvasStateHeap();
SkPicture* mPicture;
SkMatrix* mCurrentMatrix;
diff --git a/Source/WebCore/platform/graphics/android/context/RTree.cpp b/Source/WebCore/platform/graphics/android/context/RTree.cpp
index c6b9854..9512ffe 100644
--- a/Source/WebCore/platform/graphics/android/context/RTree.cpp
+++ b/Source/WebCore/platform/graphics/android/context/RTree.cpp
@@ -166,15 +166,13 @@ void RTree::display()
void* RTree::allocateNode()
{
- return m_allocator->alloc();
+ return m_allocator->alloc(sizeof(Node));
}
void RTree::deleteNode(Node* n)
{
- if (n) {
+ if (n)
n->~Node();
- m_allocator->dealloc(n);
- }
}
//////////////////////////////////////////////////////////////////////
diff --git a/Source/WebCore/platform/graphics/android/context/RTree.h b/Source/WebCore/platform/graphics/android/context/RTree.h
index 4ad8986..2a460d6 100644
--- a/Source/WebCore/platform/graphics/android/context/RTree.h
+++ b/Source/WebCore/platform/graphics/android/context/RTree.h
@@ -41,7 +41,7 @@ public:
, m_operation(ops)
{}
~RecordingData() {
- delete m_operation;
+ m_operation->~Operation();
}
size_t m_orderBy;
diff --git a/Source/WebCore/platform/graphics/android/utils/LinearAllocator.cpp b/Source/WebCore/platform/graphics/android/utils/LinearAllocator.cpp
index e7617b1..1899557 100644
--- a/Source/WebCore/platform/graphics/android/utils/LinearAllocator.cpp
+++ b/Source/WebCore/platform/graphics/android/utils/LinearAllocator.cpp
@@ -27,7 +27,6 @@
#define LOG_NDEBUG 1
#include "config.h"
-
#include "LinearAllocator.h"
#include "AndroidLog.h"
@@ -40,6 +39,33 @@ namespace WebCore {
// our pool needs to big enough to hold at least this many items
#define MIN_OBJECT_COUNT 4
+#if LOG_NDEBUG
+#define ADD_ALLOCATION(size)
+#define RM_ALLOCATION(size)
+#else
+#include <utils/Thread.h>
+static size_t s_totalAllocations = 0;
+static double s_lastLogged = 0;
+static android::Mutex s_mutex;
+
+static void _logUsageLocked() {
+ double now = currentTimeMS();
+ if (now - s_lastLogged > 5) {
+ s_lastLogged = now;
+ ALOGV("Total memory usage: %d kb", s_totalAllocations / 1024);
+ }
+}
+
+static void _addAllocation(size_t size) {
+ android::AutoMutex lock(s_mutex);
+ s_totalAllocations += size;
+ _logUsageLocked();
+}
+
+#define ADD_ALLOCATION(size) _addAllocation(size);
+#define RM_ALLOCATION(size) _addAllocation(-size);
+#endif
+
class LinearAllocator::Page {
public:
Page* next() { return m_nextPage; }
@@ -64,30 +90,29 @@ private:
Page* m_nextPage;
};
-LinearAllocator::LinearAllocator(size_t allocSize)
- : m_allocSize(allocSize)
- , m_allocCount(0)
- , m_next(0)
+LinearAllocator::LinearAllocator(size_t averageAllocSize)
+ : m_next(0)
, m_currentPage(0)
, m_pages(0)
{
- int usable_page_size = TARGET_PAGE_SIZE - sizeof(LinearAllocator::Page);
- int pcount = usable_page_size / allocSize;
- if (pcount < MIN_OBJECT_COUNT)
- pcount = MIN_OBJECT_COUNT;
- m_pageSize = pcount * allocSize + sizeof(LinearAllocator::Page);
+ if (averageAllocSize) {
+ int usable_page_size = TARGET_PAGE_SIZE - sizeof(LinearAllocator::Page);
+ int pcount = usable_page_size / averageAllocSize;
+ if (pcount < MIN_OBJECT_COUNT)
+ pcount = MIN_OBJECT_COUNT;
+ m_pageSize = pcount * averageAllocSize + sizeof(LinearAllocator::Page);
+ } else
+ m_pageSize = TARGET_PAGE_SIZE;
+ m_maxAllocSize = (m_pageSize - sizeof(LinearAllocator::Page));
}
LinearAllocator::~LinearAllocator(void)
{
- if (m_allocCount)
- ALOGW("Leaked allocations!");
- IF_ALOGV()
- ALOGV("Freeing to %dkb", memusage() >> 10);
Page* p = m_pages;
while (p) {
Page* next = p->next();
delete p;
+ RM_ALLOCATION(m_pageSize);
p = next;
}
}
@@ -102,9 +127,9 @@ void* LinearAllocator::end(Page* p)
return ((char*)p) + m_pageSize;
}
-void LinearAllocator::ensureNext()
+void LinearAllocator::ensureNext(size_t size)
{
- if (m_next && m_next < end(m_currentPage))
+ if (m_next && ((char*)m_next + size) <= end(m_currentPage))
return;
Page* p = newPage();
if (m_currentPage)
@@ -113,9 +138,6 @@ void LinearAllocator::ensureNext()
if (!m_pages)
m_pages = m_currentPage;
m_next = start(m_currentPage);
-
- IF_ALOGV()
- ALOGV("Allocator grew to %dkb", memusage() >> 10);
}
unsigned LinearAllocator::memusage()
@@ -129,28 +151,28 @@ unsigned LinearAllocator::memusage()
return memusage;
}
-void* LinearAllocator::alloc()
+void* LinearAllocator::alloc(size_t size)
{
- m_allocCount++;
- ensureNext();
+ if (size > m_maxAllocSize) {
+ ALOGE("Allocation too large! (%d exceeds max size %d)", size, m_maxAllocSize);
+ return 0;
+ }
+ ensureNext(size);
void* ptr = m_next;
- m_next = ((char*)m_next) + m_allocSize;
+ m_next = ((char*)m_next) + size;
return ptr;
}
-void LinearAllocator::dealloc(void* ptr)
+void LinearAllocator::rewindTo(void* ptr)
{
- m_allocCount--;
- if (m_next > start(m_currentPage)) {
- // If this happened to be the previous allocation, just rewind m_next
- void* prev = ((char*)m_next) - m_allocSize;
- if (ptr == prev)
- m_next = prev;
- }
+ // Don't bother rewinding across pages
+ if (ptr >= start(m_currentPage) && ptr < end(m_currentPage))
+ m_next = ptr;
}
LinearAllocator::Page* LinearAllocator::newPage()
{
+ ADD_ALLOCATION(m_pageSize);
void* buf = malloc(m_pageSize);
return new (buf) Page();
}
diff --git a/Source/WebCore/platform/graphics/android/utils/LinearAllocator.h b/Source/WebCore/platform/graphics/android/utils/LinearAllocator.h
index b0c584b..1f3265c 100644
--- a/Source/WebCore/platform/graphics/android/utils/LinearAllocator.h
+++ b/Source/WebCore/platform/graphics/android/utils/LinearAllocator.h
@@ -31,11 +31,11 @@ namespace WebCore {
class LinearAllocator
{
public:
- LinearAllocator(size_t allocSize);
+ LinearAllocator(size_t averageAllocSize = 0);
~LinearAllocator();
- void* alloc();
- void dealloc(void*);
+ void* alloc(size_t size);
+ void rewindTo(void*);
private:
LinearAllocator(const LinearAllocator& other);
@@ -43,15 +43,14 @@ private:
class Page;
Page* newPage();
- void ensureNext();
+ void ensureNext(size_t size);
void* start(Page *p);
void* end(Page* p);
unsigned memusage();
- size_t m_allocSize;
- size_t m_allocCount;
size_t m_pageSize;
+ size_t m_maxAllocSize;
void* m_next;
Page* m_currentPage;
Page* m_pages;