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
This commit is contained in:
@@ -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,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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -143,6 +143,8 @@ public:
|
||||
|
||||
static void repackVectorDrawableAtlas();
|
||||
|
||||
static void releaseVDAtlasEntries();
|
||||
|
||||
private:
|
||||
RenderThread& mRenderThread;
|
||||
CanvasContext* mContext;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -111,6 +111,14 @@ public:
|
||||
sk_sp<Bitmap> allocateHardwareBitmap(SkBitmap& skBitmap);
|
||||
void dumpGraphicsMemory(int fd);
|
||||
|
||||
/**
|
||||
* isCurrent provides a way to query, if the caller is running on
|
||||
* the render thread.
|
||||
*
|
||||
* @return true only if isCurrent is invoked from the render thread.
|
||||
*/
|
||||
static bool isCurrent();
|
||||
|
||||
protected:
|
||||
virtual bool threadLoop() override;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user