summaryrefslogtreecommitdiff
path: root/libs/hwui/ShapeCache.h
diff options
context:
space:
mode:
Diffstat (limited to 'libs/hwui/ShapeCache.h')
-rw-r--r--libs/hwui/ShapeCache.h816
1 files changed, 0 insertions, 816 deletions
diff --git a/libs/hwui/ShapeCache.h b/libs/hwui/ShapeCache.h
deleted file mode 100644
index 92314b029520..000000000000
--- a/libs/hwui/ShapeCache.h
+++ /dev/null
@@ -1,816 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HWUI_SHAPE_CACHE_H
-#define ANDROID_HWUI_SHAPE_CACHE_H
-
-#define ATRACE_TAG ATRACE_TAG_VIEW
-
-#include <GLES2/gl2.h>
-
-#include <SkBitmap.h>
-#include <SkCanvas.h>
-#include <SkPaint.h>
-#include <SkPath.h>
-#include <SkRect.h>
-
-#include <utils/JenkinsHash.h>
-#include <utils/LruCache.h>
-#include <utils/Trace.h>
-
-#include "Debug.h"
-#include "Properties.h"
-#include "Texture.h"
-#include "thread/Task.h"
-
-namespace android {
-namespace uirenderer {
-
-///////////////////////////////////////////////////////////////////////////////
-// Defines
-///////////////////////////////////////////////////////////////////////////////
-
-// Debug
-#if DEBUG_SHAPES
- #define SHAPE_LOGD(...) ALOGD(__VA_ARGS__)
-#else
- #define SHAPE_LOGD(...)
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-// Classes
-///////////////////////////////////////////////////////////////////////////////
-
-/**
- * Alpha texture used to represent a path.
- */
-struct PathTexture: public Texture {
- PathTexture(): Texture() {
- }
-
- ~PathTexture() {
- clearTask();
- }
-
- /**
- * Left coordinate of the path bounds.
- */
- float left;
- /**
- * Top coordinate of the path bounds.
- */
- float top;
- /**
- * Offset to draw the path at the correct origin.
- */
- float offset;
-
- sp<Task<SkBitmap*> > task() const {
- return mTask;
- }
-
- void setTask(const sp<Task<SkBitmap*> >& task) {
- mTask = task;
- }
-
- void clearTask() {
- if (mTask != NULL) {
- mTask.clear();
- }
- }
-
-private:
- sp<Task<SkBitmap*> > mTask;
-}; // struct PathTexture
-
-/**
- * Describe a shape in the shape cache.
- */
-struct ShapeCacheEntry {
- enum ShapeType {
- kShapeNone,
- kShapeRect,
- kShapeRoundRect,
- kShapeCircle,
- kShapeOval,
- kShapeArc,
- kShapePath
- };
-
- ShapeCacheEntry() {
- shapeType = kShapeNone;
- join = SkPaint::kDefault_Join;
- cap = SkPaint::kDefault_Cap;
- style = SkPaint::kFill_Style;
- miter = 4.0f;
- strokeWidth = 1.0f;
- pathEffect = NULL;
- }
-
- ShapeCacheEntry(ShapeType type, SkPaint* paint) {
- shapeType = type;
- join = paint->getStrokeJoin();
- cap = paint->getStrokeCap();
- miter = paint->getStrokeMiter();
- strokeWidth = paint->getStrokeWidth();
- style = paint->getStyle();
- pathEffect = paint->getPathEffect();
- }
-
- virtual ~ShapeCacheEntry() {
- }
-
- virtual hash_t hash() const {
- uint32_t hash = JenkinsHashMix(0, shapeType);
- hash = JenkinsHashMix(hash, join);
- hash = JenkinsHashMix(hash, cap);
- hash = JenkinsHashMix(hash, style);
- hash = JenkinsHashMix(hash, android::hash_type(miter));
- hash = JenkinsHashMix(hash, android::hash_type(strokeWidth));
- hash = JenkinsHashMix(hash, android::hash_type(pathEffect));
- return JenkinsHashWhiten(hash);
- }
-
- virtual int compare(const ShapeCacheEntry& rhs) const {
- int deltaInt = shapeType - rhs.shapeType;
- if (deltaInt != 0) return deltaInt;
-
- deltaInt = join - rhs.join;
- if (deltaInt != 0) return deltaInt;
-
- deltaInt = cap - rhs.cap;
- if (deltaInt != 0) return deltaInt;
-
- deltaInt = style - rhs.style;
- if (deltaInt != 0) return deltaInt;
-
- if (miter < rhs.miter) return -1;
- if (miter > rhs.miter) return +1;
-
- if (strokeWidth < rhs.strokeWidth) return -1;
- if (strokeWidth > rhs.strokeWidth) return +1;
-
- if (pathEffect < rhs.pathEffect) return -1;
- if (pathEffect > rhs.pathEffect) return +1;
-
- return 0;
- }
-
- bool operator==(const ShapeCacheEntry& other) const {
- return compare(other) == 0;
- }
-
- bool operator!=(const ShapeCacheEntry& other) const {
- return compare(other) != 0;
- }
-
- ShapeType shapeType;
- SkPaint::Join join;
- SkPaint::Cap cap;
- SkPaint::Style style;
- float miter;
- float strokeWidth;
- SkPathEffect* pathEffect;
-}; // struct ShapeCacheEntry
-
-// Cache support
-
-inline int strictly_order_type(const ShapeCacheEntry& lhs, const ShapeCacheEntry& rhs) {
- return lhs.compare(rhs) < 0;
-}
-
-inline int compare_type(const ShapeCacheEntry& lhs, const ShapeCacheEntry& rhs) {
- return lhs.compare(rhs);
-}
-
-inline hash_t hash_type(const ShapeCacheEntry& entry) {
- return entry.hash();
-}
-
-struct RoundRectShapeCacheEntry: public ShapeCacheEntry {
- RoundRectShapeCacheEntry(float width, float height, float rx, float ry, SkPaint* paint):
- ShapeCacheEntry(ShapeCacheEntry::kShapeRoundRect, paint) {
- mWidth = width;
- mHeight = height;
- mRx = rx;
- mRy = ry;
- }
-
- RoundRectShapeCacheEntry(): ShapeCacheEntry() {
- mWidth = 0;
- mHeight = 0;
- mRx = 0;
- mRy = 0;
- }
-
- hash_t hash() const {
- uint32_t hash = ShapeCacheEntry::hash();
- hash = JenkinsHashMix(hash, android::hash_type(mWidth));
- hash = JenkinsHashMix(hash, android::hash_type(mHeight));
- hash = JenkinsHashMix(hash, android::hash_type(mRx));
- hash = JenkinsHashMix(hash, android::hash_type(mRy));
- return JenkinsHashWhiten(hash);
- }
-
- int compare(const ShapeCacheEntry& r) const {
- int deltaInt = ShapeCacheEntry::compare(r);
- if (deltaInt != 0) return deltaInt;
-
- const RoundRectShapeCacheEntry& rhs = (const RoundRectShapeCacheEntry&) r;
-
- if (mWidth < rhs.mWidth) return -1;
- if (mWidth > rhs.mWidth) return +1;
-
- if (mHeight < rhs.mHeight) return -1;
- if (mHeight > rhs.mHeight) return +1;
-
- if (mRx < rhs.mRx) return -1;
- if (mRx > rhs.mRx) return +1;
-
- if (mRy < rhs.mRy) return -1;
- if (mRy > rhs.mRy) return +1;
-
- return 0;
- }
-
-private:
- float mWidth;
- float mHeight;
- float mRx;
- float mRy;
-}; // RoundRectShapeCacheEntry
-
-inline hash_t hash_type(const RoundRectShapeCacheEntry& entry) {
- return entry.hash();
-}
-
-struct CircleShapeCacheEntry: public ShapeCacheEntry {
- CircleShapeCacheEntry(float radius, SkPaint* paint):
- ShapeCacheEntry(ShapeCacheEntry::kShapeCircle, paint) {
- mRadius = radius;
- }
-
- CircleShapeCacheEntry(): ShapeCacheEntry() {
- mRadius = 0;
- }
-
- hash_t hash() const {
- uint32_t hash = ShapeCacheEntry::hash();
- hash = JenkinsHashMix(hash, android::hash_type(mRadius));
- return JenkinsHashWhiten(hash);
- }
-
- int compare(const ShapeCacheEntry& r) const {
- int deltaInt = ShapeCacheEntry::compare(r);
- if (deltaInt != 0) return deltaInt;
-
- const CircleShapeCacheEntry& rhs = (const CircleShapeCacheEntry&) r;
-
- if (mRadius < rhs.mRadius) return -1;
- if (mRadius > rhs.mRadius) return +1;
-
- return 0;
- }
-
-private:
- float mRadius;
-}; // CircleShapeCacheEntry
-
-inline hash_t hash_type(const CircleShapeCacheEntry& entry) {
- return entry.hash();
-}
-
-struct OvalShapeCacheEntry: public ShapeCacheEntry {
- OvalShapeCacheEntry(float width, float height, SkPaint* paint):
- ShapeCacheEntry(ShapeCacheEntry::kShapeOval, paint) {
- mWidth = width;
- mHeight = height;
- }
-
- OvalShapeCacheEntry(): ShapeCacheEntry() {
- mWidth = mHeight = 0;
- }
-
- hash_t hash() const {
- uint32_t hash = ShapeCacheEntry::hash();
- hash = JenkinsHashMix(hash, android::hash_type(mWidth));
- hash = JenkinsHashMix(hash, android::hash_type(mHeight));
- return JenkinsHashWhiten(hash);
- }
-
- int compare(const ShapeCacheEntry& r) const {
- int deltaInt = ShapeCacheEntry::compare(r);
- if (deltaInt != 0) return deltaInt;
-
- const OvalShapeCacheEntry& rhs = (const OvalShapeCacheEntry&) r;
-
- if (mWidth < rhs.mWidth) return -1;
- if (mWidth > rhs.mWidth) return +1;
-
- if (mHeight < rhs.mHeight) return -1;
- if (mHeight > rhs.mHeight) return +1;
-
- return 0;
- }
-
-private:
- float mWidth;
- float mHeight;
-}; // OvalShapeCacheEntry
-
-inline hash_t hash_type(const OvalShapeCacheEntry& entry) {
- return entry.hash();
-}
-
-struct RectShapeCacheEntry: public ShapeCacheEntry {
- RectShapeCacheEntry(float width, float height, SkPaint* paint):
- ShapeCacheEntry(ShapeCacheEntry::kShapeRect, paint) {
- mWidth = width;
- mHeight = height;
- }
-
- RectShapeCacheEntry(): ShapeCacheEntry() {
- mWidth = mHeight = 0;
- }
-
- hash_t hash() const {
- uint32_t hash = ShapeCacheEntry::hash();
- hash = JenkinsHashMix(hash, android::hash_type(mWidth));
- hash = JenkinsHashMix(hash, android::hash_type(mHeight));
- return JenkinsHashWhiten(hash);
- }
-
- int compare(const ShapeCacheEntry& r) const {
- int deltaInt = ShapeCacheEntry::compare(r);
- if (deltaInt != 0) return deltaInt;
-
- const RectShapeCacheEntry& rhs = (const RectShapeCacheEntry&) r;
-
- if (mWidth < rhs.mWidth) return -1;
- if (mWidth > rhs.mWidth) return +1;
-
- if (mHeight < rhs.mHeight) return -1;
- if (mHeight > rhs.mHeight) return +1;
-
- return 0;
- }
-
-private:
- float mWidth;
- float mHeight;
-}; // RectShapeCacheEntry
-
-inline hash_t hash_type(const RectShapeCacheEntry& entry) {
- return entry.hash();
-}
-
-struct ArcShapeCacheEntry: public ShapeCacheEntry {
- ArcShapeCacheEntry(float width, float height, float startAngle, float sweepAngle,
- bool useCenter, SkPaint* paint):
- ShapeCacheEntry(ShapeCacheEntry::kShapeArc, paint) {
- mWidth = width;
- mHeight = height;
- mStartAngle = startAngle;
- mSweepAngle = sweepAngle;
- mUseCenter = useCenter ? 1 : 0;
- }
-
- ArcShapeCacheEntry(): ShapeCacheEntry() {
- mWidth = 0;
- mHeight = 0;
- mStartAngle = 0;
- mSweepAngle = 0;
- mUseCenter = 0;
- }
-
- hash_t hash() const {
- uint32_t hash = ShapeCacheEntry::hash();
- hash = JenkinsHashMix(hash, android::hash_type(mWidth));
- hash = JenkinsHashMix(hash, android::hash_type(mHeight));
- hash = JenkinsHashMix(hash, android::hash_type(mStartAngle));
- hash = JenkinsHashMix(hash, android::hash_type(mSweepAngle));
- hash = JenkinsHashMix(hash, mUseCenter);
- return JenkinsHashWhiten(hash);
- }
-
- int compare(const ShapeCacheEntry& r) const {
- int deltaInt = ShapeCacheEntry::compare(r);
- if (deltaInt != 0) return deltaInt;
-
- const ArcShapeCacheEntry& rhs = (const ArcShapeCacheEntry&) r;
-
- if (mWidth < rhs.mWidth) return -1;
- if (mWidth > rhs.mWidth) return +1;
-
- if (mHeight < rhs.mHeight) return -1;
- if (mHeight > rhs.mHeight) return +1;
-
- if (mStartAngle < rhs.mStartAngle) return -1;
- if (mStartAngle > rhs.mStartAngle) return +1;
-
- if (mSweepAngle < rhs.mSweepAngle) return -1;
- if (mSweepAngle > rhs.mSweepAngle) return +1;
-
- return mUseCenter - rhs.mUseCenter;
- }
-
-private:
- float mWidth;
- float mHeight;
- float mStartAngle;
- float mSweepAngle;
- uint32_t mUseCenter;
-}; // ArcShapeCacheEntry
-
-inline hash_t hash_type(const ArcShapeCacheEntry& entry) {
- return entry.hash();
-}
-
-/**
- * A simple LRU shape cache. The cache has a maximum size expressed in bytes.
- * Any texture added to the cache causing the cache to grow beyond the maximum
- * allowed size will also cause the oldest texture to be kicked out.
- */
-template<typename Entry>
-class ShapeCache: public OnEntryRemoved<Entry, PathTexture*> {
-public:
- ShapeCache(const char* name, const char* propertyName, float defaultSize);
- ~ShapeCache();
-
- /**
- * Used as a callback when an entry is removed from the cache.
- * Do not invoke directly.
- */
- void operator()(Entry& path, PathTexture*& texture);
-
- /**
- * Clears the cache. This causes all textures to be deleted.
- */
- void clear();
-
- /**
- * Sets the maximum size of the cache in bytes.
- */
- void setMaxSize(uint32_t maxSize);
- /**
- * Returns the maximum size of the cache in bytes.
- */
- uint32_t getMaxSize();
- /**
- * Returns the current size of the cache in bytes.
- */
- uint32_t getSize();
-
- /**
- * Trims the contents of the cache, removing items until it's under its
- * specified limit.
- *
- * Trimming is used for caches that support pre-caching from a worker
- * thread. During pre-caching the maximum limit of the cache can be
- * exceeded for the duration of the frame. It is therefore required to
- * trim the cache at the end of the frame to keep the total amount of
- * memory used under control.
- *
- * Only the PathCache currently supports pre-caching.
- */
- void trim();
-
- static 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);
- }
-
- static 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);
-
- left = bounds.fLeft;
- top = bounds.fTop;
-
- offset = (int) floorf(fmax(paint->getStrokeWidth(), 1.0f) * 1.5f + 0.5f);
-
- width = uint32_t(pathWidth + offset * 2.0 + 0.5);
- height = uint32_t(pathHeight + offset * 2.0 + 0.5);
- }
-
- static void drawPath(const SkPath *path, const SkPaint* paint, SkBitmap& bitmap,
- float left, float top, float offset, uint32_t width, uint32_t height) {
- initBitmap(bitmap, width, height);
-
- SkPaint pathPaint(*paint);
- initPaint(pathPaint);
-
- SkCanvas canvas(bitmap);
- canvas.translate(-left + offset, -top + offset);
- canvas.drawPath(*path, pathPaint);
- }
-
-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);
-
- PathTexture* get(Entry entry) {
- return mCache.get(entry);
- }
-
- void removeTexture(PathTexture* texture);
-
- bool 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;
- }
-
- 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;
- }
-
- static void initBitmap(SkBitmap& bitmap, uint32_t width, uint32_t height) {
- bitmap.setConfig(SkBitmap::kA8_Config, width, height);
- bitmap.allocPixels();
- bitmap.eraseColor(0);
- }
-
- static void initPaint(SkPaint& paint) {
- // Make sure the paint is opaque, color, alpha, filter, etc.
- // will be applied later when compositing the alpha8 texture
- paint.setColor(0xff000000);
- paint.setAlpha(255);
- paint.setColorFilter(NULL);
- paint.setMaskFilter(NULL);
- paint.setShader(NULL);
- SkXfermode* mode = SkXfermode::Create(SkXfermode::kSrc_Mode);
- SkSafeUnref(paint.setXfermode(mode));
- }
-
- LruCache<Entry, PathTexture*> mCache;
- uint32_t mSize;
- uint32_t mMaxSize;
- GLuint mMaxTextureSize;
-
- char* mName;
- bool mDebugEnabled;
-
-private:
- /**
- * Generates the texture from a bitmap into the specified texture structure.
- */
- void generateTexture(SkBitmap& bitmap, Texture* texture);
-
- void init();
-}; // class ShapeCache
-
-class RoundRectShapeCache: public ShapeCache<RoundRectShapeCacheEntry> {
-public:
- RoundRectShapeCache();
-
- PathTexture* getRoundRect(float width, float height, float rx, float ry, SkPaint* paint);
-}; // class RoundRectShapeCache
-
-class CircleShapeCache: public ShapeCache<CircleShapeCacheEntry> {
-public:
- CircleShapeCache();
-
- PathTexture* getCircle(float radius, SkPaint* paint);
-}; // class CircleShapeCache
-
-class OvalShapeCache: public ShapeCache<OvalShapeCacheEntry> {
-public:
- OvalShapeCache();
-
- PathTexture* getOval(float width, float height, SkPaint* paint);
-}; // class OvalShapeCache
-
-class RectShapeCache: public ShapeCache<RectShapeCacheEntry> {
-public:
- RectShapeCache();
-
- PathTexture* getRect(float width, float height, SkPaint* paint);
-}; // class RectShapeCache
-
-class ArcShapeCache: public ShapeCache<ArcShapeCacheEntry> {
-public:
- ArcShapeCache();
-
- PathTexture* getArc(float width, float height, float startAngle, float sweepAngle,
- bool useCenter, SkPaint* paint);
-}; // class ArcShapeCache
-
-///////////////////////////////////////////////////////////////////////////////
-// Constructors/destructor
-///////////////////////////////////////////////////////////////////////////////
-
-template<class Entry>
-ShapeCache<Entry>::ShapeCache(const char* name, const char* propertyName, float defaultSize):
- mCache(LruCache<ShapeCacheEntry, PathTexture*>::kUnlimitedCapacity),
- mSize(0), mMaxSize(MB(defaultSize)) {
- char property[PROPERTY_VALUE_MAX];
- if (property_get(propertyName, property, NULL) > 0) {
- INIT_LOGD(" Setting %s cache size to %sMB", name, property);
- setMaxSize(MB(atof(property)));
- } else {
- INIT_LOGD(" Using default %s cache size of %.2fMB", name, defaultSize);
- }
-
- size_t len = strlen(name);
- mName = new char[len + 1];
- strcpy(mName, name);
- mName[len] = '\0';
-
- init();
-}
-
-template<class Entry>
-ShapeCache<Entry>::~ShapeCache() {
- mCache.clear();
- delete[] mName;
-}
-
-template<class Entry>
-void ShapeCache<Entry>::init() {
- mCache.setOnEntryRemovedListener(this);
-
- GLint maxTextureSize;
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
- mMaxTextureSize = maxTextureSize;
-
- mDebugEnabled = readDebugLevel() & kDebugCaches;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Size management
-///////////////////////////////////////////////////////////////////////////////
-
-template<class Entry>
-uint32_t ShapeCache<Entry>::getSize() {
- return mSize;
-}
-
-template<class Entry>
-uint32_t ShapeCache<Entry>::getMaxSize() {
- return mMaxSize;
-}
-
-template<class Entry>
-void ShapeCache<Entry>::setMaxSize(uint32_t maxSize) {
- mMaxSize = maxSize;
- while (mSize > mMaxSize) {
- mCache.removeOldest();
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Callbacks
-///////////////////////////////////////////////////////////////////////////////
-
-template<class Entry>
-void ShapeCache<Entry>::operator()(Entry& path, PathTexture*& texture) {
- removeTexture(texture);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Caching
-///////////////////////////////////////////////////////////////////////////////
-
-template<class Entry>
-void ShapeCache<Entry>::removeTexture(PathTexture* texture) {
- if (texture) {
- const uint32_t size = texture->width * texture->height;
- mSize -= size;
-
- SHAPE_LOGD("ShapeCache::callback: delete %s: name, size, mSize = %d, %d, %d",
- mName, texture->id, size, mSize);
- if (mDebugEnabled) {
- ALOGD("Shape %s deleted, size = %d", mName, size);
- }
-
- if (texture->id) {
- glDeleteTextures(1, &texture->id);
- }
- delete 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) {
- while (mSize + size > mMaxSize) {
- mCache.removeOldest();
- }
- }
-}
-
-template<class Entry>
-void ShapeCache<Entry>::trim() {
- while (mSize > mMaxSize) {
- mCache.removeOldest();
- }
-}
-
-template<class Entry>
-PathTexture* ShapeCache<Entry>::addTexture(const Entry& entry, const SkPath *path,
- const SkPaint* paint) {
- ATRACE_CALL();
-
- 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;
- drawPath(path, paint, bitmap, left, top, offset, width, height);
-
- 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",
- mName, texture->id, size, mSize);
- if (mDebugEnabled) {
- ALOGD("Shape %s created, size = %d", mName, size);
- }
- mCache.put(entry, texture);
- } else {
- texture->cleanup = true;
- }
-}
-
-template<class Entry>
-void ShapeCache<Entry>::clear() {
- mCache.clear();
-}
-
-template<class Entry>
-void ShapeCache<Entry>::generateTexture(SkBitmap& bitmap, Texture* texture) {
- SkAutoLockPixels alp(bitmap);
- if (!bitmap.readyToDraw()) {
- ALOGE("Cannot generate texture from bitmap");
- return;
- }
-
- glGenTextures(1, &texture->id);
-
- glBindTexture(GL_TEXTURE_2D, texture->id);
- // Textures are Alpha8
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-
- texture->blend = true;
- glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, texture->width, texture->height, 0,
- GL_ALPHA, GL_UNSIGNED_BYTE, bitmap.getPixels());
-
- texture->setFilter(GL_LINEAR);
- texture->setWrap(GL_CLAMP_TO_EDGE);
-}
-
-}; // namespace uirenderer
-}; // namespace android
-
-#endif // ANDROID_HWUI_SHAPE_CACHE_H