diff options
author | Chris Craik <ccraik@google.com> | 2014-08-07 17:27:30 -0700 |
---|---|---|
committer | Chris Craik <ccraik@google.com> | 2014-08-08 00:52:54 +0000 |
commit | 7466986d2055eb8711f36a85ac539b1572ffe805 (patch) | |
tree | 6c560d37db0e9f709e8b3114c126423ce99488fc /libs | |
parent | f06009542390472872da986486d385001e91a2a7 (diff) | |
download | frameworks_base-7466986d2055eb8711f36a85ac539b1572ffe805.zip frameworks_base-7466986d2055eb8711f36a85ac539b1572ffe805.tar.gz frameworks_base-7466986d2055eb8711f36a85ac539b1572ffe805.tar.bz2 |
Fix leak of SkPathRefs
bug:15939479
SkPath objects owned by DisplayListOps weren't being torn down, and
thus weren't releasing their SkPathRef innards.
Change-Id: I2581e124600a93a399ef3251f456c02ab52839a8
Diffstat (limited to 'libs')
-rw-r--r-- | libs/hwui/DisplayList.h | 13 | ||||
-rw-r--r-- | libs/hwui/DisplayListOp.h | 20 | ||||
-rw-r--r-- | libs/hwui/RenderNode.cpp | 18 |
3 files changed, 36 insertions, 15 deletions
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h index 79a2f61..acfa98e 100644 --- a/libs/hwui/DisplayList.h +++ b/libs/hwui/DisplayList.h @@ -69,7 +69,9 @@ class DrawRenderNodeOp; class PlaybackStateStruct { protected: PlaybackStateStruct(OpenGLRenderer& renderer, int replayFlags, LinearAllocator* allocator) - : mRenderer(renderer), mReplayFlags(replayFlags), mAllocator(allocator){} + : mRenderer(renderer) + , mReplayFlags(replayFlags) + , mAllocator(allocator) {} public: OpenGLRenderer& mRenderer; @@ -78,6 +80,15 @@ public: // Allocator with the lifetime of a single frame. // replay uses an Allocator owned by the struct, while defer shares the DeferredDisplayList's Allocator LinearAllocator * const mAllocator; + + SkPath* allocPathForFrame() { + mTempPaths.push_back(); + return &mTempPaths.back(); + } + +private: + // Paths kept alive for the duration of the frame + std::vector<SkPath> mTempPaths; }; class DeferStateStruct : public PlaybackStateStruct { diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h index 6883cc5..c6d3db7 100644 --- a/libs/hwui/DisplayListOp.h +++ b/libs/hwui/DisplayListOp.h @@ -1505,20 +1505,18 @@ private: class DrawShadowOp : public DrawOp { public: DrawShadowOp(const mat4& transformXY, const mat4& transformZ, - float casterAlpha, const SkPath* casterOutline, const SkPath* revealClip) - : DrawOp(NULL), mTransformXY(transformXY), mTransformZ(transformZ), - mCasterAlpha(casterAlpha) { - mOutline = *casterOutline; - if (revealClip) { - // intersect the outline with the convex reveal clip - Op(mOutline, *revealClip, kIntersect_PathOp, &mOutline); - } + float casterAlpha, const SkPath* casterOutline) + : DrawOp(NULL) + , mTransformXY(transformXY) + , mTransformZ(transformZ) + , mCasterAlpha(casterAlpha) + , mCasterOutline(casterOutline) { } virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo, const DeferredDisplayState& state) { renderer.getCaches().tessellationCache.precacheShadows(&state.mMatrix, - renderer.getLocalClipBounds(), isCasterOpaque(), &mOutline, + renderer.getLocalClipBounds(), isCasterOpaque(), mCasterOutline, &mTransformXY, &mTransformZ, renderer.getLightCenter(), renderer.getLightRadius()); } @@ -1527,7 +1525,7 @@ public: Matrix4 drawTransform; renderer.getMatrix(&drawTransform); renderer.getCaches().tessellationCache.getShadowBuffers(&drawTransform, - renderer.getLocalClipBounds(), isCasterOpaque(), &mOutline, + renderer.getLocalClipBounds(), isCasterOpaque(), mCasterOutline, &mTransformXY, &mTransformZ, renderer.getLightCenter(), renderer.getLightRadius(), buffers); @@ -1546,7 +1544,7 @@ private: const mat4 mTransformXY; const mat4 mTransformZ; const float mCasterAlpha; - SkPath mOutline; + const SkPath* mCasterOutline; }; class DrawLayerOp : public DrawOp { diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index f48b774..23940ee 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -534,6 +534,7 @@ public: inline void endMark() {} inline int level() { return mLevel; } inline int replayFlags() { return mDeferStruct.mReplayFlags; } + inline SkPath* allocPathForFrame() { return mDeferStruct.allocPathForFrame(); } private: DeferStateStruct& mDeferStruct; @@ -564,6 +565,7 @@ public: } inline int level() { return mLevel; } inline int replayFlags() { return mReplayStruct.mReplayFlags; } + inline SkPath* allocPathForFrame() { return mReplayStruct.allocPathForFrame(); } private: ReplayStateStruct& mReplayStruct; @@ -612,14 +614,24 @@ void RenderNode::issueDrawShadowOperation(const Matrix4& transformFromParent, T& mat4 shadowMatrixZ(transformFromParent); applyViewPropertyTransforms(shadowMatrixZ, true); - const SkPath* outlinePath = properties().getOutline().getPath(); + const SkPath* casterOutlinePath = properties().getOutline().getPath(); const SkPath* revealClipPath = properties().getRevealClip().getPath(); if (revealClipPath && revealClipPath->isEmpty()) return; float casterAlpha = properties().getAlpha() * properties().getOutline().getAlpha(); + + const SkPath* outlinePath = casterOutlinePath; + if (revealClipPath) { + // if we can't simply use the caster's path directly, create a temporary one + SkPath* frameAllocatedPath = handler.allocPathForFrame(); + + // intersect the outline with the convex reveal clip + Op(*casterOutlinePath, *revealClipPath, kIntersect_PathOp, frameAllocatedPath); + outlinePath = frameAllocatedPath; + } + DisplayListOp* shadowOp = new (handler.allocator()) DrawShadowOp( - shadowMatrixXY, shadowMatrixZ, casterAlpha, - outlinePath, revealClipPath); + shadowMatrixXY, shadowMatrixZ, casterAlpha, outlinePath); handler(shadowOp, PROPERTY_SAVECOUNT, properties().getClipToBounds()); } |