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

Commit 2fc941e4 authored by Romain Guy's avatar Romain Guy
Browse files

Fixes cache misses and extra allocations.

Bug #3421454

Change-Id: If4d5c960a7e4c581a9d213073e658284b4e1c497
parent ef36255f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -104,7 +104,7 @@ public class Canvas {
    public Canvas() {
        // 0 means no native bitmap
        mNativeCanvas = initRaster(0);
        mFinalizer = new CanvasFinalizer(0);
        mFinalizer = new CanvasFinalizer(mNativeCanvas);
    }

    /**
+11 −0
Original line number Diff line number Diff line
@@ -76,8 +76,14 @@ void Caches::dumpMemoryUsage() {
    LOGD("  PathCache            %8d / %8d", pathCache.getSize(), pathCache.getMaxSize());
    LOGD("  CircleShapeCache     %8d / %8d",
            circleShapeCache.getSize(), circleShapeCache.getMaxSize());
    LOGD("  OvalShapeCache       %8d / %8d",
            ovalShapeCache.getSize(), ovalShapeCache.getMaxSize());
    LOGD("  RoundRectShapeCache  %8d / %8d",
            roundRectShapeCache.getSize(), roundRectShapeCache.getMaxSize());
    LOGD("  RectShapeCache       %8d / %8d",
            rectShapeCache.getSize(), rectShapeCache.getMaxSize());
    LOGD("  ArcShapeCache        %8d / %8d",
            arcShapeCache.getSize(), arcShapeCache.getMaxSize());
    LOGD("  TextDropShadowCache  %8d / %8d", dropShadowCache.getSize(),
            dropShadowCache.getMaxSize());
    for (uint32_t i = 0; i < fontRenderer.getFontRendererCount(); i++) {
@@ -94,6 +100,11 @@ void Caches::dumpMemoryUsage() {
    total += gradientCache.getSize();
    total += pathCache.getSize();
    total += dropShadowCache.getSize();
    total += roundRectShapeCache.getSize();
    total += circleShapeCache.getSize();
    total += ovalShapeCache.getSize();
    total += rectShapeCache.getSize();
    total += arcShapeCache.getSize();
    for (uint32_t i = 0; i < fontRenderer.getFontRendererCount(); i++) {
        total += fontRenderer.getFontRendererSize(i);
    }
+13 −87
Original line number Diff line number Diff line
@@ -21,62 +21,6 @@
namespace android {
namespace uirenderer {

///////////////////////////////////////////////////////////////////////////////
// Defines
///////////////////////////////////////////////////////////////////////////////

#define PATH_HEAP_SIZE 64

///////////////////////////////////////////////////////////////////////////////
// Helpers
///////////////////////////////////////////////////////////////////////////////

PathHeap::PathHeap(): mHeap(PATH_HEAP_SIZE * sizeof(SkPath)) {
}

PathHeap::PathHeap(SkFlattenableReadBuffer& buffer): mHeap(PATH_HEAP_SIZE * sizeof(SkPath)) {
    int count = buffer.readS32();

    mPaths.setCount(count);
    SkPath** ptr = mPaths.begin();
    SkPath* p = (SkPath*) mHeap.allocThrow(count * sizeof(SkPath));

    for (int i = 0; i < count; i++) {
        new (p) SkPath;
        p->unflatten(buffer);
        *ptr++ = p;
        p++;
    }
}

PathHeap::~PathHeap() {
    SkPath** iter = mPaths.begin();
    SkPath** stop = mPaths.end();
    while (iter < stop) {
        (*iter)->~SkPath();
        iter++;
    }
}

int PathHeap::append(const SkPath& path) {
    SkPath* p = (SkPath*) mHeap.allocThrow(sizeof(SkPath));
    new (p) SkPath(path);
    *mPaths.append() = p;
    return mPaths.count();
}

void PathHeap::flatten(SkFlattenableWriteBuffer& buffer) const {
    int count = mPaths.count();

    buffer.write32(count);
    SkPath** iter = mPaths.begin();
    SkPath** stop = mPaths.end();
    while (iter < stop) {
        (*iter)->flatten(buffer);
        iter++;
    }
}

///////////////////////////////////////////////////////////////////////////////
// Display list
///////////////////////////////////////////////////////////////////////////////
@@ -143,17 +87,15 @@ DisplayList::~DisplayList() {
    }
    mPaints.clear();

    for (size_t i = 0; i < mPaths.size(); i++) {
        delete mPaths.itemAt(i);
    }
    mPaths.clear();

    for (size_t i = 0; i < mMatrices.size(); i++) {
        delete mMatrices.itemAt(i);
    }
    mMatrices.clear();

    if (mPathHeap) {
        for (int i = 0; i < mPathHeap->count(); i++) {
            caches.pathCache.removeDeferred(&(*mPathHeap)[i]);
        }
        mPathHeap->safeUnref();
    }
}

void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorder) {
@@ -169,12 +111,6 @@ void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorde
    writer.flatten(buffer);
    mReader.setMemory(buffer, size);

    mRCPlayback.reset(&recorder.mRCRecorder);
    mRCPlayback.setupBuffer(mReader);

    mTFPlayback.reset(&recorder.mTFRecorder);
    mTFPlayback.setupBuffer(mReader);

    Caches& caches = Caches::getInstance();

    const Vector<SkBitmap*> &bitmapResources = recorder.getBitmapResources();
@@ -196,19 +132,18 @@ void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorde
        mPaints.add(paints.itemAt(i));
    }

    const Vector<SkPath*> &paths = recorder.getPaths();
    for (size_t i = 0; i < paths.size(); i++) {
        mPaths.add(paths.itemAt(i));
    }

    const Vector<SkMatrix*> &matrices = recorder.getMatrices();
    for (size_t i = 0; i < matrices.size(); i++) {
        mMatrices.add(matrices.itemAt(i));
    }

    mPathHeap = recorder.mPathHeap;
    if (mPathHeap) {
        mPathHeap->safeRef();
    }
}

void DisplayList::init() {
    mPathHeap = NULL;
}

bool DisplayList::replay(OpenGLRenderer& renderer, uint32_t level) {
@@ -557,9 +492,7 @@ bool DisplayList::replay(OpenGLRenderer& renderer, uint32_t level) {
// Base structure
///////////////////////////////////////////////////////////////////////////////

DisplayListRenderer::DisplayListRenderer():
        mHeap(HEAP_BLOCK_SIZE), mWriter(MIN_WRITER_SIZE) {
    mPathHeap = NULL;
DisplayListRenderer::DisplayListRenderer(): mWriter(MIN_WRITER_SIZE) {
    mDisplayList = NULL;
}

@@ -568,16 +501,7 @@ DisplayListRenderer::~DisplayListRenderer() {
}

void DisplayListRenderer::reset() {
    if (mPathHeap) {
        mPathHeap->unref();
        mPathHeap = NULL;
    }

    mWriter.reset();
    mHeap.reset();

    mRCRecorder.reset();
    mTFRecorder.reset();

    Caches& caches = Caches::getInstance();
    for (size_t i = 0; i < mBitmapResources.size(); i++) {
@@ -594,6 +518,8 @@ void DisplayListRenderer::reset() {

    mPaints.clear();
    mPaintMap.clear();
    mPaths.clear();
    mPathMap.clear();
    mMatrices.clear();
}

+26 −42
Original line number Diff line number Diff line
@@ -38,7 +38,6 @@ namespace uirenderer {
///////////////////////////////////////////////////////////////////////////////

#define MIN_WRITER_SIZE 16384
#define HEAP_BLOCK_SIZE 4096

// Debug
#if DEBUG_DISPLAY_LIST
@@ -47,31 +46,6 @@ namespace uirenderer {
    #define DISPLAY_LIST_LOGD(...)
#endif

///////////////////////////////////////////////////////////////////////////////
// Helpers
///////////////////////////////////////////////////////////////////////////////

class PathHeap: public SkRefCnt {
public:
    PathHeap();
    PathHeap(SkFlattenableReadBuffer& buffer);
    ~PathHeap();

    int append(const SkPath& path);

    int count() const { return mPaths.count(); }

    SkPath& operator[](int index) const {
        return *mPaths[index];
    }

    void flatten(SkFlattenableWriteBuffer& buffer) const;

private:
    SkChunkAlloc mHeap;
    SkTDArray<SkPath*> mPaths;
};

///////////////////////////////////////////////////////////////////////////////
// Display list
///////////////////////////////////////////////////////////////////////////////
@@ -174,7 +148,7 @@ private:
    }

    SkPath* getPath() {
        return &(*mPathHeap)[getInt() - 1];
        return (SkPath*) getInt();
    }

    SkPaint* getPaint() {
@@ -209,19 +183,15 @@ private:
        text->mText = (const char*) mReader.skip(length);
    }

    PathHeap* mPathHeap;

    Vector<SkBitmap*> mBitmapResources;
    Vector<SkiaColorFilter*> mFilterResources;

    Vector<SkPaint*> mPaints;
    Vector<SkPath*> mPaths;
    Vector<SkMatrix*> mMatrices;
    Vector<SkiaShader*> mShaders;

    mutable SkFlattenableReadBuffer mReader;

    SkRefCntPlayback mRCPlayback;
    SkTypefacePlayback mTFPlayback;
};

///////////////////////////////////////////////////////////////////////////////
@@ -317,6 +287,10 @@ public:
        return mPaints;
    }

    const Vector<SkPath*>& getPaths() const {
        return mPaths;
    }

    const Vector<SkMatrix*>& getMatrices() const {
        return mMatrices;
    }
@@ -385,11 +359,24 @@ private:
        mWriter.writePad(text, byteLength);
    }

    inline void addPath(const SkPath* path) {
        if (mPathHeap == NULL) {
            mPathHeap = new PathHeap();
    inline void addPath(SkPath* path) {
        if (!path) {
            addInt((int) NULL);
            return;
        }
        addInt(mPathHeap->append(*path));

        SkPath* pathCopy = mPathMap.valueFor(path);
        if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) {
            if (pathCopy == NULL) {
                pathCopy = path;
            } else {
                pathCopy = new SkPath(*path);
                mPaths.add(pathCopy);
            }
            mPathMap.add(path, pathCopy);
        }

        addInt((int) pathCopy);
    }

    inline void addPaint(SkPaint* paint) {
@@ -457,25 +444,22 @@ private:
        caches.resourceCache.incrementRefcount(colorFilter);
    }

    SkChunkAlloc mHeap;

    Vector<SkBitmap*> mBitmapResources;
    Vector<SkiaColorFilter*> mFilterResources;

    Vector<SkPaint*> mPaints;
    DefaultKeyedVector<SkPaint*, SkPaint*> mPaintMap;

    Vector<SkPath*> mPaths;
    DefaultKeyedVector<SkPath*, SkPath*> mPathMap;

    Vector<SkiaShader*> mShaders;
    DefaultKeyedVector<SkiaShader*, SkiaShader*> mShaderMap;

    Vector<SkMatrix*> mMatrices;

    PathHeap* mPathHeap;
    SkWriter32 mWriter;

    SkRefCntRecorder mRCRecorder;
    SkRefCntRecorder mTFRecorder;

    DisplayList *mDisplayList;

    int mRestoreSaveCount;
+0 −1
Original line number Diff line number Diff line
@@ -65,7 +65,6 @@ void PathCache::clearGarbage() {

PathTexture* PathCache::get(SkPath* path, SkPaint* paint) {
    PathCacheEntry entry(path, paint);

    PathTexture* texture = mCache.get(entry);

    if (!texture) {
Loading