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

Commit 6b894d77 authored by Stan Iliev's avatar Stan Iliev
Browse files

Release VectorDrawable cache surface on render thread

Release VectorDrawable cache surface on render thread.
This is fixing an assert in skia GrSingleOwner.h:33.

Test: Ran gmail before and after the change.
Bug: 64842607
Change-Id: I46e0c2557ac5b2fc3be2cc2d35abf96f6d6c9399
parent b18835d4
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <cmath>
#include "utils/TraceUtils.h"
#include "renderthread/RenderProxy.h"
#include "renderthread/RenderThread.h"

namespace android {
namespace uirenderer {
@@ -228,6 +229,15 @@ AtlasEntry VectorDrawableAtlas::getEntry(AtlasKey atlasKey) {

void VectorDrawableAtlas::releaseEntry(AtlasKey atlasKey) {
    if (INVALID_ATLAS_KEY != atlasKey) {
        if (!renderthread::RenderThread::isCurrent()) {
            {
                AutoMutex _lock(mReleaseKeyLock);
                mKeysForRelease.push_back(atlasKey);
            }
            // invoke releaseEntry on the renderthread
            renderthread::RenderProxy::releaseVDAtlasEntries();
            return;
        }
        CacheEntry* entry = reinterpret_cast<CacheEntry*>(atlasKey);
        if (!entry->surface) {
            // Store freed atlas rectangles in "mFreeRects" and try to reuse them later, when atlas
@@ -245,6 +255,14 @@ void VectorDrawableAtlas::releaseEntry(AtlasKey atlasKey) {
    }
}

void VectorDrawableAtlas::delayedReleaseEntries() {
    AutoMutex _lock(mReleaseKeyLock);
    for (auto key : mKeysForRelease) {
        releaseEntry(key);
    }
    mKeysForRelease.clear();
}

sk_sp<SkSurface> VectorDrawableAtlas::createSurface(int width, int height, GrContext* context) {
#ifndef ANDROID_ENABLE_LINEAR_BLENDING
    sk_sp<SkColorSpace> colorSpace = nullptr;
+20 −1
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <SkSurface.h>
#include <utils/FatVector.h>
#include <utils/RefBase.h>
#include <utils/Thread.h>
#include <list>

class GrRectanizer;
@@ -103,12 +104,19 @@ public:

    /**
     * "releaseEntry" is invoked when a VectorDrawable is deleted. Passing a non-existing "atlasKey"
     * is causing an undefined behaviour.
     * is causing an undefined behaviour. This is the only function in the class that can be
     * invoked from any thread. It will marshal internally to render thread if needed.
     */
    void releaseEntry(AtlasKey atlasKey);

    void setStorageMode(StorageMode mode);

    /**
     * "delayedReleaseEntries" is indirectly invoked by "releaseEntry", when "releaseEntry" is
     * invoked from a non render thread.
     */
    void delayedReleaseEntries();

private:
    struct CacheEntry {
        CacheEntry(const SkRect& newVDrect, const SkRect& newRect,
@@ -182,6 +190,17 @@ private:
     */
    StorageMode mStorageMode;

    /**
     * mKeysForRelease is used by releaseEntry implementation to pass atlas keys from an arbitrary
     * calling thread to the render thread.
     */
    std::vector<AtlasKey> mKeysForRelease;

    /**
     * A lock used to protect access to mKeysForRelease.
     */
    Mutex mReleaseKeyLock;

    sk_sp<SkSurface> createSurface(int width, int height, GrContext* context);

    inline bool fitInAtlas(int width, int height) {
+12 −0
Original line number Diff line number Diff line
@@ -732,6 +732,18 @@ void RenderProxy::repackVectorDrawableAtlas() {
    thread.queue(task);
}

CREATE_BRIDGE1(releaseVDAtlasEntries, RenderThread* thread) {
    args->thread->cacheManager().acquireVectorDrawableAtlas()->delayedReleaseEntries();
    return nullptr;
}

void RenderProxy::releaseVDAtlasEntries() {
    RenderThread& thread = RenderThread::getInstance();
    SETUP_TASK(releaseVDAtlasEntries);
    args->thread = &thread;
    thread.queue(task);
}

void* RenderProxy::postAndWait(MethodInvokeRenderTask* task) {
    void* retval;
    task->setReturnPtr(&retval);
+2 −0
Original line number Diff line number Diff line
@@ -143,6 +143,8 @@ public:

    static void repackVectorDrawableAtlas();

    static void releaseVDAtlasEntries();

private:
    RenderThread& mRenderThread;
    CanvasContext* mContext;
+4 −0
Original line number Diff line number Diff line
@@ -499,6 +499,10 @@ sk_sp<Bitmap> RenderThread::allocateHardwareBitmap(SkBitmap& skBitmap) {
    return nullptr;
}

bool RenderThread::isCurrent() {
    return gettid() == getInstance().getTid();
}

} /* namespace renderthread */
} /* namespace uirenderer */
} /* namespace android */
Loading