summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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.h119
-rw-r--r--Source/WebCore/platform/graphics/android/context/PlatformGraphicsContext.cpp6
-rw-r--r--Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp113
-rw-r--r--Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.h4
-rw-r--r--Source/WebCore/platform/graphics/android/context/RTree.cpp61
-rw-r--r--Source/WebCore/platform/graphics/android/context/RTree.h7
-rw-r--r--Source/WebCore/platform/graphics/android/utils/LinearAllocator.cpp84
-rw-r--r--Source/WebCore/platform/graphics/android/utils/LinearAllocator.h11
-rwxr-xr-xSource/WebKit/android/jni/MockGeolocation.cpp1
-rw-r--r--Source/WebKit/android/jni/PicturePile.cpp30
12 files changed, 325 insertions, 167 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..9bbf6b9 100644
--- a/Source/WebCore/platform/graphics/android/context/GraphicsOperation.h
+++ b/Source/WebCore/platform/graphics/android/context/GraphicsOperation.h
@@ -42,14 +42,49 @@
#define TYPE_CASE(type) case type: return #type;
+#define DEBUG_GRAPHICS_OPERATIONS false
+
+#if DEBUG_GRAPHICS_OPERATIONS
+#define TYPE(x) virtual OperationType type() { return x; }
+#else
+#define TYPE(x)
+#endif
+
namespace WebCore {
class CanvasState;
+class LinearAllocator;
namespace GraphicsOperation {
class Operation {
public:
+ Operation()
+ : m_state(0)
+ , 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
+ // Only used for drawing operations, state operations will be undefined
+ CanvasState* m_canvasState;
+
+ bool apply(PlatformGraphicsContext* context) {
+ if (m_state)
+ context->setRawState(m_state);
+ return applyImpl(context);
+ }
+ virtual bool applyImpl(PlatformGraphicsContext* context) = 0;
+ virtual ~Operation() {}
+
+#if DEBUG_GRAPHICS_OPERATIONS
typedef enum { UndefinedOperation
// Matrix operations
, ConcatCTMOperation
@@ -82,28 +117,6 @@ public:
, DrawPosTextOperation
} OperationType;
- Operation()
- : m_state(0)
- , m_canvasState(0)
- {}
-
- // This m_state is applied by ourselves
- PlatformGraphicsContext::State* m_state;
- // 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)
- context->setRawState(m_state);
- return applyImpl(context);
- }
- 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()
{
switch (type()) {
@@ -140,6 +153,8 @@ public:
}
return "Undefined";
}
+#endif
+ TYPE(UndefinedOperation)
};
//**************************************
@@ -153,7 +168,7 @@ public:
context->concatCTM(m_matrix);
return true;
}
- virtual OperationType type() { return ConcatCTMOperation; }
+ TYPE(ConcatCTMOperation)
private:
AffineTransform m_matrix;
};
@@ -165,7 +180,7 @@ public:
context->rotate(m_angle);
return true;
}
- virtual OperationType type() { return RotateOperation; }
+ TYPE(RotateOperation)
private:
float m_angle;
};
@@ -177,7 +192,7 @@ public:
context->scale(m_scale);
return true;
}
- virtual OperationType type() { return ScaleOperation; }
+ TYPE(ScaleOperation)
private:
FloatSize m_scale;
};
@@ -189,7 +204,7 @@ public:
context->translate(m_x, m_y);
return true;
}
- virtual OperationType type() { return TranslateOperation; }
+ TYPE(TranslateOperation)
private:
float m_x;
float m_y;
@@ -207,7 +222,7 @@ public:
context->addInnerRoundedRectClip(m_rect, m_thickness);
return true;
}
- virtual OperationType type() { return InnerRoundedRectClipOperation; }
+ TYPE(InnerRoundedRectClipOperation)
private:
IntRect m_rect;
int m_thickness;
@@ -219,12 +234,7 @@ public:
virtual bool applyImpl(PlatformGraphicsContext* context) {
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());
- }
+ TYPE(ClipOperation)
private:
const FloatRect m_rect;
};
@@ -243,7 +253,7 @@ public:
else
return context->clip(m_path);
}
- virtual OperationType type() { return ClipPathOperation; }
+ TYPE(ClipPathOperation)
private:
const Path m_path;
bool m_clipOut;
@@ -257,7 +267,7 @@ public:
virtual bool applyImpl(PlatformGraphicsContext* context) {
return context->clipOut(m_rect);
}
- virtual OperationType type() { return ClipOutOperation; }
+ TYPE(ClipOutOperation)
private:
const IntRect m_rect;
};
@@ -269,7 +279,7 @@ public:
context->clearRect(m_rect);
return true;
}
- virtual OperationType type() { return ClearRectOperation; }
+ TYPE(ClearRectOperation)
private:
FloatRect m_rect;
};
@@ -287,7 +297,7 @@ public:
context->drawBitmapPattern(m_bitmap, m_matrix, m_operator, m_destRect);
return true;
}
- virtual OperationType type() { return DrawBitmapPatternOperation; }
+ TYPE(DrawBitmapPatternOperation)
private:
SkBitmap m_bitmap;
SkMatrix m_matrix;
@@ -304,12 +314,7 @@ public:
context->drawBitmapRect(m_bitmap, &m_srcR, m_dstR, m_operator);
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());
- }
+ TYPE(DrawBitmapRectOperation)
private:
SkBitmap m_bitmap;
SkIRect m_srcR;
@@ -328,7 +333,7 @@ public:
context->drawConvexPolygon(4, m_points, m_shouldAntiAlias);
return true;
}
- virtual OperationType type() { return DrawConvexPolygonQuadOperation; }
+ TYPE(DrawConvexPolygonQuadOperation)
private:
bool m_shouldAntiAlias;
FloatPoint m_points[4];
@@ -341,7 +346,7 @@ public:
context->drawEllipse(m_rect);
return true;
}
- virtual OperationType type() { return DrawEllipseOperation; }
+ TYPE(DrawEllipseOperation)
private:
IntRect m_rect;
};
@@ -358,7 +363,7 @@ public:
context->drawFocusRing(m_rects, m_width, m_offset, m_color);
return true;
}
- virtual OperationType type() { return DrawFocusRingOperation; }
+ TYPE(DrawFocusRingOperation)
private:
Vector<IntRect> m_rects;
int m_width;
@@ -374,7 +379,7 @@ public:
context->drawLine(m_point1, m_point2);
return true;
}
- virtual OperationType type() { return DrawLineOperation; }
+ TYPE(DrawLineOperation)
private:
IntPoint m_point1;
IntPoint m_point2;
@@ -388,7 +393,7 @@ public:
context->drawLineForText(m_point, m_width);
return true;
}
- virtual OperationType type() { return DrawLineForTextOperation; }
+ TYPE(DrawLineForTextOperation)
private:
FloatPoint m_point;
float m_width;
@@ -403,7 +408,7 @@ public:
context->drawLineForTextChecking(m_point, m_width, m_lineStyle);
return true;
}
- virtual OperationType type() { return DrawLineForTextCheckingOperation; }
+ TYPE(DrawLineForTextCheckingOperation)
private:
FloatPoint m_point;
float m_width;
@@ -417,7 +422,7 @@ public:
context->drawRect(m_rect);
return true;
}
- virtual OperationType type() { return DrawRectOperation; }
+ TYPE(DrawRectOperation)
private:
IntRect m_rect;
};
@@ -430,7 +435,7 @@ public:
context->fillPath(m_path, m_fillRule);
return true;
}
- virtual OperationType type() { return FillPathOperation; }
+ TYPE(FillPathOperation)
private:
Path m_path;
WindRule m_fillRule;
@@ -447,7 +452,7 @@ public:
context->fillRect(m_rect);
return true;
}
- virtual OperationType type() { return FillRectOperation; }
+ TYPE(FillRectOperation)
private:
FloatRect m_rect;
Color m_color;
@@ -475,7 +480,7 @@ public:
m_color);
return true;
}
- virtual OperationType type() { return FillRoundedRectOperation; }
+ TYPE(FillRoundedRectOperation)
private:
IntRect m_rect;
IntSize m_topLeft;
@@ -496,7 +501,7 @@ public:
context->strokeArc(m_rect, m_startAngle, m_angleSpan);
return true;
}
- virtual OperationType type() { return StrokeArcOperation; }
+ TYPE(StrokeArcOperation)
private:
IntRect m_rect;
int m_startAngle;
@@ -510,7 +515,7 @@ public:
context->strokePath(m_path);
return true;
}
- virtual OperationType type() { return StrokePathOperation; }
+ TYPE(StrokePathOperation)
private:
Path m_path;
};
@@ -524,7 +529,7 @@ public:
context->strokeRect(m_rect, m_lineWidth);
return true;
}
- virtual OperationType type() { return StrokeRectOperation; }
+ TYPE(StrokeRectOperation)
private:
FloatRect m_rect;
float m_lineWidth;
@@ -554,7 +559,7 @@ public:
context->getCanvas()->drawPosText(m_text, m_byteLength, m_pos, m_paint);
return true;
}
- virtual OperationType type() { return DrawPosTextOperation; }
+ TYPE(DrawPosTextOperation)
private:
void* m_text;
size_t m_byteLength;
diff --git a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContext.cpp b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContext.cpp
index f9d7f21..367abda 100644
--- a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContext.cpp
+++ b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContext.cpp
@@ -161,7 +161,7 @@ bool PlatformGraphicsContext::State::setupShadowPaint(SkPaint* paint, SkPoint* o
// HTMLCanvasElement have shadows ignore transforms set. This
// allows us to distinguish between CSS and Canvas shadows which
// have different rendering specifications.
- uint32_t flags = SkBlurMaskFilter::kHighQuality_BlurFlag;
+ uint32_t flags = SkBlurMaskFilter::kNone_BlurFlag;
if (shadowsIgnoreTransforms) {
offset->fY = -offset->fY;
flags |= SkBlurMaskFilter::kIgnoreTransform_BlurFlag;
@@ -169,7 +169,7 @@ bool PlatformGraphicsContext::State::setupShadowPaint(SkPaint* paint, SkPoint* o
if (shadow.blur > 0) {
paint->setMaskFilter(SkBlurMaskFilter::Create(shadow.blur,
- SkBlurMaskFilter::kNormal_BlurStyle))->unref();
+ SkBlurMaskFilter::kNormal_BlurStyle, flags))->unref();
}
return SkColorGetA(shadow.color) && (shadow.blur || shadow.dx || shadow.dy);
}
@@ -395,7 +395,7 @@ void PlatformGraphicsContext::setupPaintCommon(SkPaint* paint) const
// allows us to distinguish between CSS and Canvas shadows which
// have different rendering specifications.
SkScalar dy = m_state->shadow.dy;
- uint32_t flags = SkBlurDrawLooper::kHighQuality_BlurFlag;
+ uint32_t flags = SkBlurDrawLooper::kNone_BlurFlag;
if (shadowsIgnoreTransforms()) {
dy = -dy;
flags |= SkBlurDrawLooper::kIgnoreTransform_BlurFlag;
diff --git a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp
index a2163ce..b0ab3ac 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,13 +844,12 @@ 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());
- operation->m_globalBounds = ibounds;
RecordingData* data = new RecordingData(operation, mRecording->recording()->m_nodeCount++);
mRecording->recording()->m_tree.insert(ibounds, data);
}
@@ -842,4 +861,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..fa048b7 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);
- }
}
//////////////////////////////////////////////////////////////////////
@@ -187,6 +185,7 @@ ElementList::ElementList(int size)
, m_minY(0)
, m_maxY(0)
, m_area(0)
+ , m_didTighten(false)
{
m_children = new Node*[size];
}
@@ -196,22 +195,26 @@ ElementList::~ElementList()
delete[] m_children;
}
-void ElementList::add(Node* node, bool doTighten)
+void ElementList::add(Node* node)
{
m_children[m_nbChildren] = node;
m_nbChildren++;
- if (doTighten)
- tighten();
+ m_didTighten = false;
}
void ElementList::tighten()
{
+ if (m_didTighten)
+ return;
recomputeBounds(m_minX, m_minY, m_maxX, m_maxY,
m_nbChildren, m_children, &m_area);
+ m_didTighten = true;
}
int ElementList::delta(Node* node)
{
+ if (!m_didTighten)
+ tighten();
return computeDeltaArea(node, m_minX, m_minY, m_maxX, m_maxY);
}
@@ -223,6 +226,7 @@ void ElementList::removeAll()
m_minY = 0;
m_maxY = 0;
m_area = 0;
+ m_didTighten = false;
}
void ElementList::display() {
@@ -308,19 +312,21 @@ int Node::delta(Node* node)
return computeDeltaArea(node, m_minX, m_minY, m_maxX, m_maxY);
}
-void Node::add(Node* node)
+void Node::simpleAdd(Node* node)
{
node->setParent(this);
if (!m_children)
m_children = new Node*[m_tree->m_maxChildren + 1];
m_children[m_nbChildren] = node;
m_nbChildren++;
- Node* NN = 0;
+}
+void Node::add(Node* node)
+{
+ simpleAdd(node);
+ Node* NN = 0;
if (m_nbChildren > m_tree->m_maxChildren)
NN = split();
- else
- tighten();
adjustTree(this, NN);
}
@@ -439,11 +445,12 @@ Node* Node::split()
// Use the list to rebuild the nodes
removeAll();
for (unsigned int i = 0; i < listA->m_nbChildren; i++)
- add(listA->m_children[i]);
+ simpleAdd(listA->m_children[i]);
Node* NN = Node::create(m_tree);
for (unsigned int i = 0; i < listB->m_nbChildren; i++)
- NN->add(listB->m_children[i]);
+ NN->simpleAdd(listB->m_children[i]);
+ NN->tighten();
return NN;
}
@@ -455,36 +462,52 @@ bool Node::isRoot()
void Node::adjustTree(Node* N, Node* NN)
{
+ bool callParent = N->updateBounds();
+
if (N->isRoot() && NN) {
// build new root
Node* root = Node::create(m_tree);
#ifdef DEBUG
ALOGV("-> node %d created as new root", root->m_tid);
#endif
- root->add(N);
- root->add(NN);
+ root->simpleAdd(N);
+ root->simpleAdd(NN);
+ root->tighten();
m_tree->m_root = root;
return;
}
+
if (N->isRoot())
return;
if (N->m_parent) {
- N->m_parent->tighten();
if (NN)
N->m_parent->add(NN);
- else
+ else if (callParent)
adjustTree(N->m_parent, 0);
}
}
+bool Node::updateBounds()
+{
+ int ominx = m_minX;
+ int ominy = m_minY;
+ int omaxx = m_maxX;
+ int omaxy = m_maxY;
+ tighten();
+ if ((ominx != m_minX)
+ || (ominy != m_minY)
+ || (omaxx != m_maxX)
+ || (omaxy != m_maxY))
+ return true;
+ return false;
+}
+
#ifdef DEBUG
static int gMaxLevel = 0;
static int gNbNodes = 0;
static int gNbElements = 0;
-#endif
-#ifdef DEBUG
void Node::drawTree(int level)
{
if (level == 0) {
diff --git a/Source/WebCore/platform/graphics/android/context/RTree.h b/Source/WebCore/platform/graphics/android/context/RTree.h
index 4ad8986..366e3d1 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;
@@ -88,7 +88,7 @@ public:
ElementList(int size);
~ElementList();
- void add(Node* n, bool doTighten = true);
+ void add(Node* n);
void tighten();
int delta(Node* n);
void removeAll();
@@ -104,6 +104,7 @@ private:
int m_minY;
int m_maxY;
int m_area;
+ bool m_didTighten;
};
class Node {
@@ -133,6 +134,7 @@ private:
void setParent(Node* n);
Node* findNode(Node* n);
+ void simpleAdd(Node* n);
void add(Node* n);
void remove(Node* n);
void destroy(int index);
@@ -140,6 +142,7 @@ private:
Node* split();
void adjustTree(Node* N, Node* NN);
void tighten();
+ bool updateBounds();
int delta(Node* n);
bool overlap(int minx, int miny, int maxx, int maxy);
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;
diff --git a/Source/WebKit/android/jni/MockGeolocation.cpp b/Source/WebKit/android/jni/MockGeolocation.cpp
index 164c37d..d588010 100755
--- a/Source/WebKit/android/jni/MockGeolocation.cpp
+++ b/Source/WebKit/android/jni/MockGeolocation.cpp
@@ -32,6 +32,7 @@
#include <GeolocationError.h>
#include <GeolocationPosition.h>
+#include "JNIHelp.h"
#include "ScopedLocalRef.h"
#include <wtf/CurrentTime.h>
diff --git a/Source/WebKit/android/jni/PicturePile.cpp b/Source/WebKit/android/jni/PicturePile.cpp
index 0731977..91f3e74 100644
--- a/Source/WebKit/android/jni/PicturePile.cpp
+++ b/Source/WebKit/android/jni/PicturePile.cpp
@@ -153,14 +153,30 @@ void PicturePile::setSize(const IntSize& size)
{
if (m_size == size)
return;
+ IntSize oldSize = m_size;
m_size = size;
- // TODO: See above about just adding invals for new content
- m_pile.clear();
- m_webkitInvals.clear();
- if (!size.isEmpty()) {
- IntRect area(0, 0, size.width(), size.height());
- m_webkitInvals.append(area);
- m_pile.append(area);
+ if (size.width() <= oldSize.width() && size.height() <= oldSize.height()) {
+ // We are shrinking - huzzah, nothing to do!
+ // TODO: Loop through and throw out Pictures that are now clipped out
+ } else if (oldSize.width() == size.width()) {
+ // Only changing vertically
+ IntRect rect(0, std::min(oldSize.height(), size.height()),
+ size.width(), std::abs(oldSize.height() - size.height()));
+ invalidate(rect);
+ } else if (oldSize.height() == size.height()) {
+ // Only changing horizontally
+ IntRect rect(std::min(oldSize.width(), size.width()), 0,
+ std::abs(oldSize.width() - size.width()), size.height());
+ invalidate(rect);
+ } else {
+ // Both width & height changed, full inval :(
+ m_pile.clear();
+ m_webkitInvals.clear();
+ if (!size.isEmpty()) {
+ IntRect area(0, 0, size.width(), size.height());
+ m_webkitInvals.append(area);
+ m_pile.append(area);
+ }
}
}