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

Commit 52e4392e authored by Stan Iliev's avatar Stan Iliev
Browse files

Access VectorDrawableAtlas only on RenderThread

VectorDrawableAtlas dtor can run only on RenderThread, because
it releases GPU resources. It is usually CacheManager, which
destroys the atlas on RenderThread in response to trimMemory.
This CL fixes a rare situation, when a Java finalizer thread
deletes the atlas.

Bug: 137722646
Test: Manual testing on a device
Change-Id: I9d900809c23efaead9aaf16ee3306bc8c7c6b379
parent 10952def
Loading
Loading
Loading
Loading
+32 −12
Original line number Diff line number Diff line
@@ -16,19 +16,24 @@

#include "VectorDrawable.h"

#include <math.h>
#include <string.h>
#include <utils/Log.h>
#include "hwui/Paint.h"

#include "PathParser.h"
#include "SkColorFilter.h"
#include "SkImageInfo.h"
#include "SkShader.h"
#include "hwui/Paint.h"

#ifdef __ANDROID__
#include "renderthread/RenderThread.h"
#endif

#include "utils/Macros.h"
#include "utils/TraceUtils.h"
#include "utils/VectorDrawableUtils.h"

#include <math.h>
#include <string.h>

namespace android {
namespace uirenderer {
namespace VectorDrawable {
@@ -548,12 +553,27 @@ sk_sp<SkSurface> Tree::Cache::getSurface(SkRect* bounds) {

void Tree::Cache::clear() {
#ifdef __ANDROID__  // Layoutlib does not support hardware acceleration
    if (mAtlasKey != INVALID_ATLAS_KEY) {
        if (renderthread::RenderThread::isCurrent()) {
            sp<skiapipeline::VectorDrawableAtlas> lockAtlas = mAtlas.promote();
            if (lockAtlas.get()) {
                lockAtlas->releaseEntry(mAtlasKey);
            }
    mAtlas = nullptr;
        } else {
            // VectorDrawableAtlas can be accessed only on RenderThread.
            // Use by-copy capture of the current Cache variables, because "this" may not be valid
            // by the time the lambda is evaluated on RenderThread.
            renderthread::RenderThread::getInstance().queue().post(
                    [atlas = mAtlas, atlasKey = mAtlasKey]() {
                        sp<skiapipeline::VectorDrawableAtlas> lockAtlas = atlas.promote();
                        if (lockAtlas.get()) {
                            lockAtlas->releaseEntry(atlasKey);
                        }
                    });
        }
        mAtlasKey = INVALID_ATLAS_KEY;
    }
    mAtlas = nullptr;
#endif
}

+5 −0
Original line number Diff line number Diff line
@@ -53,6 +53,10 @@ namespace skiapipeline {
class VkFunctorDrawHandler;
}

namespace VectorDrawable {
class Tree;
}

namespace renderthread {

class CanvasContext;
@@ -138,6 +142,7 @@ private:
    friend class android::uirenderer::TestUtils;
    friend class android::uirenderer::WebViewFunctor;
    friend class android::uirenderer::skiapipeline::VkFunctorDrawHandler;
    friend class android::uirenderer::VectorDrawable::Tree;

    RenderThread();
    virtual ~RenderThread();