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

Commit d9ee5508 authored by John Reck's avatar John Reck
Browse files

Reduce, reuse, recycle SNAPSHOTS!

Shaves like, 1 whole us off of reset

Change-Id: I459370448583d5e22fd302ba1353319564a814be
parent 9ad05de2
Loading
Loading
Loading
Loading
+53 −7
Original line number Original line Diff line number Diff line
@@ -28,10 +28,21 @@ CanvasState::CanvasState(CanvasStateClient& renderer)
        , mWidth(-1)
        , mWidth(-1)
        , mHeight(-1)
        , mHeight(-1)
        , mSaveCount(1)
        , mSaveCount(1)
        , mFirstSnapshot(new Snapshot)
        , mCanvas(renderer)
        , 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(
void CanvasState::initializeSaveStack(
@@ -41,11 +52,12 @@ void CanvasState::initializeSaveStack(
    if (mWidth != viewportWidth || mHeight != viewportHeight) {
    if (mWidth != viewportWidth || mHeight != viewportHeight) {
        mWidth = viewportWidth;
        mWidth = viewportWidth;
        mHeight = viewportHeight;
        mHeight = viewportHeight;
        mFirstSnapshot->initializeViewport(viewportWidth, viewportHeight);
        mFirstSnapshot.initializeViewport(viewportWidth, viewportHeight);
        mCanvas.onViewportInitialized();
        mCanvas.onViewportInitialized();
    }
    }


    mSnapshot = new Snapshot(mFirstSnapshot,
    freeAllSnapshots();
    mSnapshot = allocSnapshot(&mFirstSnapshot,
            SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
            SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
    mSnapshot->setClip(clipLeft, clipTop, clipRight, clipBottom);
    mSnapshot->setClip(clipLeft, clipTop, clipRight, clipBottom);
    mSnapshot->fbo = mCanvas.getTargetFbo();
    mSnapshot->fbo = mCanvas.getTargetFbo();
@@ -53,6 +65,38 @@ void CanvasState::initializeSaveStack(
    mSaveCount = 1;
    mSaveCount = 1;
}
}


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);
}

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);
    }
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Save (layer)
// Save (layer)
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
@@ -64,7 +108,7 @@ void CanvasState::initializeSaveStack(
 * stack, and ensures restoreToCount() doesn't call back into subclass overrides.
 * stack, and ensures restoreToCount() doesn't call back into subclass overrides.
 */
 */
int CanvasState::saveSnapshot(int flags) {
int CanvasState::saveSnapshot(int flags) {
    mSnapshot = new Snapshot(mSnapshot, flags);
    mSnapshot = allocSnapshot(mSnapshot, flags);
    return mSaveCount++;
    return mSaveCount++;
}
}


@@ -76,14 +120,16 @@ int CanvasState::save(int flags) {
 * Guaranteed to restore without side-effects.
 * Guaranteed to restore without side-effects.
 */
 */
void CanvasState::restoreSnapshot() {
void CanvasState::restoreSnapshot() {
    sp<Snapshot> toRemove = mSnapshot;
    Snapshot* toRemove = mSnapshot;
    sp<Snapshot> toRestore = mSnapshot->previous;
    Snapshot* toRestore = mSnapshot->previous;


    mSaveCount--;
    mSaveCount--;
    mSnapshot = toRestore;
    mSnapshot = toRestore;


    // subclass handles restore implementation
    // subclass handles restore implementation
    mCanvas.onSnapshotRestored(*toRemove, *toRestore);
    mCanvas.onSnapshotRestored(*toRemove, *toRestore);

    freeSnapshot(toRemove);
}
}


void CanvasState::restore() {
void CanvasState::restore() {
+17 −7
Original line number Original line Diff line number Diff line
@@ -17,12 +17,12 @@
#ifndef ANDROID_HWUI_CANVAS_STATE_H
#ifndef ANDROID_HWUI_CANVAS_STATE_H
#define ANDROID_HWUI_CANVAS_STATE_H
#define ANDROID_HWUI_CANVAS_STATE_H


#include "Snapshot.h"

#include <SkMatrix.h>
#include <SkMatrix.h>
#include <SkPath.h>
#include <SkPath.h>
#include <SkRegion.h>
#include <SkRegion.h>


#include "Snapshot.h"

namespace android {
namespace android {
namespace uirenderer {
namespace uirenderer {


@@ -74,6 +74,7 @@ public:
class CanvasState {
class CanvasState {
public:
public:
    CanvasState(CanvasStateClient& renderer);
    CanvasState(CanvasStateClient& renderer);
    ~CanvasState();


    /**
    /**
     * Initializes the first snapshot, computing the projection matrix,
     * Initializes the first snapshot, computing the projection matrix,
@@ -157,11 +158,15 @@ public:
    int getHeight() const { return mHeight; }
    int getHeight() const { return mHeight; }
    bool clipIsSimple() const { return currentSnapshot()->clipIsSimple(); }
    bool clipIsSimple() const { return currentSnapshot()->clipIsSimple(); }


    inline const Snapshot* currentSnapshot() const { return mSnapshot.get(); }
    inline const Snapshot* currentSnapshot() const { return mSnapshot; }
    inline Snapshot* writableSnapshot() { return mSnapshot.get(); }
    inline Snapshot* writableSnapshot() { return mSnapshot; }
    inline const Snapshot* firstSnapshot() const { return mFirstSnapshot.get(); }
    inline const Snapshot* firstSnapshot() const { return &mFirstSnapshot; }


private:
private:
    Snapshot* allocSnapshot(Snapshot* previous, int savecount);
    void freeSnapshot(Snapshot* snapshot);
    void freeAllSnapshots();

    /// indicates that the clip has been changed since the last time it was consumed
    /// indicates that the clip has been changed since the last time it was consumed
    bool mDirtyClip;
    bool mDirtyClip;


@@ -172,13 +177,18 @@ private:
    int mSaveCount;
    int mSaveCount;


    /// Base state
    /// Base state
    sp<Snapshot> mFirstSnapshot;
    Snapshot mFirstSnapshot;


    /// Host providing callbacks
    /// Host providing callbacks
    CanvasStateClient& mCanvas;
    CanvasStateClient& mCanvas;


    /// Current state
    /// Current state
    sp<Snapshot> mSnapshot;
    Snapshot* mSnapshot;

    // Pool of allocated snapshots to re-use
    // NOTE: The dtors have already been invoked!
    Snapshot* mSnapshotPool = nullptr;
    int mSnapshotPoolCount = 0;


}; // class CanvasState
}; // class CanvasState


+3 −3
Original line number Original line Diff line number Diff line
@@ -44,7 +44,7 @@ Snapshot::Snapshot()
 * Copies the specified snapshot/ The specified snapshot is stored as
 * Copies the specified snapshot/ The specified snapshot is stored as
 * the previous snapshot.
 * the previous snapshot.
 */
 */
Snapshot::Snapshot(const sp<Snapshot>& s, int saveFlags)
Snapshot::Snapshot(Snapshot* s, int saveFlags)
        : flags(0)
        : flags(0)
        , previous(s)
        , previous(s)
        , layer(s->layer)
        , layer(s->layer)
@@ -148,7 +148,7 @@ void Snapshot::buildScreenSpaceTransform(Matrix4* outTransform) const {
    const Snapshot* current = this;
    const Snapshot* current = this;
    do {
    do {
        snapshotList.push(current);
        snapshotList.push(current);
        current = current->previous.get();
        current = current->previous;
    } while (current);
    } while (current);


    // traverse the list, adding in each transform that contributes to the total transform
    // traverse the list, adding in each transform that contributes to the total transform
@@ -240,7 +240,7 @@ bool Snapshot::isIgnored() const {


void Snapshot::dump() const {
void Snapshot::dump() const {
    ALOGD("Snapshot %p, flags %x, prev %p, height %d, ignored %d, hasComplexClip %d",
    ALOGD("Snapshot %p, flags %x, prev %p, height %d, ignored %d, hasComplexClip %d",
            this, flags, previous.get(), getViewportHeight(), isIgnored(), !mClipArea->isSimple());
            this, flags, previous, getViewportHeight(), isIgnored(), !mClipArea->isSimple());
    const Rect& clipRect(mClipArea->getClipRect());
    const Rect& clipRect(mClipArea->getClipRect());
    ALOGD("  ClipRect %.1f %.1f %.1f %.1f, clip simple %d",
    ALOGD("  ClipRect %.1f %.1f %.1f %.1f, clip simple %d",
            clipRect.left, clipRect.top, clipRect.right, clipRect.bottom, mClipArea->isSimple());
            clipRect.left, clipRect.top, clipRect.right, clipRect.bottom, mClipArea->isSimple());
+3 −3
Original line number Original line Diff line number Diff line
@@ -83,11 +83,11 @@ public:
 * Each snapshot has a link to a previous snapshot, indicating the previous
 * Each snapshot has a link to a previous snapshot, indicating the previous
 * state of the renderer.
 * state of the renderer.
 */
 */
class Snapshot: public LightRefBase<Snapshot> {
class Snapshot {
public:
public:


    Snapshot();
    Snapshot();
    Snapshot(const sp<Snapshot>& s, int saveFlags);
    Snapshot(Snapshot* s, int saveFlags);


    /**
    /**
     * Various flags set on ::flags.
     * Various flags set on ::flags.
@@ -229,7 +229,7 @@ public:
    /**
    /**
     * Previous snapshot.
     * Previous snapshot.
     */
     */
    sp<Snapshot> previous;
    Snapshot* previous;


    /**
    /**
     * A pointer to the currently active layer.
     * A pointer to the currently active layer.