diff options
Diffstat (limited to 'libs/hwui/CanvasState.cpp')
-rw-r--r-- | libs/hwui/CanvasState.cpp | 92 |
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; |