summaryrefslogtreecommitdiff
path: root/libs/hwui/VectorDrawable.cpp
diff options
context:
space:
mode:
authorStan Iliev <stani@google.com>2019-08-06 15:59:44 -0400
committerStan Iliev <stani@google.com>2019-08-09 15:52:05 -0400
commit52e4392ed0111a24ac83f0393907e092ceb844f3 (patch)
tree7905be5cda6dbac53ed9b213e07c2b38001b419f /libs/hwui/VectorDrawable.cpp
parent10952defd8e3b7e6d2e416f773ddeb47ea03ed85 (diff)
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
Diffstat (limited to 'libs/hwui/VectorDrawable.cpp')
-rw-r--r--libs/hwui/VectorDrawable.cpp44
1 files changed, 32 insertions, 12 deletions
diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp
index f91d178f01f3..61403aa93c97 100644
--- a/libs/hwui/VectorDrawable.cpp
+++ b/libs/hwui/VectorDrawable.cpp
@@ -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 {
@@ -472,7 +477,7 @@ void Tree::drawStaging(Canvas* outCanvas) {
mStagingProperties.getBounds().bottom(), &paint);
}
-void Tree::getPaintFor(SkPaint* outPaint, const TreeProperties &prop) const {
+void Tree::getPaintFor(SkPaint* outPaint, const TreeProperties& prop) const {
// HWUI always draws VD with bilinear filtering.
outPaint->setFilterQuality(kLow_SkFilterQuality);
if (prop.getColorFilter() != nullptr) {
@@ -492,7 +497,7 @@ Bitmap& Tree::getBitmapUpdateIfDirty() {
}
void Tree::updateCache(sp<skiapipeline::VectorDrawableAtlas>& atlas, GrContext* context) {
-#ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
+#ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
SkRect dst;
sk_sp<SkSurface> surface = mCache.getSurface(&dst);
bool canReuseSurface = surface && dst.width() >= mProperties.getScaledWidth() &&
@@ -533,7 +538,7 @@ void Tree::Cache::setAtlas(sp<skiapipeline::VectorDrawableAtlas> newAtlas,
sk_sp<SkSurface> Tree::Cache::getSurface(SkRect* bounds) {
sk_sp<SkSurface> surface;
-#ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
+#ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
sp<skiapipeline::VectorDrawableAtlas> atlas = mAtlas.promote();
if (atlas.get() && mAtlasKey != INVALID_ATLAS_KEY) {
auto atlasEntry = atlas->getEntry(mAtlasKey);
@@ -547,13 +552,28 @@ sk_sp<SkSurface> Tree::Cache::getSurface(SkRect* bounds) {
}
void Tree::Cache::clear() {
-#ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
- sp<skiapipeline::VectorDrawableAtlas> lockAtlas = mAtlas.promote();
- if (lockAtlas.get()) {
- lockAtlas->releaseEntry(mAtlasKey);
+#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);
+ }
+ } 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;
- mAtlasKey = INVALID_ATLAS_KEY;
#endif
}