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

Commit 4ac36f80 authored by Chris Craik's avatar Chris Craik
Browse files

Fix frame-allocated path lifecycles

bug:18667472

Previously, we were allocating per-frame temporary paths within the
PlaybackStateStruct, but these are not safe as layers allocate these
transiently. Instead, move these to the OpenGLRenderer, which has
better define lifecycle.

Additionally, don't store SkPath objects directly in vector, since
they are then subject to relocation.

Change-Id: I8187ef542fcd5b030502bb75eb123ee26c0daa96
parent 596d4e72
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -325,6 +325,7 @@ void AmbientShadow::createAmbientShadow(bool isCasterOpaque,
    // At the end, update the real index and vertex buffer size.
    shadowVertexBuffer.updateVertexCount(vertexBufferIndex);
    shadowVertexBuffer.updateIndexCount(indexBufferIndex);
    shadowVertexBuffer.computeBounds<AlphaVertex>();

    ShadowTessellator::checkOverflow(vertexBufferIndex, totalVertexCount, "Ambient Vertex Buffer");
    ShadowTessellator::checkOverflow(indexBufferIndex, totalIndexCount, "Ambient Index Buffer");
+4 −8
Original line number Diff line number Diff line
@@ -77,18 +77,14 @@ public:
    OpenGLRenderer& mRenderer;
    const int mReplayFlags;

    // Allocator with the lifetime of a single frame.
    // replay uses an Allocator owned by the struct, while defer shares the DeferredDisplayList's Allocator
    // Allocator with the lifetime of a single frame. replay uses an Allocator owned by the struct,
    // while defer shares the DeferredDisplayList's Allocator
    // TODO: move this allocator to be owned by object with clear frame lifecycle
    LinearAllocator * const mAllocator;

    SkPath* allocPathForFrame() {
        mTempPaths.push_back();
        return &mTempPaths.back();
        return mRenderer.allocPathForFrame();
    }

private:
    // Paths kept alive for the duration of the frame
    std::vector<SkPath> mTempPaths;
};

class DeferStateStruct : public PlaybackStateStruct {
+5 −0
Original line number Diff line number Diff line
@@ -311,6 +311,11 @@ void OpenGLRenderer::finish() {
    renderOverdraw();
    endTiling();

    for (size_t i = 0; i < mTempPaths.size(); i++) {
        delete mTempPaths[i];
    }
    mTempPaths.clear();

    // When finish() is invoked on FBO 0 we've reached the end
    // of the current frame
    if (getTargetFbo() == 0) {
+9 −0
Original line number Diff line number Diff line
@@ -342,6 +342,12 @@ public:
    uint8_t getAmbientShadowAlpha() const { return mAmbientShadowAlpha; }
    uint8_t getSpotShadowAlpha() const { return mSpotShadowAlpha; }

    SkPath* allocPathForFrame() {
        SkPath* path = new SkPath();
        mTempPaths.push_back(path);
        return path;
    }

protected:
    /**
     * Perform the setup specific to a frame. This method does not
@@ -1014,6 +1020,9 @@ private:
    uint8_t mAmbientShadowAlpha;
    uint8_t mSpotShadowAlpha;

    // Paths kept alive for the duration of the frame
    std::vector<SkPath*> mTempPaths;

    friend class Layer;
    friend class TextSetupFunctor;
    friend class DrawBitmapOp;