Loading libs/hwui/PathCache.cpp +6 −1 Original line number Diff line number Diff line Loading @@ -25,10 +25,15 @@ namespace android { namespace uirenderer { // Defined in ShapeCache.h void computePathBounds(const SkPath* path, const SkPaint* paint, float& left, float& top, float& offset, uint32_t& width, uint32_t& height) { const SkRect& bounds = path->getBounds(); computeBounds(bounds, paint, left, top, offset, width, height); } void computeBounds(const SkRect& bounds, const SkPaint* paint, float& left, float& top, float& offset, uint32_t& width, uint32_t& height) { const float pathWidth = fmax(bounds.width(), 1.0f); const float pathHeight = fmax(bounds.height(), 1.0f); Loading libs/hwui/ShapeCache.cpp +22 −3 Original line number Diff line number Diff line Loading @@ -105,10 +105,29 @@ PathTexture* RectShapeCache::getRect(float width, float height, SkPaint* paint) PathTexture* texture = get(entry); if (!texture) { SkPath path; path.addRect(0.0f, 0.0f, width, height, SkPath::kCW_Direction); SkRect bounds; bounds.set(0.0f, 0.0f, width, height); texture = addTexture(entry, &path, paint); float left, top, offset; uint32_t rectWidth, rectHeight; computeBounds(bounds, paint, left, top, offset, rectWidth, rectHeight); if (!checkTextureSize(rectWidth, rectHeight)) return NULL; purgeCache(rectWidth, rectHeight); SkBitmap bitmap; initBitmap(bitmap, rectWidth, rectHeight); SkPaint pathPaint(*paint); initPaint(pathPaint); SkCanvas canvas(bitmap); canvas.translate(-left + offset, -top + offset); canvas.drawRect(bounds, pathPaint); texture = createTexture(0, 0, offset, rectWidth, rectHeight, 0); addTexture(entry, &bitmap, texture); } return texture; Loading libs/hwui/ShapeCache.h +80 −34 Original line number Diff line number Diff line Loading @@ -336,6 +336,19 @@ public: protected: PathTexture* addTexture(const Entry& entry, const SkPath *path, const SkPaint* paint); PathTexture* addTexture(const Entry& entry, SkBitmap* bitmap); void addTexture(const Entry& entry, SkBitmap* bitmap, PathTexture* texture); /** * Ensures there is enough space in the cache for a texture of the specified * dimensions. */ void purgeCache(uint32_t width, uint32_t height); void initBitmap(SkBitmap& bitmap, uint32_t width, uint32_t height); void initPaint(SkPaint& paint); bool checkTextureSize(uint32_t width, uint32_t height); PathTexture* get(Entry entry) { return mCache.get(entry); Loading Loading @@ -491,21 +504,23 @@ void ShapeCache<Entry>::removeTexture(PathTexture* texture) { void computePathBounds(const SkPath* path, const SkPaint* paint, float& left, float& top, float& offset, uint32_t& width, uint32_t& height); void computeBounds(const SkRect& bounds, const SkPaint* paint, float& left, float& top, float& offset, uint32_t& width, uint32_t& height); template<class Entry> PathTexture* ShapeCache<Entry>::addTexture(const Entry& entry, const SkPath *path, const SkPaint* paint) { float left, top, offset; uint32_t width, height; computePathBounds(path, paint, left, top, offset, width, height); if (width > mMaxTextureSize || height > mMaxTextureSize) { ALOGW("Shape %s too large to be rendered into a texture (%dx%d, max=%dx%d)", mName, width, height, mMaxTextureSize, mMaxTextureSize); return NULL; static PathTexture* createTexture(float left, float top, float offset, uint32_t width, uint32_t height, uint32_t id) { PathTexture* texture = new PathTexture; texture->left = left; texture->top = top; texture->offset = offset; texture->width = width; texture->height = height; texture->generation = id; return texture; } template<class Entry> void ShapeCache<Entry>::purgeCache(uint32_t width, uint32_t height) { const uint32_t size = width * height; // Don't even try to cache a bitmap that's bigger than the cache if (size < mMaxSize) { Loading @@ -513,38 +528,71 @@ PathTexture* ShapeCache<Entry>::addTexture(const Entry& entry, const SkPath *pat mCache.removeOldest(); } } } PathTexture* texture = new PathTexture; texture->left = left; texture->top = top; texture->offset = offset; texture->width = width; texture->height = height; texture->generation = path->getGenerationID(); SkBitmap bitmap; template<class Entry> void ShapeCache<Entry>::initBitmap(SkBitmap& bitmap, uint32_t width, uint32_t height) { bitmap.setConfig(SkBitmap::kA8_Config, width, height); bitmap.allocPixels(); bitmap.eraseColor(0); } SkPaint pathPaint(*paint); template<class Entry> void ShapeCache<Entry>::initPaint(SkPaint& paint) { // Make sure the paint is opaque, color, alpha, filter, etc. // will be applied later when compositing the alpha8 texture pathPaint.setColor(0xff000000); pathPaint.setAlpha(255); pathPaint.setColorFilter(NULL); pathPaint.setMaskFilter(NULL); pathPaint.setShader(NULL); paint.setColor(0xff000000); paint.setAlpha(255); paint.setColorFilter(NULL); paint.setMaskFilter(NULL); paint.setShader(NULL); SkXfermode* mode = SkXfermode::Create(SkXfermode::kSrc_Mode); SkSafeUnref(pathPaint.setXfermode(mode)); SkSafeUnref(paint.setXfermode(mode)); } template<class Entry> bool ShapeCache<Entry>::checkTextureSize(uint32_t width, uint32_t height) { if (width > mMaxTextureSize || height > mMaxTextureSize) { ALOGW("Shape %s too large to be rendered into a texture (%dx%d, max=%dx%d)", mName, width, height, mMaxTextureSize, mMaxTextureSize); return false; } return true; } template<class Entry> PathTexture* ShapeCache<Entry>::addTexture(const Entry& entry, const SkPath *path, const SkPaint* paint) { float left, top, offset; uint32_t width, height; computePathBounds(path, paint, left, top, offset, width, height); if (!checkTextureSize(width, height)) return NULL; purgeCache(width, height); SkBitmap bitmap; initBitmap(bitmap, width, height); SkPaint pathPaint(*paint); initPaint(pathPaint); SkCanvas canvas(bitmap); canvas.translate(-left + offset, -top + offset); canvas.drawPath(*path, pathPaint); generateTexture(bitmap, texture); PathTexture* texture = createTexture(left, top, offset, width, height, path->getGenerationID()); addTexture(entry, &bitmap, texture); return texture; } template<class Entry> void ShapeCache<Entry>::addTexture(const Entry& entry, SkBitmap* bitmap, PathTexture* texture) { generateTexture(*bitmap, texture); uint32_t size = texture->width * texture->height; if (size < mMaxSize) { mSize += size; SHAPE_LOGD("ShapeCache::get: create %s: name, size, mSize = %d, %d, %d", Loading @@ -556,8 +604,6 @@ PathTexture* ShapeCache<Entry>::addTexture(const Entry& entry, const SkPath *pat } else { texture->cleanup = true; } return texture; } template<class Entry> Loading Loading
libs/hwui/PathCache.cpp +6 −1 Original line number Diff line number Diff line Loading @@ -25,10 +25,15 @@ namespace android { namespace uirenderer { // Defined in ShapeCache.h void computePathBounds(const SkPath* path, const SkPaint* paint, float& left, float& top, float& offset, uint32_t& width, uint32_t& height) { const SkRect& bounds = path->getBounds(); computeBounds(bounds, paint, left, top, offset, width, height); } void computeBounds(const SkRect& bounds, const SkPaint* paint, float& left, float& top, float& offset, uint32_t& width, uint32_t& height) { const float pathWidth = fmax(bounds.width(), 1.0f); const float pathHeight = fmax(bounds.height(), 1.0f); Loading
libs/hwui/ShapeCache.cpp +22 −3 Original line number Diff line number Diff line Loading @@ -105,10 +105,29 @@ PathTexture* RectShapeCache::getRect(float width, float height, SkPaint* paint) PathTexture* texture = get(entry); if (!texture) { SkPath path; path.addRect(0.0f, 0.0f, width, height, SkPath::kCW_Direction); SkRect bounds; bounds.set(0.0f, 0.0f, width, height); texture = addTexture(entry, &path, paint); float left, top, offset; uint32_t rectWidth, rectHeight; computeBounds(bounds, paint, left, top, offset, rectWidth, rectHeight); if (!checkTextureSize(rectWidth, rectHeight)) return NULL; purgeCache(rectWidth, rectHeight); SkBitmap bitmap; initBitmap(bitmap, rectWidth, rectHeight); SkPaint pathPaint(*paint); initPaint(pathPaint); SkCanvas canvas(bitmap); canvas.translate(-left + offset, -top + offset); canvas.drawRect(bounds, pathPaint); texture = createTexture(0, 0, offset, rectWidth, rectHeight, 0); addTexture(entry, &bitmap, texture); } return texture; Loading
libs/hwui/ShapeCache.h +80 −34 Original line number Diff line number Diff line Loading @@ -336,6 +336,19 @@ public: protected: PathTexture* addTexture(const Entry& entry, const SkPath *path, const SkPaint* paint); PathTexture* addTexture(const Entry& entry, SkBitmap* bitmap); void addTexture(const Entry& entry, SkBitmap* bitmap, PathTexture* texture); /** * Ensures there is enough space in the cache for a texture of the specified * dimensions. */ void purgeCache(uint32_t width, uint32_t height); void initBitmap(SkBitmap& bitmap, uint32_t width, uint32_t height); void initPaint(SkPaint& paint); bool checkTextureSize(uint32_t width, uint32_t height); PathTexture* get(Entry entry) { return mCache.get(entry); Loading Loading @@ -491,21 +504,23 @@ void ShapeCache<Entry>::removeTexture(PathTexture* texture) { void computePathBounds(const SkPath* path, const SkPaint* paint, float& left, float& top, float& offset, uint32_t& width, uint32_t& height); void computeBounds(const SkRect& bounds, const SkPaint* paint, float& left, float& top, float& offset, uint32_t& width, uint32_t& height); template<class Entry> PathTexture* ShapeCache<Entry>::addTexture(const Entry& entry, const SkPath *path, const SkPaint* paint) { float left, top, offset; uint32_t width, height; computePathBounds(path, paint, left, top, offset, width, height); if (width > mMaxTextureSize || height > mMaxTextureSize) { ALOGW("Shape %s too large to be rendered into a texture (%dx%d, max=%dx%d)", mName, width, height, mMaxTextureSize, mMaxTextureSize); return NULL; static PathTexture* createTexture(float left, float top, float offset, uint32_t width, uint32_t height, uint32_t id) { PathTexture* texture = new PathTexture; texture->left = left; texture->top = top; texture->offset = offset; texture->width = width; texture->height = height; texture->generation = id; return texture; } template<class Entry> void ShapeCache<Entry>::purgeCache(uint32_t width, uint32_t height) { const uint32_t size = width * height; // Don't even try to cache a bitmap that's bigger than the cache if (size < mMaxSize) { Loading @@ -513,38 +528,71 @@ PathTexture* ShapeCache<Entry>::addTexture(const Entry& entry, const SkPath *pat mCache.removeOldest(); } } } PathTexture* texture = new PathTexture; texture->left = left; texture->top = top; texture->offset = offset; texture->width = width; texture->height = height; texture->generation = path->getGenerationID(); SkBitmap bitmap; template<class Entry> void ShapeCache<Entry>::initBitmap(SkBitmap& bitmap, uint32_t width, uint32_t height) { bitmap.setConfig(SkBitmap::kA8_Config, width, height); bitmap.allocPixels(); bitmap.eraseColor(0); } SkPaint pathPaint(*paint); template<class Entry> void ShapeCache<Entry>::initPaint(SkPaint& paint) { // Make sure the paint is opaque, color, alpha, filter, etc. // will be applied later when compositing the alpha8 texture pathPaint.setColor(0xff000000); pathPaint.setAlpha(255); pathPaint.setColorFilter(NULL); pathPaint.setMaskFilter(NULL); pathPaint.setShader(NULL); paint.setColor(0xff000000); paint.setAlpha(255); paint.setColorFilter(NULL); paint.setMaskFilter(NULL); paint.setShader(NULL); SkXfermode* mode = SkXfermode::Create(SkXfermode::kSrc_Mode); SkSafeUnref(pathPaint.setXfermode(mode)); SkSafeUnref(paint.setXfermode(mode)); } template<class Entry> bool ShapeCache<Entry>::checkTextureSize(uint32_t width, uint32_t height) { if (width > mMaxTextureSize || height > mMaxTextureSize) { ALOGW("Shape %s too large to be rendered into a texture (%dx%d, max=%dx%d)", mName, width, height, mMaxTextureSize, mMaxTextureSize); return false; } return true; } template<class Entry> PathTexture* ShapeCache<Entry>::addTexture(const Entry& entry, const SkPath *path, const SkPaint* paint) { float left, top, offset; uint32_t width, height; computePathBounds(path, paint, left, top, offset, width, height); if (!checkTextureSize(width, height)) return NULL; purgeCache(width, height); SkBitmap bitmap; initBitmap(bitmap, width, height); SkPaint pathPaint(*paint); initPaint(pathPaint); SkCanvas canvas(bitmap); canvas.translate(-left + offset, -top + offset); canvas.drawPath(*path, pathPaint); generateTexture(bitmap, texture); PathTexture* texture = createTexture(left, top, offset, width, height, path->getGenerationID()); addTexture(entry, &bitmap, texture); return texture; } template<class Entry> void ShapeCache<Entry>::addTexture(const Entry& entry, SkBitmap* bitmap, PathTexture* texture) { generateTexture(*bitmap, texture); uint32_t size = texture->width * texture->height; if (size < mMaxSize) { mSize += size; SHAPE_LOGD("ShapeCache::get: create %s: name, size, mSize = %d, %d, %d", Loading @@ -556,8 +604,6 @@ PathTexture* ShapeCache<Entry>::addTexture(const Entry& entry, const SkPath *pat } else { texture->cleanup = true; } return texture; } template<class Entry> Loading