diff options
Diffstat (limited to 'libs/hwui/PathCache.cpp')
-rw-r--r-- | libs/hwui/PathCache.cpp | 139 |
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); |