Loading core/java/android/view/ViewRoot.java +7 −7 Original line number Diff line number Diff line Loading @@ -489,17 +489,17 @@ public final class ViewRoot extends Handler implements ViewParent, // Try to enable hardware acceleration if requested if (attrs != null && (attrs.flags & WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0) { // Only enable hardware acceleration if we are not in the system process // The window manager creates ViewRoots to display animated preview windows // of launching apps and we don't want those to be hardware accelerated if (!HardwareRenderer.sRendererDisabled) { // Don't enable hardware acceleration when we're not on the main thread if (Looper.getMainLooper() != Looper.myLooper()) { Log.w(HardwareRenderer.LOG_TAG, "Attempting to initialize hardware acceleration " + "outside of the main thread, aborting"); Log.w(HardwareRenderer.LOG_TAG, "Attempting to initialize hardware " + "acceleration outside of the main thread, aborting"); return; } // Only enable hardware acceleration if we are not in the system process // The window manager creates ViewRoots to display animated preview windows // of launching apps and we don't want those to be hardware accelerated if (!HardwareRenderer.sRendererDisabled) { final boolean translucent = attrs.format != PixelFormat.OPAQUE; if (mAttachInfo.mHardwareRenderer != null) { mAttachInfo.mHardwareRenderer.destroy(true); Loading libs/hwui/Caches.h +1 −1 Original line number Diff line number Diff line Loading @@ -31,8 +31,8 @@ #include "GradientCache.h" #include "PatchCache.h" #include "ProgramCache.h" #include "PathCache.h" #include "ShapeCache.h" #include "PathCache.h" #include "TextDropShadowCache.h" #include "FboCache.h" #include "ResourceCache.h" Loading libs/hwui/Debug.h +0 −3 Original line number Diff line number Diff line Loading @@ -42,9 +42,6 @@ // This flag requires DEBUG_PATCHES to be turned on #define DEBUG_PATCHES_EMPTY_VERTICES 0 // Turn on to display debug info about paths #define DEBUG_PATHS 0 // Turn on to display debug info about shapes #define DEBUG_SHAPES 0 Loading libs/hwui/PathCache.cpp +3 −182 Original line number Diff line number Diff line Loading @@ -16,11 +16,6 @@ #define LOG_TAG "OpenGLRenderer" #include <GLES2/gl2.h> #include <SkCanvas.h> #include <SkRect.h> #include <utils/threads.h> #include "PathCache.h" Loading @@ -30,87 +25,11 @@ namespace android { namespace uirenderer { /////////////////////////////////////////////////////////////////////////////// // Constructors/destructor /////////////////////////////////////////////////////////////////////////////// PathCache::PathCache(): mCache(GenerationCache<PathCacheEntry, 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) { LOGD(" Setting path cache size to %sMB", property); setMaxSize(MB(atof(property))); } else { LOGD(" Using default path cache size of %.2fMB", DEFAULT_PATH_CACHE_SIZE); } init(); } PathCache::PathCache(uint32_t maxByteSize): mCache(GenerationCache<PathCacheEntry, PathTexture*>::kUnlimitedCapacity), mSize(0), mMaxSize(maxByteSize) { init(); } PathCache::~PathCache() { mCache.clear(); } void PathCache::init() { mCache.setOnEntryRemovedListener(this); GLint maxTextureSize; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); mMaxTextureSize = maxTextureSize; mDebugEnabled = readDebugLevel() & kDebugCaches; } /////////////////////////////////////////////////////////////////////////////// // Size management // Path cache /////////////////////////////////////////////////////////////////////////////// uint32_t PathCache::getSize() { return mSize; } uint32_t PathCache::getMaxSize() { return mMaxSize; } void PathCache::setMaxSize(uint32_t maxSize) { mMaxSize = maxSize; while (mSize > mMaxSize) { mCache.removeOldest(); } } /////////////////////////////////////////////////////////////////////////////// // Callbacks /////////////////////////////////////////////////////////////////////////////// void PathCache::operator()(PathCacheEntry& path, PathTexture*& texture) { removeTexture(texture); } /////////////////////////////////////////////////////////////////////////////// // Caching /////////////////////////////////////////////////////////////////////////////// void PathCache::removeTexture(PathTexture* texture) { if (texture) { const uint32_t size = texture->width * texture->height; mSize -= size; PATH_LOGD("PathCache::callback: delete path: name, size, mSize = %d, %d, %d", texture->id, size, mSize); if (mDebugEnabled) { LOGD("Path deleted, size = %d", size); } glDeleteTextures(1, &texture->id); delete texture; } PathCache::PathCache(): ShapeCache<PathCacheEntry>("path", PROPERTY_PATH_CACHE_SIZE, DEFAULT_PATH_CACHE_SIZE) { } void PathCache::remove(SkPath* path) { Loading Loading @@ -159,103 +78,5 @@ PathTexture* PathCache::get(SkPath* path, SkPaint* paint) { return texture; } PathTexture* PathCache::addTexture(const PathCacheEntry& entry, const SkPath *path, const SkPaint* paint) { const SkRect& bounds = path->getBounds(); const float pathWidth = fmax(bounds.width(), 1.0f); const float pathHeight = fmax(bounds.height(), 1.0f); if (pathWidth > mMaxTextureSize || pathHeight > mMaxTextureSize) { LOGW("Path too large to be rendered into a texture"); return NULL; } const float offset = entry.strokeWidth * 1.5f; const uint32_t width = uint32_t(pathWidth + offset * 2.0 + 0.5); const uint32_t height = uint32_t(pathHeight + offset * 2.0 + 0.5); 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(); } } PathTexture* texture = new PathTexture; texture->left = bounds.fLeft; texture->top = bounds.fTop; texture->offset = offset; texture->width = width; texture->height = height; texture->generation = path->getGenerationID(); SkBitmap bitmap; bitmap.setConfig(SkBitmap::kA8_Config, width, height); bitmap.allocPixels(); bitmap.eraseColor(0); SkPaint pathPaint(*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); SkXfermode* mode = SkXfermode::Create(SkXfermode::kSrc_Mode); pathPaint.setXfermode(mode)->safeUnref(); SkCanvas canvas(bitmap); canvas.translate(-bounds.fLeft + offset, -bounds.fTop + offset); canvas.drawPath(*path, pathPaint); generateTexture(bitmap, texture); if (size < mMaxSize) { mSize += size; PATH_LOGD("PathCache::get: create path: name, size, mSize = %d, %d, %d", texture->id, size, mSize); if (mDebugEnabled) { LOGD("Path created, size = %d", size); } mCache.put(entry, texture); } else { texture->cleanup = true; } return texture; } void PathCache::clear() { mCache.clear(); } void PathCache::generateTexture(SkBitmap& bitmap, Texture* texture) { SkAutoLockPixels alp(bitmap); if (!bitmap.readyToDraw()) { LOGE("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()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } }; // namespace uirenderer }; // namespace android libs/hwui/PathCache.h +17 −122 Original line number Diff line number Diff line Loading @@ -17,133 +17,60 @@ #ifndef ANDROID_HWUI_PATH_CACHE_H #define ANDROID_HWUI_PATH_CACHE_H #include <SkBitmap.h> #include <SkPaint.h> #include <SkPath.h> #include <utils/Vector.h> #include "Debug.h" #include "Texture.h" #include "ShapeCache.h" #include "utils/Compare.h" #include "utils/GenerationCache.h" namespace android { namespace uirenderer { /////////////////////////////////////////////////////////////////////////////// // Defines /////////////////////////////////////////////////////////////////////////////// // Debug #if DEBUG_PATHS #define PATH_LOGD(...) LOGD(__VA_ARGS__) #else #define PATH_LOGD(...) #endif /////////////////////////////////////////////////////////////////////////////// // Classes /////////////////////////////////////////////////////////////////////////////// /** * Describe a path in the path cache. */ struct PathCacheEntry { PathCacheEntry() { path = NULL; join = SkPaint::kDefault_Join; cap = SkPaint::kDefault_Cap; style = SkPaint::kFill_Style; miter = 4.0f; strokeWidth = 1.0f; struct PathCacheEntry: public ShapeCacheEntry { PathCacheEntry(SkPath* path, SkPaint* paint): ShapeCacheEntry(ShapeCacheEntry::kShapePath, paint) { this->path = path; } PathCacheEntry(const PathCacheEntry& entry): path(entry.path), join(entry.join), cap(entry.cap), style(entry.style), miter(entry.miter), strokeWidth(entry.strokeWidth) { PathCacheEntry(): ShapeCacheEntry() { path = NULL; } PathCacheEntry(SkPath* path, SkPaint* paint) { this->path = path; join = paint->getStrokeJoin(); cap = paint->getStrokeCap(); miter = paint->getStrokeMiter(); strokeWidth = paint->getStrokeWidth(); style = paint->getStyle(); PathCacheEntry(const PathCacheEntry& entry): ShapeCacheEntry(entry) { path = entry.path; } SkPath* path; SkPaint::Join join; SkPaint::Cap cap; SkPaint::Style style; float miter; float strokeWidth; bool operator<(const PathCacheEntry& rhs) const { bool lessThan(const ShapeCacheEntry& r) const { const PathCacheEntry& rhs = (const PathCacheEntry&) r; LTE_INT(path) { LTE_INT(join) { LTE_INT(cap) { LTE_INT(style) { LTE_FLOAT(miter) { LTE_FLOAT(strokeWidth) return false; } } } } } return false; } }; // struct PathCacheEntry /** * Alpha texture used to represent a path. */ struct PathTexture: public Texture { PathTexture(): Texture() { return false; } /** * 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; }; // struct PathTexture SkPath* path; }; // PathCacheEntry /** * A simple LRU path 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. */ class PathCache: public OnEntryRemoved<PathCacheEntry, PathTexture*> { class PathCache: public ShapeCache<PathCacheEntry> { public: PathCache(); PathCache(uint32_t maxByteSize); ~PathCache(); /** * Used as a callback when an entry is removed from the cache. * Do not invoke directly. */ void operator()(PathCacheEntry& path, PathTexture*& texture); /** * Returns the texture associated with the specified path. If the texture * cannot be found in the cache, a new texture is generated. */ PathTexture* get(SkPath* path, SkPaint* paint); /** * Clears the cache. This causes all textures to be deleted. */ void clear(); /** * Removes an entry. */ Loading @@ -158,39 +85,7 @@ public: */ void clearGarbage(); /** * 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(); private: /** * Generates the texture from a bitmap into the specified texture structure. */ void generateTexture(SkBitmap& bitmap, Texture* texture); void removeTexture(PathTexture* texture); PathTexture* addTexture(const PathCacheEntry& entry, const SkPath *path, const SkPaint* paint); void init(); GenerationCache<PathCacheEntry, PathTexture*> mCache; uint32_t mSize; uint32_t mMaxSize; GLuint mMaxTextureSize; bool mDebugEnabled; Vector<SkPath*> mGarbage; mutable Mutex mLock; }; // class PathCache Loading Loading
core/java/android/view/ViewRoot.java +7 −7 Original line number Diff line number Diff line Loading @@ -489,17 +489,17 @@ public final class ViewRoot extends Handler implements ViewParent, // Try to enable hardware acceleration if requested if (attrs != null && (attrs.flags & WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0) { // Only enable hardware acceleration if we are not in the system process // The window manager creates ViewRoots to display animated preview windows // of launching apps and we don't want those to be hardware accelerated if (!HardwareRenderer.sRendererDisabled) { // Don't enable hardware acceleration when we're not on the main thread if (Looper.getMainLooper() != Looper.myLooper()) { Log.w(HardwareRenderer.LOG_TAG, "Attempting to initialize hardware acceleration " + "outside of the main thread, aborting"); Log.w(HardwareRenderer.LOG_TAG, "Attempting to initialize hardware " + "acceleration outside of the main thread, aborting"); return; } // Only enable hardware acceleration if we are not in the system process // The window manager creates ViewRoots to display animated preview windows // of launching apps and we don't want those to be hardware accelerated if (!HardwareRenderer.sRendererDisabled) { final boolean translucent = attrs.format != PixelFormat.OPAQUE; if (mAttachInfo.mHardwareRenderer != null) { mAttachInfo.mHardwareRenderer.destroy(true); Loading
libs/hwui/Caches.h +1 −1 Original line number Diff line number Diff line Loading @@ -31,8 +31,8 @@ #include "GradientCache.h" #include "PatchCache.h" #include "ProgramCache.h" #include "PathCache.h" #include "ShapeCache.h" #include "PathCache.h" #include "TextDropShadowCache.h" #include "FboCache.h" #include "ResourceCache.h" Loading
libs/hwui/Debug.h +0 −3 Original line number Diff line number Diff line Loading @@ -42,9 +42,6 @@ // This flag requires DEBUG_PATCHES to be turned on #define DEBUG_PATCHES_EMPTY_VERTICES 0 // Turn on to display debug info about paths #define DEBUG_PATHS 0 // Turn on to display debug info about shapes #define DEBUG_SHAPES 0 Loading
libs/hwui/PathCache.cpp +3 −182 Original line number Diff line number Diff line Loading @@ -16,11 +16,6 @@ #define LOG_TAG "OpenGLRenderer" #include <GLES2/gl2.h> #include <SkCanvas.h> #include <SkRect.h> #include <utils/threads.h> #include "PathCache.h" Loading @@ -30,87 +25,11 @@ namespace android { namespace uirenderer { /////////////////////////////////////////////////////////////////////////////// // Constructors/destructor /////////////////////////////////////////////////////////////////////////////// PathCache::PathCache(): mCache(GenerationCache<PathCacheEntry, 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) { LOGD(" Setting path cache size to %sMB", property); setMaxSize(MB(atof(property))); } else { LOGD(" Using default path cache size of %.2fMB", DEFAULT_PATH_CACHE_SIZE); } init(); } PathCache::PathCache(uint32_t maxByteSize): mCache(GenerationCache<PathCacheEntry, PathTexture*>::kUnlimitedCapacity), mSize(0), mMaxSize(maxByteSize) { init(); } PathCache::~PathCache() { mCache.clear(); } void PathCache::init() { mCache.setOnEntryRemovedListener(this); GLint maxTextureSize; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); mMaxTextureSize = maxTextureSize; mDebugEnabled = readDebugLevel() & kDebugCaches; } /////////////////////////////////////////////////////////////////////////////// // Size management // Path cache /////////////////////////////////////////////////////////////////////////////// uint32_t PathCache::getSize() { return mSize; } uint32_t PathCache::getMaxSize() { return mMaxSize; } void PathCache::setMaxSize(uint32_t maxSize) { mMaxSize = maxSize; while (mSize > mMaxSize) { mCache.removeOldest(); } } /////////////////////////////////////////////////////////////////////////////// // Callbacks /////////////////////////////////////////////////////////////////////////////// void PathCache::operator()(PathCacheEntry& path, PathTexture*& texture) { removeTexture(texture); } /////////////////////////////////////////////////////////////////////////////// // Caching /////////////////////////////////////////////////////////////////////////////// void PathCache::removeTexture(PathTexture* texture) { if (texture) { const uint32_t size = texture->width * texture->height; mSize -= size; PATH_LOGD("PathCache::callback: delete path: name, size, mSize = %d, %d, %d", texture->id, size, mSize); if (mDebugEnabled) { LOGD("Path deleted, size = %d", size); } glDeleteTextures(1, &texture->id); delete texture; } PathCache::PathCache(): ShapeCache<PathCacheEntry>("path", PROPERTY_PATH_CACHE_SIZE, DEFAULT_PATH_CACHE_SIZE) { } void PathCache::remove(SkPath* path) { Loading Loading @@ -159,103 +78,5 @@ PathTexture* PathCache::get(SkPath* path, SkPaint* paint) { return texture; } PathTexture* PathCache::addTexture(const PathCacheEntry& entry, const SkPath *path, const SkPaint* paint) { const SkRect& bounds = path->getBounds(); const float pathWidth = fmax(bounds.width(), 1.0f); const float pathHeight = fmax(bounds.height(), 1.0f); if (pathWidth > mMaxTextureSize || pathHeight > mMaxTextureSize) { LOGW("Path too large to be rendered into a texture"); return NULL; } const float offset = entry.strokeWidth * 1.5f; const uint32_t width = uint32_t(pathWidth + offset * 2.0 + 0.5); const uint32_t height = uint32_t(pathHeight + offset * 2.0 + 0.5); 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(); } } PathTexture* texture = new PathTexture; texture->left = bounds.fLeft; texture->top = bounds.fTop; texture->offset = offset; texture->width = width; texture->height = height; texture->generation = path->getGenerationID(); SkBitmap bitmap; bitmap.setConfig(SkBitmap::kA8_Config, width, height); bitmap.allocPixels(); bitmap.eraseColor(0); SkPaint pathPaint(*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); SkXfermode* mode = SkXfermode::Create(SkXfermode::kSrc_Mode); pathPaint.setXfermode(mode)->safeUnref(); SkCanvas canvas(bitmap); canvas.translate(-bounds.fLeft + offset, -bounds.fTop + offset); canvas.drawPath(*path, pathPaint); generateTexture(bitmap, texture); if (size < mMaxSize) { mSize += size; PATH_LOGD("PathCache::get: create path: name, size, mSize = %d, %d, %d", texture->id, size, mSize); if (mDebugEnabled) { LOGD("Path created, size = %d", size); } mCache.put(entry, texture); } else { texture->cleanup = true; } return texture; } void PathCache::clear() { mCache.clear(); } void PathCache::generateTexture(SkBitmap& bitmap, Texture* texture) { SkAutoLockPixels alp(bitmap); if (!bitmap.readyToDraw()) { LOGE("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()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } }; // namespace uirenderer }; // namespace android
libs/hwui/PathCache.h +17 −122 Original line number Diff line number Diff line Loading @@ -17,133 +17,60 @@ #ifndef ANDROID_HWUI_PATH_CACHE_H #define ANDROID_HWUI_PATH_CACHE_H #include <SkBitmap.h> #include <SkPaint.h> #include <SkPath.h> #include <utils/Vector.h> #include "Debug.h" #include "Texture.h" #include "ShapeCache.h" #include "utils/Compare.h" #include "utils/GenerationCache.h" namespace android { namespace uirenderer { /////////////////////////////////////////////////////////////////////////////// // Defines /////////////////////////////////////////////////////////////////////////////// // Debug #if DEBUG_PATHS #define PATH_LOGD(...) LOGD(__VA_ARGS__) #else #define PATH_LOGD(...) #endif /////////////////////////////////////////////////////////////////////////////// // Classes /////////////////////////////////////////////////////////////////////////////// /** * Describe a path in the path cache. */ struct PathCacheEntry { PathCacheEntry() { path = NULL; join = SkPaint::kDefault_Join; cap = SkPaint::kDefault_Cap; style = SkPaint::kFill_Style; miter = 4.0f; strokeWidth = 1.0f; struct PathCacheEntry: public ShapeCacheEntry { PathCacheEntry(SkPath* path, SkPaint* paint): ShapeCacheEntry(ShapeCacheEntry::kShapePath, paint) { this->path = path; } PathCacheEntry(const PathCacheEntry& entry): path(entry.path), join(entry.join), cap(entry.cap), style(entry.style), miter(entry.miter), strokeWidth(entry.strokeWidth) { PathCacheEntry(): ShapeCacheEntry() { path = NULL; } PathCacheEntry(SkPath* path, SkPaint* paint) { this->path = path; join = paint->getStrokeJoin(); cap = paint->getStrokeCap(); miter = paint->getStrokeMiter(); strokeWidth = paint->getStrokeWidth(); style = paint->getStyle(); PathCacheEntry(const PathCacheEntry& entry): ShapeCacheEntry(entry) { path = entry.path; } SkPath* path; SkPaint::Join join; SkPaint::Cap cap; SkPaint::Style style; float miter; float strokeWidth; bool operator<(const PathCacheEntry& rhs) const { bool lessThan(const ShapeCacheEntry& r) const { const PathCacheEntry& rhs = (const PathCacheEntry&) r; LTE_INT(path) { LTE_INT(join) { LTE_INT(cap) { LTE_INT(style) { LTE_FLOAT(miter) { LTE_FLOAT(strokeWidth) return false; } } } } } return false; } }; // struct PathCacheEntry /** * Alpha texture used to represent a path. */ struct PathTexture: public Texture { PathTexture(): Texture() { return false; } /** * 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; }; // struct PathTexture SkPath* path; }; // PathCacheEntry /** * A simple LRU path 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. */ class PathCache: public OnEntryRemoved<PathCacheEntry, PathTexture*> { class PathCache: public ShapeCache<PathCacheEntry> { public: PathCache(); PathCache(uint32_t maxByteSize); ~PathCache(); /** * Used as a callback when an entry is removed from the cache. * Do not invoke directly. */ void operator()(PathCacheEntry& path, PathTexture*& texture); /** * Returns the texture associated with the specified path. If the texture * cannot be found in the cache, a new texture is generated. */ PathTexture* get(SkPath* path, SkPaint* paint); /** * Clears the cache. This causes all textures to be deleted. */ void clear(); /** * Removes an entry. */ Loading @@ -158,39 +85,7 @@ public: */ void clearGarbage(); /** * 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(); private: /** * Generates the texture from a bitmap into the specified texture structure. */ void generateTexture(SkBitmap& bitmap, Texture* texture); void removeTexture(PathTexture* texture); PathTexture* addTexture(const PathCacheEntry& entry, const SkPath *path, const SkPaint* paint); void init(); GenerationCache<PathCacheEntry, PathTexture*> mCache; uint32_t mSize; uint32_t mMaxSize; GLuint mMaxTextureSize; bool mDebugEnabled; Vector<SkPath*> mGarbage; mutable Mutex mLock; }; // class PathCache Loading