summaryrefslogtreecommitdiffstats
path: root/libs/hwui/PathCache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/hwui/PathCache.cpp')
-rw-r--r--libs/hwui/PathCache.cpp139
1 files changed, 46 insertions, 93 deletions
diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp
index 6f48e4d..bdb44a6 100644
--- a/libs/hwui/PathCache.cpp
+++ b/libs/hwui/PathCache.cpp
@@ -31,7 +31,6 @@
#include "PathCache.h"
#include "thread/Signal.h"
-#include "thread/Task.h"
#include "thread/TaskProcessor.h"
namespace android {
@@ -41,25 +40,25 @@ namespace uirenderer {
// Cache entries
///////////////////////////////////////////////////////////////////////////////
-PathDescription::PathDescription():
- type(kShapeNone),
- join(SkPaint::kDefault_Join),
- cap(SkPaint::kDefault_Cap),
- style(SkPaint::kFill_Style),
- miter(4.0f),
- strokeWidth(1.0f),
- pathEffect(NULL) {
+PathDescription::PathDescription()
+ : type(kShapeNone)
+ , join(SkPaint::kDefault_Join)
+ , cap(SkPaint::kDefault_Cap)
+ , style(SkPaint::kFill_Style)
+ , miter(4.0f)
+ , strokeWidth(1.0f)
+ , pathEffect(nullptr) {
memset(&shape, 0, sizeof(Shape));
}
-PathDescription::PathDescription(ShapeType type, const SkPaint* paint):
- type(type),
- join(paint->getStrokeJoin()),
- cap(paint->getStrokeCap()),
- style(paint->getStyle()),
- miter(paint->getStrokeMiter()),
- strokeWidth(paint->getStrokeWidth()),
- pathEffect(paint->getPathEffect()) {
+PathDescription::PathDescription(ShapeType type, const SkPaint* paint)
+ : type(type)
+ , join(paint->getStrokeJoin())
+ , cap(paint->getStrokeCap())
+ , style(paint->getStyle())
+ , miter(paint->getStrokeMiter())
+ , strokeWidth(paint->getStrokeWidth())
+ , pathEffect(paint->getPathEffect()) {
memset(&shape, 0, sizeof(Shape));
}
@@ -81,7 +80,7 @@ hash_t PathDescription::hash() const {
bool PathCache::canDrawAsConvexPath(SkPath* path, const SkPaint* paint) {
// NOTE: This should only be used after PathTessellator handles joins properly
- return paint->getPathEffect() == NULL && path->getConvexity() == SkPath::kConvex_Convexity;
+ return paint->getPathEffect() == nullptr && path->getConvexity() == SkPath::kConvex_Convexity;
}
void PathCache::computePathBounds(const SkPath* path, const SkPaint* paint,
@@ -114,9 +113,9 @@ static void initPaint(SkPaint& paint) {
// will be applied later when compositing the alpha8 texture
paint.setColor(SK_ColorBLACK);
paint.setAlpha(255);
- paint.setColorFilter(NULL);
- paint.setMaskFilter(NULL);
- paint.setShader(NULL);
+ paint.setColorFilter(nullptr);
+ paint.setMaskFilter(nullptr);
+ paint.setShader(nullptr);
SkXfermode* mode = SkXfermode::Create(SkXfermode::kSrc_Mode);
SkSafeUnref(paint.setXfermode(mode));
}
@@ -133,18 +132,6 @@ static void drawPath(const SkPath *path, const SkPaint* paint, SkBitmap& bitmap,
canvas.drawPath(*path, pathPaint);
}
-static PathTexture* createTexture(float left, float top, float offset,
- uint32_t width, uint32_t height, uint32_t id) {
- PathTexture* texture = new PathTexture(Caches::getInstance());
- texture->left = left;
- texture->top = top;
- texture->offset = offset;
- texture->width = width;
- texture->height = height;
- texture->generation = id;
- return texture;
-}
-
///////////////////////////////////////////////////////////////////////////////
// Cache constructor/destructor
///////////////////////////////////////////////////////////////////////////////
@@ -153,7 +140,7 @@ PathCache::PathCache():
mCache(LruCache<PathDescription, PathTexture*>::kUnlimitedCapacity),
mSize(0), mMaxSize(MB(DEFAULT_PATH_CACHE_SIZE)) {
char property[PROPERTY_VALUE_MAX];
- if (property_get(PROPERTY_PATH_CACHE_SIZE, property, NULL) > 0) {
+ if (property_get(PROPERTY_PATH_CACHE_SIZE, property, nullptr) > 0) {
INIT_LOGD(" Setting %s cache size to %sMB", name, property);
setMaxSize(MB(atof(property)));
} else {
@@ -211,8 +198,8 @@ void PathCache::removeTexture(PathTexture* texture) {
// If there is a pending task we must wait for it to return
// before attempting our cleanup
const sp<Task<SkBitmap*> >& task = texture->task();
- if (task != NULL) {
- SkBitmap* bitmap = task->getResult();
+ if (task != nullptr) {
+ task->getResult();
texture->clearTask();
} else {
// If there is a pending task, the path was not added
@@ -231,7 +218,7 @@ void PathCache::removeTexture(PathTexture* texture) {
}
if (texture->id) {
- Caches::getInstance().deleteTexture(texture->id);
+ Caches::getInstance().textureState().deleteTexture(texture->id);
}
delete texture;
}
@@ -261,14 +248,15 @@ PathTexture* PathCache::addTexture(const PathDescription& entry, const SkPath *p
uint32_t width, height;
computePathBounds(path, paint, left, top, offset, width, height);
- if (!checkTextureSize(width, height)) return NULL;
+ if (!checkTextureSize(width, height)) return nullptr;
purgeCache(width, height);
SkBitmap bitmap;
drawPath(path, paint, bitmap, left, top, offset, width, height);
- PathTexture* texture = createTexture(left, top, offset, width, height,
+ PathTexture* texture = new PathTexture(Caches::getInstance(),
+ left, top, offset, width, height,
path->getGenerationID());
generateTexture(entry, &bitmap, texture);
@@ -313,7 +301,7 @@ void PathCache::generateTexture(SkBitmap& bitmap, Texture* texture) {
glGenTextures(1, &texture->id);
- Caches::getInstance().bindTexture(texture->id);
+ Caches::getInstance().textureState().bindTexture(texture->id);
// Textures are Alpha8
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
@@ -355,7 +343,7 @@ void PathCache::PathProcessor::onProcess(const sp<Task<SkBitmap*> >& task) {
} else {
texture->width = 0;
texture->height = 0;
- t->setResult(NULL);
+ t->setResult(nullptr);
}
}
@@ -363,22 +351,9 @@ void PathCache::PathProcessor::onProcess(const sp<Task<SkBitmap*> >& task) {
// Paths
///////////////////////////////////////////////////////////////////////////////
-void PathCache::remove(Vector<PathDescription>& pathsToRemove, const path_pair_t& pair) {
- LruCache<PathDescription, PathTexture*>::Iterator i(mCache);
-
- while (i.next()) {
- const PathDescription& key = i.key();
- if (key.type == kShapePath &&
- (key.shape.path.mPath == pair.getFirst() ||
- key.shape.path.mPath == pair.getSecond())) {
- pathsToRemove.push(key);
- }
- }
-}
-
-void PathCache::removeDeferred(SkPath* path) {
+void PathCache::removeDeferred(const SkPath* path) {
Mutex::Autolock l(mLock);
- mGarbage.push(path_pair_t(path, const_cast<SkPath*>(path->getSourcePath())));
+ mGarbage.push(path->getGenerationID());
}
void PathCache::clearGarbage() {
@@ -388,9 +363,15 @@ void PathCache::clearGarbage() {
Mutex::Autolock l(mLock);
size_t count = mGarbage.size();
for (size_t i = 0; i < count; i++) {
- const path_pair_t& pair = mGarbage.itemAt(i);
- remove(pathsToRemove, pair);
- delete pair.getFirst();
+ const uint32_t generationID = mGarbage.itemAt(i);
+
+ LruCache<PathDescription, PathTexture*>::Iterator iter(mCache);
+ while (iter.next()) {
+ const PathDescription& key = iter.key();
+ if (key.type == kShapePath && key.shape.path.mGenerationID == generationID) {
+ pathsToRemove.push(key);
+ }
+ }
}
mGarbage.clear();
}
@@ -400,27 +381,9 @@ void PathCache::clearGarbage() {
}
}
-/**
- * To properly handle path mutations at draw time we always make a copy
- * of paths objects when recording display lists. The source path points
- * to the path we originally copied the path from. This ensures we use
- * the original path as a cache key the first time a path is inserted
- * in the cache. The source path is also used to reclaim garbage when a
- * Dalvik Path object is collected.
- */
-static const SkPath* getSourcePath(const SkPath* path) {
- const SkPath* sourcePath = path->getSourcePath();
- if (sourcePath && sourcePath->getGenerationID() == path->getGenerationID()) {
- return const_cast<SkPath*>(sourcePath);
- }
- return path;
-}
-
PathTexture* PathCache::get(const SkPath* path, const SkPaint* paint) {
- path = getSourcePath(path);
-
PathDescription entry(kShapePath, paint);
- entry.shape.path.mPath = path;
+ entry.shape.path.mGenerationID = path->getGenerationID();
PathTexture* texture = mCache.get(entry);
@@ -430,7 +393,7 @@ PathTexture* PathCache::get(const SkPath* path, const SkPaint* paint) {
// A bitmap is attached to the texture, this means we need to
// upload it as a GL texture
const sp<Task<SkBitmap*> >& task = texture->task();
- if (task != NULL) {
+ if (task != nullptr) {
// But we must first wait for the worker thread to be done
// producing the bitmap, so let's wait
SkBitmap* bitmap = task->getResult();
@@ -440,14 +403,9 @@ PathTexture* PathCache::get(const SkPath* path, const SkPaint* paint) {
} else {
ALOGW("Path too large to be rendered into a texture");
texture->clearTask();
- texture = NULL;
+ texture = nullptr;
mCache.remove(entry);
}
- } else if (path->getGenerationID() != texture->generation) {
- // The size of the path might have changed so we first
- // remove the entry from the cache
- mCache.remove(entry);
- texture = addTexture(entry, path, paint);
}
}
@@ -459,25 +417,20 @@ void PathCache::precache(const SkPath* path, const SkPaint* paint) {
return;
}
- path = getSourcePath(path);
-
PathDescription entry(kShapePath, paint);
- entry.shape.path.mPath = path;
+ entry.shape.path.mGenerationID = path->getGenerationID();
PathTexture* texture = mCache.get(entry);
bool generate = false;
if (!texture) {
generate = true;
- } else if (path->getGenerationID() != texture->generation) {
- mCache.remove(entry);
- generate = true;
}
if (generate) {
// It is important to specify the generation ID so we do not
// attempt to precache the same path several times
- texture = createTexture(0.0f, 0.0f, 0.0f, 0, 0, path->getGenerationID());
+ texture = new PathTexture(Caches::getInstance(), path->getGenerationID());
sp<PathTask> task = new PathTask(path, paint, texture);
texture->setTask(task);
@@ -490,7 +443,7 @@ void PathCache::precache(const SkPath* path, const SkPaint* paint) {
// be enforced.
mCache.put(entry, texture);
- if (mProcessor == NULL) {
+ if (mProcessor == nullptr) {
mProcessor = new PathProcessor(Caches::getInstance());
}
mProcessor->add(task);