Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7466986d authored by Chris Craik's avatar Chris Craik
Browse files

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
parent f0600954
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -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 {
+9 −11
Original line number Diff line number Diff line
@@ -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 {
+15 −3
Original line number Diff line number Diff line
@@ -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());
}