summaryrefslogtreecommitdiff
path: root/libs/hwui/CanvasState.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/hwui/CanvasState.cpp')
-rw-r--r--libs/hwui/CanvasState.cpp92
1 files changed, 66 insertions, 26 deletions
diff --git a/libs/hwui/CanvasState.cpp b/libs/hwui/CanvasState.cpp
index e22b0d3084ab..6a6cc42043df 100644
--- a/libs/hwui/CanvasState.cpp
+++ b/libs/hwui/CanvasState.cpp
@@ -28,19 +28,36 @@ CanvasState::CanvasState(CanvasStateClient& renderer)
, mWidth(-1)
, mHeight(-1)
, mSaveCount(1)
- , mFirstSnapshot(new Snapshot)
, mCanvas(renderer)
- , mSnapshot(mFirstSnapshot) {
-
+ , mSnapshot(&mFirstSnapshot) {
}
CanvasState::~CanvasState() {
-
+ // First call freeSnapshot on all but mFirstSnapshot
+ // to invoke all the dtors
+ freeAllSnapshots();
+
+ // Now actually release the memory
+ while (mSnapshotPool) {
+ void* temp = mSnapshotPool;
+ mSnapshotPool = mSnapshotPool->previous;
+ free(temp);
+ }
}
-void CanvasState::initializeSaveStack(float clipLeft, float clipTop,
+void CanvasState::initializeSaveStack(
+ int viewportWidth, int viewportHeight,
+ float clipLeft, float clipTop,
float clipRight, float clipBottom, const Vector3& lightCenter) {
- mSnapshot = new Snapshot(mFirstSnapshot,
+ if (mWidth != viewportWidth || mHeight != viewportHeight) {
+ mWidth = viewportWidth;
+ mHeight = viewportHeight;
+ mFirstSnapshot.initializeViewport(viewportWidth, viewportHeight);
+ mCanvas.onViewportInitialized();
+ }
+
+ freeAllSnapshots();
+ mSnapshot = allocSnapshot(&mFirstSnapshot,
SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
mSnapshot->setClip(clipLeft, clipTop, clipRight, clipBottom);
mSnapshot->fbo = mCanvas.getTargetFbo();
@@ -48,18 +65,36 @@ void CanvasState::initializeSaveStack(float clipLeft, float clipTop,
mSaveCount = 1;
}
-void CanvasState::setViewport(int width, int height) {
- mWidth = width;
- mHeight = height;
- mFirstSnapshot->initializeViewport(width, height);
- mCanvas.onViewportInitialized();
+Snapshot* CanvasState::allocSnapshot(Snapshot* previous, int savecount) {
+ void* memory;
+ if (mSnapshotPool) {
+ memory = mSnapshotPool;
+ mSnapshotPool = mSnapshotPool->previous;
+ mSnapshotPoolCount--;
+ } else {
+ memory = malloc(sizeof(Snapshot));
+ }
+ return new (memory) Snapshot(previous, savecount);
+}
- // create a temporary 1st snapshot, so old snapshots are released,
- // and viewport can be queried safely.
- // TODO: remove, combine viewport + save stack initialization
- mSnapshot = new Snapshot(mFirstSnapshot,
- SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
- mSaveCount = 1;
+void CanvasState::freeSnapshot(Snapshot* snapshot) {
+ snapshot->~Snapshot();
+ // Arbitrary number, just don't let this grown unbounded
+ if (mSnapshotPoolCount > 10) {
+ free((void*) snapshot);
+ } else {
+ snapshot->previous = mSnapshotPool;
+ mSnapshotPool = snapshot;
+ mSnapshotPoolCount++;
+ }
+}
+
+void CanvasState::freeAllSnapshots() {
+ while (mSnapshot != &mFirstSnapshot) {
+ Snapshot* temp = mSnapshot;
+ mSnapshot = mSnapshot->previous;
+ freeSnapshot(temp);
+ }
}
///////////////////////////////////////////////////////////////////////////////
@@ -73,7 +108,7 @@ void CanvasState::setViewport(int width, int height) {
* stack, and ensures restoreToCount() doesn't call back into subclass overrides.
*/
int CanvasState::saveSnapshot(int flags) {
- mSnapshot = new Snapshot(mSnapshot, flags);
+ mSnapshot = allocSnapshot(mSnapshot, flags);
return mSaveCount++;
}
@@ -85,14 +120,16 @@ int CanvasState::save(int flags) {
* Guaranteed to restore without side-effects.
*/
void CanvasState::restoreSnapshot() {
- sp<Snapshot> toRemove = mSnapshot;
- sp<Snapshot> toRestore = mSnapshot->previous;
+ Snapshot* toRemove = mSnapshot;
+ Snapshot* toRestore = mSnapshot->previous;
mSaveCount--;
mSnapshot = toRestore;
// subclass handles restore implementation
mCanvas.onSnapshotRestored(*toRemove, *toRestore);
+
+ freeSnapshot(toRemove);
}
void CanvasState::restore() {
@@ -138,7 +175,7 @@ void CanvasState::setMatrix(const SkMatrix& matrix) {
}
void CanvasState::setMatrix(const Matrix4& matrix) {
- mSnapshot->transform->load(matrix);
+ *(mSnapshot->transform) = matrix;
}
void CanvasState::concatMatrix(const SkMatrix& matrix) {
@@ -155,17 +192,20 @@ void CanvasState::concatMatrix(const Matrix4& matrix) {
///////////////////////////////////////////////////////////////////////////////
bool CanvasState::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) {
- mDirtyClip |= mSnapshot->clip(left, top, right, bottom, op);
+ mSnapshot->clip(left, top, right, bottom, op);
+ mDirtyClip = true;
return !mSnapshot->clipIsEmpty();
}
bool CanvasState::clipPath(const SkPath* path, SkRegion::Op op) {
- mDirtyClip |= mSnapshot->clipPath(*path, op);
+ mSnapshot->clipPath(*path, op);
+ mDirtyClip = true;
return !mSnapshot->clipIsEmpty();
}
bool CanvasState::clipRegion(const SkRegion* region, SkRegion::Op op) {
- mDirtyClip |= mSnapshot->clipRegionTransformed(*region, op);
+ mSnapshot->clipRegionTransformed(*region, op);
+ mDirtyClip = true;
return !mSnapshot->clipIsEmpty();
}
@@ -219,7 +259,7 @@ bool CanvasState::calculateQuickRejectForScissor(float left, float top,
currentTransform()->mapRect(r);
r.snapGeometryToPixelBoundaries(snapOut);
- Rect clipRect(currentClipRect());
+ Rect clipRect(currentRenderTargetClip());
clipRect.snapToPixelBoundaries();
if (!clipRect.intersects(r)) return true;
@@ -247,7 +287,7 @@ bool CanvasState::quickRejectConservative(float left, float top,
currentTransform()->mapRect(r);
r.roundOut(); // rounded out to be conservative
- Rect clipRect(currentClipRect());
+ Rect clipRect(currentRenderTargetClip());
clipRect.snapToPixelBoundaries();
if (!clipRect.intersects(r)) return true;