Merge "DisplayList optimizations and fixes."

This commit is contained in:
Chet Haase
2010-10-26 06:59:19 -07:00
committed by Android (Google) Code Review
8 changed files with 82 additions and 118 deletions

View File

@@ -32,12 +32,6 @@ class SkMatrixGlue {
public:
static void finalizer(JNIEnv* env, jobject clazz, SkMatrix* obj) {
#ifdef USE_OPENGL_RENDERER
if (android::uirenderer::Caches::hasInstance()) {
android::uirenderer::Caches::getInstance().resourceCache.destructor(obj);
return;
}
#endif // USE_OPENGL_RENDERER
delete obj;
}

View File

@@ -63,12 +63,6 @@ public:
};
static void finalizer(JNIEnv* env, jobject clazz, SkPaint* obj) {
#ifdef USE_OPENGL_RENDERER
if (android::uirenderer::Caches::hasInstance()) {
android::uirenderer::Caches::getInstance().resourceCache.destructor(obj);
return;
}
#endif // USE_OPENGL_RENDERER
delete obj;
}

View File

@@ -108,18 +108,7 @@ DisplayList::DisplayList(const DisplayListRenderer& recorder) {
mBitmapResources.add(resource);
caches.resourceCache.incrementRefcount(resource);
}
const Vector<SkMatrix*> &matrixResources = recorder.getMatrixResources();
for (size_t i = 0; i < matrixResources.size(); i++) {
SkMatrix* resource = matrixResources.itemAt(i);
mMatrixResources.add(resource);
caches.resourceCache.incrementRefcount(resource);
}
const Vector<SkPaint*> &paintResources = recorder.getPaintResources();
for (size_t i = 0; i < paintResources.size(); i++) {
SkPaint* resource = paintResources.itemAt(i);
mPaintResources.add(resource);
caches.resourceCache.incrementRefcount(resource);
}
const Vector<SkiaShader*> &shaderResources = recorder.getShaderResources();
for (size_t i = 0; i < shaderResources.size(); i++) {
SkiaShader* resource = shaderResources.itemAt(i);
@@ -127,6 +116,16 @@ DisplayList::DisplayList(const DisplayListRenderer& recorder) {
caches.resourceCache.incrementRefcount(resource);
}
const Vector<SkPaint*> &paints = recorder.getPaints();
for (size_t i = 0; i < paints.size(); i++) {
mPaints.add(paints.itemAt(i));
}
const Vector<SkMatrix*> &matrices = recorder.getMatrices();
for (size_t i = 0; i < matrices.size(); i++) {
mMatrices.add(matrices.itemAt(i));
}
mPathHeap = recorder.mPathHeap;
mPathHeap->safeRef();
}
@@ -137,25 +136,25 @@ DisplayList::~DisplayList() {
Caches& caches = Caches::getInstance();
for (size_t i = 0; i < mBitmapResources.size(); i++) {
SkBitmap* resource = mBitmapResources.itemAt(i);
caches.resourceCache.decrementRefcount(resource);
caches.resourceCache.decrementRefcount(mBitmapResources.itemAt(i));
}
mBitmapResources.clear();
for (size_t i = 0; i < mMatrixResources.size(); i++) {
SkMatrix* resource = mMatrixResources.itemAt(i);
caches.resourceCache.decrementRefcount(resource);
}
mMatrixResources.clear();
for (size_t i = 0; i < mPaintResources.size(); i++) {
SkPaint* resource = mPaintResources.itemAt(i);
caches.resourceCache.decrementRefcount(resource);
}
mPaintResources.clear();
for (size_t i = 0; i < mShaderResources.size(); i++) {
SkiaShader* resource = mShaderResources.itemAt(i);
caches.resourceCache.decrementRefcount(resource);
caches.resourceCache.decrementRefcount(mShaderResources.itemAt(i));
}
mShaderResources.clear();
for (size_t i = 0; i < mPaints.size(); i++) {
delete mPaints.itemAt(i);
}
mPaints.clear();
for (size_t i = 0; i < mMatrices.size(); i++) {
delete mMatrices.itemAt(i);
}
mMatrices.clear();
mPathHeap->safeUnref();
}
@@ -335,21 +334,16 @@ void DisplayListRenderer::reset() {
caches.resourceCache.decrementRefcount(resource);
}
mBitmapResources.clear();
for (size_t i = 0; i < mMatrixResources.size(); i++) {
SkMatrix* resource = mMatrixResources.itemAt(i);
caches.resourceCache.decrementRefcount(resource);
}
mMatrixResources.clear();
for (size_t i = 0; i < mPaintResources.size(); i++) {
SkPaint* resource = mPaintResources.itemAt(i);
caches.resourceCache.decrementRefcount(resource);
}
mPaintResources.clear();
for (size_t i = 0; i < mShaderResources.size(); i++) {
SkiaShader* resource = mShaderResources.itemAt(i);
caches.resourceCache.decrementRefcount(resource);
}
mShaderResources.clear();
mPaints.clear();
mPaintMap.clear();
mMatrices.clear();
}
///////////////////////////////////////////////////////////////////////////////

