summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/ViewRoot.java14
-rw-r--r--libs/hwui/Caches.h2
-rw-r--r--libs/hwui/Debug.h3
-rw-r--r--libs/hwui/PathCache.cpp185
-rw-r--r--libs/hwui/PathCache.h139
-rw-r--r--libs/hwui/ShapeCache.cpp14
-rw-r--r--libs/hwui/ShapeCache.h88
7 files changed, 98 insertions, 347 deletions
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 1f15628..97983ba 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -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) {
- // 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");
- 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) {
+ // 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");
+ return;
+ }
+
final boolean translucent = attrs.format != PixelFormat.OPAQUE;
if (mAttachInfo.mHardwareRenderer != null) {
mAttachInfo.mHardwareRenderer.destroy(true);
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index c03c347..aa0ceb7 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -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"
diff --git a/libs/hwui/Debug.h b/libs/hwui/Debug.h
index 014519e..6236684 100644
--- a/libs/hwui/Debug.h
+++ b/libs/hwui/Debug.h
@@ -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
diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp
index 3184598..28c302e 100644
--- a/libs/hwui/PathCache.cpp
+++ b/libs/hwui/PathCache.cpp
@@ -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"
@@ -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) {
@@ -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
diff --git a/libs/hwui/PathCache.h b/libs/hwui/PathCache.h
index ae2e55d..dc67e16 100644
--- a/libs/hwui/PathCache.h
+++ b/libs/hwui/PathCache.h
@@ -17,123 +17,54 @@
#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;
}
return false;
}
-}; // struct PathCacheEntry
-
-/**
- * Alpha texture used to represent a path.
- */
-struct PathTexture: public Texture {
- PathTexture(): Texture() {
- }
- /**
- * 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
@@ -141,10 +72,6 @@ public:
*/
PathTexture* get(SkPath* path, SkPaint* paint);
/**
- * Clears the cache. This causes all textures to be deleted.
- */
- void clear();
- /**
* Removes an entry.
*/
void remove(SkPath* path);
@@ -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
diff --git a/libs/hwui/ShapeCache.cpp b/libs/hwui/ShapeCache.cpp
index ffa18e3..b78eecb 100644
--- a/libs/hwui/ShapeCache.cpp
+++ b/libs/hwui/ShapeCache.cpp
@@ -21,7 +21,12 @@
namespace android {
namespace uirenderer {
-RoundRectShapeCache::RoundRectShapeCache(): ShapeCache<RoundRectShapeCacheEntry>() {
+///////////////////////////////////////////////////////////////////////////////
+// Rounded rects
+///////////////////////////////////////////////////////////////////////////////
+
+RoundRectShapeCache::RoundRectShapeCache(): ShapeCache<RoundRectShapeCacheEntry>(
+ "round rect", PROPERTY_SHAPE_CACHE_SIZE, DEFAULT_SHAPE_CACHE_SIZE) {
}
PathTexture* RoundRectShapeCache::getRoundRect(float width, float height,
@@ -41,7 +46,12 @@ PathTexture* RoundRectShapeCache::getRoundRect(float width, float height,
return texture;
}
-CircleShapeCache::CircleShapeCache(): ShapeCache<CircleShapeCacheEntry>() {
+///////////////////////////////////////////////////////////////////////////////
+// Circles
+///////////////////////////////////////////////////////////////////////////////
+
+CircleShapeCache::CircleShapeCache(): ShapeCache<CircleShapeCacheEntry>(
+ "circle", PROPERTY_SHAPE_CACHE_SIZE, DEFAULT_SHAPE_CACHE_SIZE) {
}
PathTexture* CircleShapeCache::getCircle(float radius, SkPaint* paint) {
diff --git a/libs/hwui/ShapeCache.h b/libs/hwui/ShapeCache.h
index 910d01d..c8bcfc2 100644
--- a/libs/hwui/ShapeCache.h
+++ b/libs/hwui/ShapeCache.h
@@ -19,11 +19,17 @@
#include <GLES2/gl2.h>
+#include <SkBitmap.h>
#include <SkCanvas.h>
+#include <SkPaint.h>
+#include <SkPath.h>
#include <SkRect.h>
-#include "PathCache.h"
+#include "Debug.h"
#include "Properties.h"
+#include "Texture.h"
+#include "utils/Compare.h"
+#include "utils/GenerationCache.h"
namespace android {
namespace uirenderer {
@@ -44,6 +50,27 @@ namespace uirenderer {
///////////////////////////////////////////////////////////////////////////////
/**
+ * Alpha texture used to represent a path.
+ */
+struct PathTexture: public Texture {
+ PathTexture(): Texture() {
+ }
+
+ /**
+ * 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
+
+/**
* Describe a shape in the shape cache.
*/
struct ShapeCacheEntry {
@@ -52,7 +79,8 @@ struct ShapeCacheEntry {
kShapeRoundRect,
kShapeCircle,
kShapeOval,
- kShapeArc
+ kShapeArc,
+ kShapePath
};
ShapeCacheEntry() {
@@ -196,8 +224,7 @@ private:
template<typename Entry>
class ShapeCache: public OnEntryRemoved<Entry, PathTexture*> {
public:
- ShapeCache();
- ShapeCache(uint32_t maxByteSize);
+ ShapeCache(const char* name, const char* propertyName, float defaultSize);
~ShapeCache();
/**
@@ -231,22 +258,23 @@ protected:
return mCache.get(entry);
}
-private:
- /**
- * Generates the texture from a bitmap into the specified texture structure.
- */
- void generateTexture(SkBitmap& bitmap, Texture* texture);
-
void removeTexture(PathTexture* texture);
- void init();
-
GenerationCache<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> {
@@ -269,29 +297,29 @@ public:
///////////////////////////////////////////////////////////////////////////////
template<class Entry>
-ShapeCache<Entry>::ShapeCache():
+ShapeCache<Entry>::ShapeCache(const char* name, const char* propertyName, float defaultSize):
mCache(GenerationCache<ShapeCacheEntry, PathTexture*>::kUnlimitedCapacity),
- mSize(0), mMaxSize(MB(DEFAULT_SHAPE_CACHE_SIZE)) {
+ mSize(0), mMaxSize(MB(defaultSize)) {
char property[PROPERTY_VALUE_MAX];
- if (property_get(PROPERTY_SHAPE_CACHE_SIZE, property, NULL) > 0) {
- LOGD(" Setting shape cache size to %sMB", property);
+ if (property_get(propertyName, property, NULL) > 0) {
+ LOGD(" Setting %s cache size to %sMB", name, property);
setMaxSize(MB(atof(property)));
} else {
- LOGD(" Using default shape cache size of %.2fMB", DEFAULT_SHAPE_CACHE_SIZE);
+ LOGD(" Using default %s cache size of %.2fMB", name, defaultSize);
}
- init();
-}
-template<class Entry>
-ShapeCache<Entry>::ShapeCache(uint32_t maxByteSize):
- mCache(GenerationCache<ShapeCacheEntry, PathTexture*>::kUnlimitedCapacity),
- mSize(0), mMaxSize(maxByteSize) {
+ 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>
@@ -346,10 +374,10 @@ void ShapeCache<Entry>::removeTexture(PathTexture* texture) {
const uint32_t size = texture->width * texture->height;
mSize -= size;
- SHAPE_LOGD("ShapeCache::callback: delete path: name, size, mSize = %d, %d, %d",
- texture->id, size, mSize);
+ SHAPE_LOGD("ShapeCache::callback: delete %s: name, size, mSize = %d, %d, %d",
+ mName, texture->id, size, mSize);
if (mDebugEnabled) {
- LOGD("Path deleted, size = %d", size);
+ LOGD("Shape %s deleted, size = %d", mName, size);
}
glDeleteTextures(1, &texture->id);
@@ -366,7 +394,7 @@ PathTexture* ShapeCache<Entry>::addTexture(const Entry& entry, const SkPath *pat
const float pathHeight = fmax(bounds.height(), 1.0f);
if (pathWidth > mMaxTextureSize || pathHeight > mMaxTextureSize) {
- LOGW("Shape too large to be rendered into a texture");
+ LOGW("Shape %s too large to be rendered into a texture", mName);
return NULL;
}
@@ -415,10 +443,10 @@ PathTexture* ShapeCache<Entry>::addTexture(const Entry& entry, const SkPath *pat
if (size < mMaxSize) {
mSize += size;
- SHAPE_LOGD("ShapeCache::get: create path: name, size, mSize = %d, %d, %d",
- texture->id, size, mSize);
+ SHAPE_LOGD("ShapeCache::get: create %s: name, size, mSize = %d, %d, %d",
+ mName, texture->id, size, mSize);
if (mDebugEnabled) {
- LOGD("Shape created, size = %d", size);
+ LOGD("Shape %s created, size = %d", mName, size);
}
mCache.put(entry, texture);
} else {