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

Commit 58ecc204 authored by Romain Guy's avatar Romain Guy
Browse files

Reduce the number of locks acquired by display lists

Change-Id: I1123aae0355de84db705bb75042c7083fc69c9f2
parent 369bb97d
Loading
Loading
Loading
Loading
+53 −40
Original line number Diff line number Diff line
@@ -149,6 +149,7 @@ void DisplayList::clearResources() {
    delete mTransformMatrix3D;
    delete mStaticMatrix;
    delete mAnimationMatrix;

    mTransformMatrix = NULL;
    mTransformCamera = NULL;
    mTransformMatrix3D = NULL;
@@ -156,50 +157,54 @@ void DisplayList::clearResources() {
    mAnimationMatrix = NULL;

    Caches& caches = Caches::getInstance();
    caches.resourceCache.lock();

    for (size_t i = 0; i < mBitmapResources.size(); i++) {
        caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i));
        caches.resourceCache.decrementRefcountLocked(mBitmapResources.itemAt(i));
    }
    mBitmapResources.clear();

    for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) {
        SkBitmap* bitmap = mOwnedBitmapResources.itemAt(i);
        caches.resourceCache.decrementRefcount(bitmap);
        caches.resourceCache.destructor(bitmap);
        caches.resourceCache.decrementRefcountLocked(bitmap);
        caches.resourceCache.destructorLocked(bitmap);
    }
    mOwnedBitmapResources.clear();

    for (size_t i = 0; i < mFilterResources.size(); i++) {
        caches.resourceCache.decrementRefcount(mFilterResources.itemAt(i));
        caches.resourceCache.decrementRefcountLocked(mFilterResources.itemAt(i));
    }
    mFilterResources.clear();

    for (size_t i = 0; i < mShaders.size(); i++) {
        caches.resourceCache.decrementRefcount(mShaders.itemAt(i));
        caches.resourceCache.destructor(mShaders.itemAt(i));
        caches.resourceCache.decrementRefcountLocked(mShaders.itemAt(i));
        caches.resourceCache.destructorLocked(mShaders.itemAt(i));
    }
    mShaders.clear();

    for (size_t i = 0; i < mSourcePaths.size(); i++) {
        caches.resourceCache.decrementRefcountLocked(mSourcePaths.itemAt(i));
    }

    caches.resourceCache.unlock();

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

    for (size_t i = 0; i < mPaths.size(); i++) {
        SkPath* path = mPaths.itemAt(i);
        caches.pathCache.remove(path);
        delete path;
    }
    mPaths.clear();

    for (size_t i = 0; i < mSourcePaths.size(); i++) {
        caches.resourceCache.decrementRefcount(mSourcePaths.itemAt(i));
    }
    mSourcePaths.clear();

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

    mBitmapResources.clear();
    mOwnedBitmapResources.clear();
    mFilterResources.clear();
    mShaders.clear();
    mSourcePaths.clear();
    mPaints.clear();
    mPaths.clear();
    mMatrices.clear();
}