View File

@@ -182,10 +182,11 @@ private:
PathHeap* mPathHeap;
Vector<SkBitmap*> mBitmapResources;
Vector<SkMatrix*> mMatrixResources;
Vector<SkPaint*> mPaintResources;
Vector<SkiaShader*> mShaderResources;
Vector<SkPaint*> mPaints;
Vector<SkMatrix*> mMatrices;
mutable SkFlattenableReadBuffer mReader;
SkRefCntPlayback mRCPlayback;
@@ -263,18 +264,18 @@ public:
return mBitmapResources;
}
const Vector<SkMatrix*>& getMatrixResources() const {
return mMatrixResources;
}
const Vector<SkPaint*>& getPaintResources() const {
return mPaintResources;
}
const Vector<SkiaShader*>& getShaderResources() const {
return mShaderResources;
}
const Vector<SkPaint*>& getPaints() const {
return mPaints;
}
const Vector<SkMatrix*>& getMatrices() const {
return mMatrices;
}
private:
inline void addOp(DisplayList::Op drawOp) {
mWriter.writeInt(drawOp);
@@ -334,20 +335,30 @@ private:
}
inline void addPaint(SkPaint* paint) {
addInt((int)paint);
mPaintResources.add(paint);
Caches& caches = Caches::getInstance();
caches.resourceCache.incrementRefcount(paint);
if (paint == NULL) {
addInt((int)NULL);
return;
}
SkPaint *paintCopy = mPaintMap.valueFor(paint);
if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) {
paintCopy = new SkPaint(*paint);
mPaintMap.add(paint, paintCopy);
mPaints.add(paintCopy);
}
addInt((int)paintCopy);
}
inline void addMatrix(SkMatrix* matrix) {
addInt((int)matrix);
mMatrixResources.add(matrix);
Caches& caches = Caches::getInstance();
caches.resourceCache.incrementRefcount(matrix);
// Copying the matrix is cheap and prevents against the user changing the original
// matrix before the operation that uses it
addInt((int) new SkMatrix(*matrix));
}
inline void addBitmap(SkBitmap* bitmap) {
// Note that this assumes the bitmap is immutable. There are cases this won't handle
// correctly, such as creating the bitmap from scratch, drawing with it, changing its
// contents, and drawing again. The only fix would be to always copy it the first time,
// which doesn't seem worth the extra cycles for this unlikely case.
addInt((int)bitmap);
mBitmapResources.add(bitmap);
Caches& caches = Caches::getInstance();
@@ -364,10 +375,12 @@ private:
SkChunkAlloc mHeap;
Vector<SkBitmap*> mBitmapResources;
Vector<SkMatrix*> mMatrixResources;
Vector<SkPaint*> mPaintResources;
Vector<SkiaShader*> mShaderResources;
Vector<SkPaint*> mPaints;
DefaultKeyedVector<SkPaint *, SkPaint *> mPaintMap;
Vector<SkMatrix*> mMatrices;
PathHeap* mPathHeap;
SkWriter32 mWriter;

View File

@@ -62,14 +62,6 @@ void ResourceCache::incrementRefcount(SkBitmap* bitmapResource) {
incrementRefcount((void*)bitmapResource, kBitmap);
}
void ResourceCache::incrementRefcount(SkMatrix* matrixResource) {
incrementRefcount((void*)matrixResource, kMatrix);
}
void ResourceCache::incrementRefcount(SkPaint* paintResource) {
incrementRefcount((void*)paintResource, kPaint);
}
void ResourceCache::incrementRefcount(SkiaShader* shaderResource) {
shaderResource->getSkShader()->safeRef();
incrementRefcount((void*)shaderResource, kShader);
@@ -136,34 +128,6 @@ void ResourceCache::destructor(SkBitmap* resource) {
}
}
void ResourceCache::destructor(SkMatrix* resource) {
ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
if (ref == NULL) {
// If we're not tracking this resource, just delete it
delete resource;
return;
}
ref->destroyed = true;
if (ref->refCount == 0) {
deleteResourceReference(resource, ref);
return;
}
}
void ResourceCache::destructor(SkPaint* resource) {
ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
if (ref == NULL) {
// If we're not tracking this resource, just delete it
delete resource;
return;
}
ref->destroyed = true;
if (ref->refCount == 0) {
deleteResourceReference(resource, ref);
return;
}
}
void ResourceCache::destructor(SkiaShader* resource) {
ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
if (ref == NULL) {
@@ -196,12 +160,6 @@ void ResourceCache::deleteResourceReference(void* resource, ResourceReference* r
delete bitmap;
}
break;
case kMatrix:
delete (SkMatrix*) resource;
break;
case kPaint:
delete (SkPaint*) resource;
break;
case kShader:
SkiaShader* shader = (SkiaShader*)resource;
if (Caches::hasInstance()) {

View File

@@ -18,8 +18,6 @@
#define ANDROID_UI_RESOURCE_CACHE_H
#include <SkBitmap.h>
#include <SkMatrix.h>
#include <SkPaint.h>
#include <SkiaShader.h>
#include <utils/KeyedVector.h>
@@ -31,8 +29,6 @@ namespace uirenderer {
*/
enum ResourceType {
kBitmap,
kMatrix,
kPaint,
kShader,
};
@@ -56,8 +52,6 @@ public:
ResourceCache();
~ResourceCache();
void incrementRefcount(SkBitmap* resource);
void incrementRefcount(SkMatrix* resource);
void incrementRefcount(SkPaint* resource);
void incrementRefcount(SkiaShader* resource);
void incrementRefcount(const void* resource, ResourceType resourceType);
void decrementRefcount(void* resource);
@@ -66,8 +60,6 @@ public:
void recycle(void* resource);
void recycle(SkBitmap* resource);
void destructor(SkBitmap* resource);
void destructor(SkMatrix* resource);
void destructor(SkPaint* resource);
void destructor(SkiaShader* resource);
private:
void deleteResourceReference(void* resource, ResourceReference* ref);

View File

@@ -94,6 +94,8 @@ void TextureCache::operator()(SkBitmap*& bitmap, Texture*& texture) {
// This will be called already locked
if (texture) {
mSize -= texture->bitmapSize;
TEXTURE_LOGD("TextureCache::callback: removed size, mSize = %d, %d",
texture->bitmapSize, mSize);
glDeleteTextures(1, &texture->id);
delete texture;
}
@@ -131,6 +133,8 @@ Texture* TextureCache::get(SkBitmap* bitmap) {
if (size < mMaxSize) {
mLock.lock();
mSize += size;
TEXTURE_LOGD("TextureCache::get: create texture(0x%p): size, mSize = %d, %d",
bitmap, size, mSize);
mCache.put(bitmap, texture);
mLock.unlock();
} else {
@@ -151,6 +155,7 @@ void TextureCache::remove(SkBitmap* bitmap) {
void TextureCache::clear() {
Mutex::Autolock _l(mLock);
mCache.clear();
TEXTURE_LOGD("TextureCache:clear(), miSize = %d", mSize);
}
void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool regenerate) {

View File

@@ -25,6 +25,20 @@
namespace android {
namespace uirenderer {
///////////////////////////////////////////////////////////////////////////////
// Defines
///////////////////////////////////////////////////////////////////////////////
// Debug
#define DEBUG_TEXTURES 0
// Debug
#if DEBUG_TEXTURES
#define TEXTURE_LOGD(...) LOGD(__VA_ARGS__)
#else
#define TEXTURE_LOGD(...)
#endif
/**
* A simple LRU texture cache. The cache has a maximum size expressed in bytes.
* Any texture added to the cache causing the cache to grow beyond the maximum