@@ -223,35 +228,44 @@ void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorde
    mReader.setMemory(buffer, mSize);

    Caches& caches = Caches::getInstance();
    caches.resourceCache.lock();

    const Vector<SkBitmap*>& bitmapResources = recorder.getBitmapResources();
    for (size_t i = 0; i < bitmapResources.size(); i++) {
        SkBitmap* resource = bitmapResources.itemAt(i);
        mBitmapResources.add(resource);
        caches.resourceCache.incrementRefcount(resource);
        caches.resourceCache.incrementRefcountLocked(resource);
    }

    const Vector<SkBitmap*> &ownedBitmapResources = recorder.getOwnedBitmapResources();
    for (size_t i = 0; i < ownedBitmapResources.size(); i++) {
        SkBitmap* resource = ownedBitmapResources.itemAt(i);
        mOwnedBitmapResources.add(resource);
        caches.resourceCache.incrementRefcount(resource);
        caches.resourceCache.incrementRefcountLocked(resource);
    }

    const Vector<SkiaColorFilter*>& filterResources = recorder.getFilterResources();
    for (size_t i = 0; i < filterResources.size(); i++) {
        SkiaColorFilter* resource = filterResources.itemAt(i);
        mFilterResources.add(resource);
        caches.resourceCache.incrementRefcount(resource);
        caches.resourceCache.incrementRefcountLocked(resource);
    }

    const Vector<SkiaShader*>& shaders = recorder.getShaders();
    for (size_t i = 0; i < shaders.size(); i++) {
        SkiaShader* resource = shaders.itemAt(i);
        mShaders.add(resource);
        caches.resourceCache.incrementRefcount(resource);
        caches.resourceCache.incrementRefcountLocked(resource);
    }

    const SortedVector<SkPath*>& sourcePaths = recorder.getSourcePaths();
    for (size_t i = 0; i < sourcePaths.size(); i++) {
        mSourcePaths.add(sourcePaths.itemAt(i));
        caches.resourceCache.incrementRefcountLocked(sourcePaths.itemAt(i));
    }

    caches.resourceCache.unlock();

    const Vector<SkPaint*>& paints = recorder.getPaints();
    for (size_t i = 0; i < paints.size(); i++) {
        mPaints.add(paints.itemAt(i));
@@ -262,12 +276,6 @@ void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorde
        mPaths.add(paths.itemAt(i));
    }

    const SortedVector<SkPath*>& sourcePaths = recorder.getSourcePaths();
    for (size_t i = 0; i < sourcePaths.size(); i++) {
        mSourcePaths.add(sourcePaths.itemAt(i));
        caches.resourceCache.incrementRefcount(sourcePaths.itemAt(i));
    }

    const Vector<SkMatrix*>& matrices = recorder.getMatrices();
    for (size_t i = 0; i < matrices.size(); i++) {
        mMatrices.add(matrices.itemAt(i));
@@ -1309,7 +1317,8 @@ status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flag
// Base structure
///////////////////////////////////////////////////////////////////////////////

DisplayListRenderer::DisplayListRenderer() : mWriter(MIN_WRITER_SIZE),
DisplayListRenderer::DisplayListRenderer():
        mCaches(Caches::getInstance()), mWriter(MIN_WRITER_SIZE),
        mTranslateX(0.0f), mTranslateY(0.0f), mHasTranslate(false), mHasDrawOps(false) {
}

@@ -1320,34 +1329,38 @@ DisplayListRenderer::~DisplayListRenderer() {
void DisplayListRenderer::reset() {
    mWriter.reset();

    Caches& caches = Caches::getInstance();
    mCaches.resourceCache.lock();

    for (size_t i = 0; i < mBitmapResources.size(); i++) {
        caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i));
        mCaches.resourceCache.decrementRefcountLocked(mBitmapResources.itemAt(i));
    }
    mBitmapResources.clear();

    for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) {
        SkBitmap* bitmap = mOwnedBitmapResources.itemAt(i);
        caches.resourceCache.decrementRefcount(bitmap);
        mCaches.resourceCache.decrementRefcountLocked(mOwnedBitmapResources.itemAt(i));
    }
    mOwnedBitmapResources.clear();

    for (size_t i = 0; i < mFilterResources.size(); i++) {
        caches.resourceCache.decrementRefcount(mFilterResources.itemAt(i));
        mCaches.resourceCache.decrementRefcountLocked(mFilterResources.itemAt(i));
    }
    mFilterResources.clear();

    for (size_t i = 0; i < mShaders.size(); i++) {
        caches.resourceCache.decrementRefcount(mShaders.itemAt(i));
        mCaches.resourceCache.decrementRefcountLocked(mShaders.itemAt(i));
    }
    mShaders.clear();
    mShaderMap.clear();

    for (size_t i = 0; i < mSourcePaths.size(); i++) {
        caches.resourceCache.decrementRefcount(mSourcePaths.itemAt(i));
        mCaches.resourceCache.decrementRefcountLocked(mSourcePaths.itemAt(i));
    }

    mCaches.resourceCache.unlock();

    mBitmapResources.clear();
    mOwnedBitmapResources.clear();
    mFilterResources.clear();
    mSourcePaths.clear();

    mShaders.clear();
    mShaderMap.clear();

    mPaints.clear();
    mPaintMap.clear();

+8 −7
Original line number Diff line number Diff line
@@ -763,7 +763,7 @@ private:
            mPaths.add(pathCopy);
        }
        if (mSourcePaths.indexOf(path) < 0) {
            Caches::getInstance().resourceCache.incrementRefcount(path);
            mCaches.resourceCache.incrementRefcount(path);
            mSourcePaths.add(path);
        }

@@ -811,13 +811,13 @@ private:
        // which doesn't seem worth the extra cycles for this unlikely case.
        addInt((int) bitmap);
        mBitmapResources.add(bitmap);
        Caches::getInstance().resourceCache.incrementRefcount(bitmap);
        mCaches.resourceCache.incrementRefcount(bitmap);
    }

    void addBitmapData(SkBitmap* bitmap) {
        addInt((int) bitmap);
        mOwnedBitmapResources.add(bitmap);
        Caches::getInstance().resourceCache.incrementRefcount(bitmap);
        mCaches.resourceCache.incrementRefcount(bitmap);
    }

    inline void addShader(SkiaShader* shader) {
@@ -833,7 +833,7 @@ private:
            // replaceValueFor() performs an add if the entry doesn't exist
            mShaderMap.replaceValueFor(shader, shaderCopy);
            mShaders.add(shaderCopy);
            Caches::getInstance().resourceCache.incrementRefcount(shaderCopy);
            mCaches.resourceCache.incrementRefcount(shaderCopy);
        }

        addInt((int) shaderCopy);
@@ -842,7 +842,7 @@ private:
    inline void addColorFilter(SkiaColorFilter* colorFilter) {
        addInt((int) colorFilter);
        mFilterResources.add(colorFilter);
        Caches::getInstance().resourceCache.incrementRefcount(colorFilter);
        mCaches.resourceCache.incrementRefcount(colorFilter);
    }

    Vector<SkBitmap*> mBitmapResources;
@@ -862,15 +862,16 @@ private:

    Vector<SkMatrix*> mMatrices;

    SkWriter32 mWriter;
    uint32_t mBufferSize;

    int mRestoreSaveCount;

    Caches& mCaches;
    SkWriter32 mWriter;

    float mTranslateX;
    float mTranslateY;
    bool mHasTranslate;

    bool mHasDrawOps;

    friend class DisplayList;
+103 −27
Original line number Diff line number Diff line
@@ -46,15 +46,17 @@ ResourceCache::~ResourceCache() {
    delete mCache;
}

void ResourceCache::lock() {
    mLock.lock();
}

void ResourceCache::unlock() {
    mLock.unlock();
}

void ResourceCache::incrementRefcount(void* resource, ResourceType resourceType) {
    Mutex::Autolock _l(mLock);
    ssize_t index = mCache->indexOfKey(resource);
    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
    if (ref == NULL || mCache->size() == 0) {
        ref = new ResourceReference(resourceType);
        mCache->add(resource, ref);
    }
    ref->refCount++;
    incrementRefcountLocked(resource, resourceType);
}

void ResourceCache::incrementRefcount(SkBitmap* bitmapResource) {
@@ -77,18 +79,39 @@ void ResourceCache::incrementRefcount(SkiaColorFilter* filterResource) {
    incrementRefcount((void*) filterResource, kColorFilter);
}

void ResourceCache::decrementRefcount(void* resource) {
    Mutex::Autolock _l(mLock);
void ResourceCache::incrementRefcountLocked(void* resource, ResourceType resourceType) {
    ssize_t index = mCache->indexOfKey(resource);
    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
    if (ref == NULL) {
        // Should not get here - shouldn't get a call to decrement if we're not yet tracking it
        return;
    if (ref == NULL || mCache->size() == 0) {
        ref = new ResourceReference(resourceType);
        mCache->add(resource, ref);
    }
    ref->refCount--;
    if (ref->refCount == 0) {
        deleteResourceReference(resource, ref);
    ref->refCount++;
}

void ResourceCache::incrementRefcountLocked(SkBitmap* bitmapResource) {
    SkSafeRef(bitmapResource->pixelRef());
    SkSafeRef(bitmapResource->getColorTable());
    incrementRefcountLocked((void*) bitmapResource, kBitmap);
}

void ResourceCache::incrementRefcountLocked(SkPath* pathResource) {
    incrementRefcountLocked((void*) pathResource, kPath);
}

void ResourceCache::incrementRefcountLocked(SkiaShader* shaderResource) {
    SkSafeRef(shaderResource->getSkShader());
    incrementRefcountLocked((void*) shaderResource, kShader);
}

void ResourceCache::incrementRefcountLocked(SkiaColorFilter* filterResource) {
    SkSafeRef(filterResource->getSkColorFilter());
    incrementRefcountLocked((void*) filterResource, kColorFilter);
}

void ResourceCache::decrementRefcount(void* resource) {
    Mutex::Autolock _l(mLock);
    decrementRefcountLocked(resource);
}

void ResourceCache::decrementRefcount(SkBitmap* bitmapResource) {
@@ -111,27 +134,45 @@ void ResourceCache::decrementRefcount(SkiaColorFilter* filterResource) {
    decrementRefcount((void*) filterResource);
}

void ResourceCache::recycle(SkBitmap* resource) {
    Mutex::Autolock _l(mLock);
void ResourceCache::decrementRefcountLocked(void* resource) {
    ssize_t index = mCache->indexOfKey(resource);
    if (index < 0) {
        // not tracking this resource; just recycle the pixel data
        resource->setPixels(NULL, NULL);
        return;
    }
    ResourceReference* ref = mCache->valueAt(index);
    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
    if (ref == NULL) {
        // Should not get here - shouldn't get a call to recycle if we're not yet tracking it
        // Should not get here - shouldn't get a call to decrement if we're not yet tracking it
        return;
    }
    ref->recycled = true;
    ref->refCount--;
    if (ref->refCount == 0) {
        deleteResourceReference(resource, ref);
    }
}

void ResourceCache::decrementRefcountLocked(SkBitmap* bitmapResource) {
    SkSafeUnref(bitmapResource->pixelRef());
    SkSafeUnref(bitmapResource->getColorTable());
    decrementRefcountLocked((void*) bitmapResource);
}

void ResourceCache::decrementRefcountLocked(SkPath* pathResource) {
    decrementRefcountLocked((void*) pathResource);
}

void ResourceCache::decrementRefcountLocked(SkiaShader* shaderResource) {
    SkSafeUnref(shaderResource->getSkShader());
    decrementRefcountLocked((void*) shaderResource);
}

void ResourceCache::decrementRefcountLocked(SkiaColorFilter* filterResource) {
    SkSafeUnref(filterResource->getSkColorFilter());
    decrementRefcountLocked((void*) filterResource);
}

void ResourceCache::destructor(SkPath* resource) {
    Mutex::Autolock _l(mLock);
    destructorLocked(resource);
}

void ResourceCache::destructorLocked(SkPath* resource) {
    ssize_t index = mCache->indexOfKey(resource);
    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
    if (ref == NULL) {
@@ -150,6 +191,10 @@ void ResourceCache::destructor(SkPath* resource) {

void ResourceCache::destructor(SkBitmap* resource) {
    Mutex::Autolock _l(mLock);
    destructorLocked(resource);
}

void ResourceCache::destructorLocked(SkBitmap* resource) {
    ssize_t index = mCache->indexOfKey(resource);
    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
    if (ref == NULL) {
@@ -168,6 +213,10 @@ void ResourceCache::destructor(SkBitmap* resource) {

void ResourceCache::destructor(SkiaShader* resource) {
    Mutex::Autolock _l(mLock);
    destructorLocked(resource);
}

void ResourceCache::destructorLocked(SkiaShader* resource) {
    ssize_t index = mCache->indexOfKey(resource);
    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
    if (ref == NULL) {
@@ -183,6 +232,10 @@ void ResourceCache::destructor(SkiaShader* resource) {

void ResourceCache::destructor(SkiaColorFilter* resource) {
    Mutex::Autolock _l(mLock);
    destructorLocked(resource);
}

void ResourceCache::destructorLocked(SkiaColorFilter* resource) {
    ssize_t index = mCache->indexOfKey(resource);
    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
    if (ref == NULL) {
@@ -196,6 +249,29 @@ void ResourceCache::destructor(SkiaColorFilter* resource) {
    }
}

void ResourceCache::recycle(SkBitmap* resource) {
    Mutex::Autolock _l(mLock);
    recycleLocked(resource);
}

void ResourceCache::recycleLocked(SkBitmap* resource) {
    ssize_t index = mCache->indexOfKey(resource);
    if (index < 0) {
        // not tracking this resource; just recycle the pixel data
        resource->setPixels(NULL, NULL);
        return;
    }
    ResourceReference* ref = mCache->valueAt(index);
    if (ref == NULL) {
        // Should not get here - shouldn't get a call to recycle if we're not yet tracking it
        return;
    }
    ref->recycled = true;
    if (ref->refCount == 0) {
        deleteResourceReference(resource, ref);
    }
}

/**
 * This method should only be called while the mLock mutex is held (that mutex is grabbed
 * by the various destructor() and recycle() methods which call this method).
+37 −4
Original line number Diff line number Diff line
@@ -52,28 +52,59 @@ public:
};

class ANDROID_API ResourceCache {
    KeyedVector<void *, ResourceReference *>* mCache;
public:
    ResourceCache();
    ~ResourceCache();

    /**
     * When using these two methods, make sure to only invoke the *Locked()
     * variants of increment/decrementRefcount(), recyle() and destructor()
     */
    void lock();
    void unlock();

    void incrementRefcount(SkPath* resource);
    void incrementRefcount(SkBitmap* resource);
    void incrementRefcount(SkiaShader* resource);
    void incrementRefcount(SkiaColorFilter* resource);
    void incrementRefcount(const void* resource, ResourceType resourceType);
    void decrementRefcount(void* resource);

    void incrementRefcountLocked(SkPath* resource);
    void incrementRefcountLocked(SkBitmap* resource);
    void incrementRefcountLocked(SkiaShader* resource);
    void incrementRefcountLocked(SkiaColorFilter* resource);

    void decrementRefcount(SkBitmap* resource);
    void decrementRefcount(SkPath* resource);
    void decrementRefcount(SkiaShader* resource);
    void decrementRefcount(SkiaColorFilter* resource);
    void recycle(SkBitmap* resource);

    void decrementRefcountLocked(SkBitmap* resource);
    void decrementRefcountLocked(SkPath* resource);
    void decrementRefcountLocked(SkiaShader* resource);
    void decrementRefcountLocked(SkiaColorFilter* resource);

    void destructor(SkPath* resource);
    void destructor(SkBitmap* resource);
    void destructor(SkiaShader* resource);
    void destructor(SkiaColorFilter* resource);

    void destructorLocked(SkPath* resource);
    void destructorLocked(SkBitmap* resource);
    void destructorLocked(SkiaShader* resource);
    void destructorLocked(SkiaColorFilter* resource);

    void recycle(SkBitmap* resource);
    void recycleLocked(SkBitmap* resource);

private:
    void deleteResourceReference(void* resource, ResourceReference* ref);

    void incrementRefcount(void* resource, ResourceType resourceType);
    void incrementRefcountLocked(void* resource, ResourceType resourceType);

    void decrementRefcount(void* resource);
    void decrementRefcountLocked(void* resource);

    void logCache();

    /**
@@ -82,6 +113,8 @@ private:
     * or a reference queue finalization thread.
     */
    mutable Mutex mLock;

    KeyedVector<void*, ResourceReference*>* mCache;
};

}; // namespace uirenderer