summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorChet Haase <chet@google.com>2010-10-08 08:37:55 -0700
committerChet Haase <chet@google.com>2010-10-21 12:02:42 -0700
commit5c13d89c1332fcc499379b9064b891187b75ca32 (patch)
tree439222e6d58a765a84133345ac6ef7cb13f1c04e /libs
parenta376d030a2075909219926d622b71016418d7dcd (diff)
downloadframeworks_base-5c13d89c1332fcc499379b9064b891187b75ca32.zip
frameworks_base-5c13d89c1332fcc499379b9064b891187b75ca32.tar.gz
frameworks_base-5c13d89c1332fcc499379b9064b891187b75ca32.tar.bz2
Optimizing display lists by referencing pointers to resources instead of copying them
Change-Id: I81ad3551d74aa1e5bb64d69e33d2eb29a6c1eb6a
Diffstat (limited to 'libs')
-rw-r--r--libs/hwui/Android.mk1
-rw-r--r--libs/hwui/Caches.h2
-rw-r--r--libs/hwui/DisplayListRenderer.cpp187
-rw-r--r--libs/hwui/DisplayListRenderer.h105
-rw-r--r--libs/hwui/OpenGLDebugRenderer.cpp16
-rw-r--r--libs/hwui/OpenGLDebugRenderer.h14
-rw-r--r--libs/hwui/OpenGLRenderer.cpp18
-rw-r--r--libs/hwui/OpenGLRenderer.h18
-rw-r--r--libs/hwui/ResourceCache.cpp219
-rw-r--r--libs/hwui/ResourceCache.h81
-rw-r--r--libs/hwui/SkiaShader.h4
11 files changed, 469 insertions, 196 deletions
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 5bf0ccc..f314b09 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -20,6 +20,7 @@ ifeq ($(USE_OPENGL_RENDERER),true)
PathCache.cpp \
Program.cpp \
ProgramCache.cpp \
+ ResourceCache.cpp \
SkiaColorFilter.cpp \
SkiaShader.cpp \
TextureCache.cpp \
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index e6e494d..0c704da 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -34,6 +34,7 @@
#include "TextDropShadowCache.h"
#include "FboCache.h"
#include "Line.h"
+#include "ResourceCache.h"
namespace android {
namespace uirenderer {
@@ -138,6 +139,7 @@ public:
TextDropShadowCache dropShadowCache;
FboCache fboCache;
GammaFontRenderer fontRenderer;
+ ResourceCache resourceCache;
Line line;
}; // class Caches
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index b3517c4..a43f164 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -100,39 +100,31 @@ DisplayList::DisplayList(const DisplayListRenderer& recorder) {
mTFPlayback.reset(&recorder.mTFRecorder);
mTFPlayback.setupBuffer(mReader);
- const SkTDArray<const SkFlatBitmap*>& bitmaps = recorder.getBitmaps();
- mBitmapCount = bitmaps.count();
- if (mBitmapCount > 0) {
- mBitmaps = new SkBitmap[mBitmapCount];
- for (const SkFlatBitmap** flatBitmapPtr = bitmaps.begin();
- flatBitmapPtr != bitmaps.end(); flatBitmapPtr++) {
- const SkFlatBitmap* flatBitmap = *flatBitmapPtr;
- int index = flatBitmap->index() - 1;
- flatBitmap->unflatten(&mBitmaps[index], &mRCPlayback);
- }
- }
+ Caches& caches = Caches::getInstance();
- const SkTDArray<const SkFlatMatrix*>& matrices = recorder.getMatrices();
- mMatrixCount = matrices.count();
- if (mMatrixCount > 0) {
- mMatrices = new SkMatrix[mMatrixCount];
- for (const SkFlatMatrix** matrixPtr = matrices.begin();
- matrixPtr != matrices.end(); matrixPtr++) {
- const SkFlatMatrix* flatMatrix = *matrixPtr;
- flatMatrix->unflatten(&mMatrices[flatMatrix->index() - 1]);
- }
+ const Vector<SkBitmap*> &bitmapResources = recorder.getBitmapResources();
+ for (size_t i = 0; i < bitmapResources.size(); i++) {
+ SkBitmap* resource = bitmapResources.itemAt(i);
+ mBitmapResources.add(resource);
+ caches.resourceCache.incrementRefcount(resource);
}
-
- const SkTDArray<const SkFlatPaint*>& paints = recorder.getPaints();
- mPaintCount = paints.count();
- if (mPaintCount > 0) {
- mPaints = new SkPaint[mPaintCount];
- for (const SkFlatPaint** flatPaintPtr = paints.begin();
- flatPaintPtr != paints.end(); flatPaintPtr++) {
- const SkFlatPaint* flatPaint = *flatPaintPtr;
- int index = flatPaint->index() - 1;
- flatPaint->unflatten(&mPaints[index], &mRCPlayback, &mTFPlayback);
- }
+ 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);
+ mShaderResources.add(resource);
+ caches.resourceCache.incrementRefcount(resource);
}
mPathHeap = recorder.mPathHeap;
@@ -143,23 +135,32 @@ DisplayList::~DisplayList() {
sk_free((void*) mReader.base());
Caches& caches = Caches::getInstance();
- for (int i = 0; i < mBitmapCount; i++) {
- caches.textureCache.remove(&mBitmaps[i]);
- }
-
- delete[] mBitmaps;
- delete[] mMatrices;
- delete[] mPaints;
+ for (size_t i = 0; i < mBitmapResources.size(); i++) {
+ SkBitmap* resource = mBitmapResources.itemAt(i);
+ 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();
mPathHeap->safeUnref();
}
void DisplayList::init() {
- mBitmaps = NULL;
- mMatrices = NULL;
- mPaints = NULL;
mPathHeap = NULL;
- mBitmapCount = mMatrixCount = mPaintCount = 0;
}
void DisplayList::replay(OpenGLRenderer& renderer) {
@@ -280,7 +281,7 @@ void DisplayList::replay(OpenGLRenderer& renderer) {
}
break;
case SetupShader: {
- // TODO: Implement
+ renderer.setupShader(getShader());
}
break;
case ResetColorFilter: {
@@ -309,7 +310,6 @@ void DisplayList::replay(OpenGLRenderer& renderer) {
DisplayListRenderer::DisplayListRenderer():
mHeap(HEAP_BLOCK_SIZE), mWriter(MIN_WRITER_SIZE) {
- mBitmapIndex = mMatrixIndex = mPaintIndex = 1;
mPathHeap = NULL;
}
@@ -323,15 +323,33 @@ void DisplayListRenderer::reset() {
mPathHeap = NULL;
}
- mBitmaps.reset();
- mMatrices.reset();
- mPaints.reset();
-
mWriter.reset();
mHeap.reset();
mRCRecorder.reset();
mTFRecorder.reset();
+
+ Caches& caches = Caches::getInstance();
+ for (size_t i = 0; i < mBitmapResources.size(); i++) {
+ SkBitmap* resource = mBitmapResources.itemAt(i);
+ 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();
}
///////////////////////////////////////////////////////////////////////////////
@@ -380,7 +398,7 @@ void DisplayListRenderer::restoreToCount(int saveCount) {
}
int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom,
- const SkPaint* p, int flags) {
+ SkPaint* p, int flags) {
addOp(DisplayList::SaveLayer);
addBounds(left, top, right, bottom);
addPaint(p);
@@ -427,15 +445,15 @@ bool DisplayListRenderer::clipRect(float left, float top, float right, float bot
}
void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top,
- const SkPaint* paint) {
+ SkPaint* paint) {
addOp(DisplayList::DrawBitmap);
addBitmap(bitmap);
addPoint(left, top);
addPaint(paint);
}
-void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, const SkMatrix* matrix,
- const SkPaint* paint) {
+void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix,
+ SkPaint* paint) {
addOp(DisplayList::DrawBitmapMatrix);
addBitmap(bitmap);
addMatrix(matrix);
@@ -444,7 +462,7 @@ void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, const SkMatrix* matrix,
void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop,
- float dstRight, float dstBottom, const SkPaint* paint) {
+ float dstRight, float dstBottom, SkPaint* paint) {
addOp(DisplayList::DrawBitmapRect);
addBitmap(bitmap);
addBounds(srcLeft, srcTop, srcRight, srcBottom);
@@ -454,7 +472,7 @@ void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcT
void DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
- float left, float top, float right, float bottom, const SkPaint* paint) {
+ float left, float top, float right, float bottom, SkPaint* paint) {
addOp(DisplayList::DrawPatch);
addBitmap(bitmap);
addInts(xDivs, width);
@@ -471,7 +489,7 @@ void DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
}
void DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
- const SkPaint* paint) {
+ SkPaint* paint) {
addOp(DisplayList::DrawRect);
addBounds(left, top, right, bottom);
addPaint(paint);
@@ -483,7 +501,7 @@ void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
addPaint(paint);
}
-void DisplayListRenderer::drawLines(float* points, int count, const SkPaint* paint) {
+void DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) {
addOp(DisplayList::DrawLines);
addFloats(points, count);
addPaint(paint);
@@ -504,8 +522,8 @@ void DisplayListRenderer::resetShader() {
}
void DisplayListRenderer::setupShader(SkiaShader* shader) {
- // TODO: Implement
- OpenGLRenderer::setupShader(shader);
+ addOp(DisplayList::SetupShader);
+ addShader(shader);
}
void DisplayListRenderer::resetColorFilter() {
@@ -531,58 +549,5 @@ void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int colo
OpenGLRenderer::setupShadow(radius, dx, dy, color);
}
-///////////////////////////////////////////////////////////////////////////////
-// Recording management
-///////////////////////////////////////////////////////////////////////////////
-
-int DisplayListRenderer::find(SkTDArray<const SkFlatPaint*>& paints, const SkPaint* paint) {
- if (paint == NULL) {
- return 0;
- }
-
- SkFlatPaint* flat = SkFlatPaint::Flatten(&mHeap, *paint, mPaintIndex,
- &mRCRecorder, &mTFRecorder);
- int index = SkTSearch<SkFlatData>((const SkFlatData**) paints.begin(),
- paints.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
- if (index >= 0) {
- (void) mHeap.unalloc(flat);
- return paints[index]->index();
- }
-
- index = ~index;
- *paints.insert(index) = flat;
- return mPaintIndex++;
-}
-
-int DisplayListRenderer::find(SkTDArray<const SkFlatMatrix*>& matrices, const SkMatrix* matrix) {
- if (matrix == NULL) {
- return 0;
- }
-
- SkFlatMatrix* flat = SkFlatMatrix::Flatten(&mHeap, *matrix, mMatrixIndex);
- int index = SkTSearch<SkFlatData>((const SkFlatData**) matrices.begin(),
- matrices.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
- if (index >= 0) {
- (void) mHeap.unalloc(flat);
- return matrices[index]->index();
- }
- index = ~index;
- *matrices.insert(index) = flat;
- return mMatrixIndex++;
-}
-
-int DisplayListRenderer::find(SkTDArray<const SkFlatBitmap*>& bitmaps, const SkBitmap& bitmap) {
- SkFlatBitmap* flat = SkFlatBitmap::Flatten(&mHeap, bitmap, mBitmapIndex, &mRCRecorder);
- int index = SkTSearch<SkFlatData>((const SkFlatData**) bitmaps.begin(),
- bitmaps.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
- if (index >= 0) {
- (void) mHeap.unalloc(flat);
- return bitmaps[index]->index();
- }
- index = ~index;
- *bitmaps.insert(index) = flat;
- return mBitmapIndex++;
-}
-
}; // namespace uirenderer
}; // namespace android
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 9e6d5b1..c8cd801 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -128,8 +128,11 @@ private:
};
SkBitmap* getBitmap() {
- int index = getInt();
- return &mBitmaps[index - 1];
+ return (SkBitmap*) getInt();
+ }
+
+ SkiaShader* getShader() {
+ return (SkiaShader*) getInt();
}
inline int getIndex() {
@@ -141,11 +144,7 @@ private:
}
SkMatrix* getMatrix() {
- int index = getInt();
- if (index == 0) {
- return NULL;
- }
- return &mMatrices[index - 1];
+ return (SkMatrix*) getInt();
}
SkPath* getPath() {
@@ -153,11 +152,7 @@ private:
}
SkPaint* getPaint() {
- int index = getInt();
- if (index == 0) {
- return NULL;
- }
- return &mPaints[index - 1];
+ return (SkPaint*) getInt();
}
inline float getFloat() {
@@ -186,14 +181,10 @@ private:
PathHeap* mPathHeap;
- SkBitmap* mBitmaps;
- int mBitmapCount;
-
- SkMatrix* mMatrices;
- int mMatrixCount;
-
- SkPaint* mPaints;
- int mPaintCount;
+ Vector<SkBitmap*> mBitmapResources;
+ Vector<SkMatrix*> mMatrixResources;
+ Vector<SkPaint*> mPaintResources;
+ Vector<SkiaShader*> mShaderResources;
mutable SkFlattenableReadBuffer mReader;
@@ -224,7 +215,7 @@ public:
void restoreToCount(int saveCount);
int saveLayer(float left, float top, float right, float bottom,
- const SkPaint* p, int flags);
+ SkPaint* p, int flags);
void translate(float dx, float dy);
void rotate(float degrees);
@@ -235,18 +226,18 @@ public:
bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
- void drawBitmap(SkBitmap* bitmap, float left, float top, const SkPaint* paint);
- void drawBitmap(SkBitmap* bitmap, const SkMatrix* matrix, const SkPaint* paint);
+ void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
+ void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop,
- float dstRight, float dstBottom, const SkPaint* paint);
+ float dstRight, float dstBottom, SkPaint* paint);
void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
- float left, float top, float right, float bottom, const SkPaint* paint);
+ float left, float top, float right, float bottom, SkPaint* paint);
void drawColor(int color, SkXfermode::Mode mode);
- void drawRect(float left, float top, float right, float bottom, const SkPaint* paint);
+ void drawRect(float left, float top, float right, float bottom, SkPaint* paint);
void drawPath(SkPath* path, SkPaint* paint);
- void drawLines(float* points, int count, const SkPaint* paint);
+ void drawLines(float* points, int count, SkPaint* paint);
void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint);
void resetShader();
@@ -268,16 +259,20 @@ public:
return mWriter;
}
- const SkTDArray<const SkFlatBitmap*>& getBitmaps() const {
- return mBitmaps;
+ const Vector<SkBitmap*>& getBitmapResources() const {
+ return mBitmapResources;
}
- const SkTDArray<const SkFlatMatrix*>& getMatrices() const {
- return mMatrices;
+ const Vector<SkMatrix*>& getMatrixResources() const {
+ return mMatrixResources;
}
- const SkTDArray<const SkFlatPaint*>& getPaints() const {
- return mPaints;
+ const Vector<SkPaint*>& getPaintResources() const {
+ return mPaintResources;
+ }
+
+ const Vector<SkiaShader*>& getShaderResources() const {
+ return mShaderResources;
}
private:
@@ -338,34 +333,40 @@ private:
addInt(mPathHeap->append(*path));
}
- int find(SkTDArray<const SkFlatPaint*>& paints, const SkPaint* paint);
-
- inline void addPaint(const SkPaint* paint) {
- addInt(find(mPaints, paint));
+ inline void addPaint(SkPaint* paint) {
+ addInt((int)paint);
+ mPaintResources.add(paint);
+ Caches& caches = Caches::getInstance();
+ caches.resourceCache.incrementRefcount(paint);
}
- int find(SkTDArray<const SkFlatMatrix*>& matrices, const SkMatrix* matrix);
-
- inline void addMatrix(const SkMatrix* matrix) {
- addInt(find(mMatrices, matrix));
+ inline void addMatrix(SkMatrix* matrix) {
+ addInt((int)matrix);
+ mMatrixResources.add(matrix);
+ Caches& caches = Caches::getInstance();
+ caches.resourceCache.incrementRefcount(matrix);
}
- int find(SkTDArray<const SkFlatBitmap*>& bitmaps, const SkBitmap& bitmap);
+ inline void addBitmap(SkBitmap* bitmap) {
+ addInt((int)bitmap);
+ mBitmapResources.add(bitmap);
+ Caches& caches = Caches::getInstance();
+ caches.resourceCache.incrementRefcount(bitmap);
+ }
- inline void addBitmap(const SkBitmap* bitmap) {
- addInt(find(mBitmaps, *bitmap));
+ inline void addShader(SkiaShader* shader) {
+ addInt((int)shader);
+ mShaderResources.add(shader);
+ Caches& caches = Caches::getInstance();
+ caches.resourceCache.incrementRefcount(shader);
}
SkChunkAlloc mHeap;
- int mBitmapIndex;
- SkTDArray<const SkFlatBitmap*> mBitmaps;
-
- int mMatrixIndex;
- SkTDArray<const SkFlatMatrix*> mMatrices;
-
- int mPaintIndex;
- SkTDArray<const SkFlatPaint*> mPaints;
+ Vector<SkBitmap*> mBitmapResources;
+ Vector<SkMatrix*> mMatrixResources;
+ Vector<SkPaint*> mPaintResources;
+ Vector<SkiaShader*> mShaderResources;
PathHeap* mPathHeap;
SkWriter32 mWriter;
diff --git a/libs/hwui/OpenGLDebugRenderer.cpp b/libs/hwui/OpenGLDebugRenderer.cpp
index d492e23..fe75ca2 100644
--- a/libs/hwui/OpenGLDebugRenderer.cpp
+++ b/libs/hwui/OpenGLDebugRenderer.cpp
@@ -42,21 +42,21 @@ void OpenGLDebugRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previo
}
int OpenGLDebugRenderer::saveLayer(float left, float top, float right, float bottom,
- const SkPaint* p, int flags) {
+ SkPaint* p, int flags) {
mPrimitivesCount++;
StopWatch w("saveLayer");
return OpenGLRenderer::saveLayer(left, top, right, bottom, p, flags);
}
void OpenGLDebugRenderer::drawBitmap(SkBitmap* bitmap, float left, float top,
- const SkPaint* paint) {
+ SkPaint* paint) {
mPrimitivesCount++;
StopWatch w("drawBitmap");
OpenGLRenderer::drawBitmap(bitmap, left, top, paint);
}
-void OpenGLDebugRenderer::drawBitmap(SkBitmap* bitmap, const SkMatrix* matrix,
- const SkPaint* paint) {
+void OpenGLDebugRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix,
+ SkPaint* paint) {
mPrimitivesCount++;
StopWatch w("drawBitmapMatrix");
OpenGLRenderer::drawBitmap(bitmap, matrix, paint);
@@ -64,7 +64,7 @@ void OpenGLDebugRenderer::drawBitmap(SkBitmap* bitmap, const SkMatrix* matrix,
void OpenGLDebugRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop,
- float dstRight, float dstBottom, const SkPaint* paint) {
+ float dstRight, float dstBottom, SkPaint* paint) {
mPrimitivesCount++;
StopWatch w("drawBitmapRect");
OpenGLRenderer::drawBitmap(bitmap, srcLeft, srcTop, srcRight, srcBottom,
@@ -73,7 +73,7 @@ void OpenGLDebugRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcT
void OpenGLDebugRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
- float left, float top, float right, float bottom, const SkPaint* paint) {
+ float left, float top, float right, float bottom, SkPaint* paint) {
mPrimitivesCount++;
StopWatch w("drawPatch");
OpenGLRenderer::drawPatch(bitmap, xDivs, yDivs, colors, width, height, numColors,
@@ -87,7 +87,7 @@ void OpenGLDebugRenderer::drawColor(int color, SkXfermode::Mode mode) {
}
void OpenGLDebugRenderer::drawRect(float left, float top, float right, float bottom,
- const SkPaint* paint) {
+ SkPaint* paint) {
mPrimitivesCount++;
StopWatch w("drawRect");
OpenGLRenderer::drawRect(left, top, right, bottom, paint);
@@ -99,7 +99,7 @@ void OpenGLDebugRenderer::drawPath(SkPath* path, SkPaint* paint) {
OpenGLRenderer::drawPath(path, paint);
}
-void OpenGLDebugRenderer::drawLines(float* points, int count, const SkPaint* paint) {
+void OpenGLDebugRenderer::drawLines(float* points, int count, SkPaint* paint) {
mPrimitivesCount++;
StopWatch w("drawLines");
OpenGLRenderer::drawLines(points, count, paint);
diff --git a/libs/hwui/OpenGLDebugRenderer.h b/libs/hwui/OpenGLDebugRenderer.h
index 4997ef3..ce6a4aa 100644
--- a/libs/hwui/OpenGLDebugRenderer.h
+++ b/libs/hwui/OpenGLDebugRenderer.h
@@ -38,20 +38,20 @@ public:
void finish();
int saveLayer(float left, float top, float right, float bottom,
- const SkPaint* p, int flags);
+ SkPaint* p, int flags);
- void drawBitmap(SkBitmap* bitmap, float left, float top, const SkPaint* paint);
- void drawBitmap(SkBitmap* bitmap, const SkMatrix* matrix, const SkPaint* paint);
+ void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
+ void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop,
- float dstRight, float dstBottom, const SkPaint* paint);
+ float dstRight, float dstBottom, SkPaint* paint);
void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
- float left, float top, float right, float bottom, const SkPaint* paint);
+ float left, float top, float right, float bottom, SkPaint* paint);
void drawColor(int color, SkXfermode::Mode mode);
- void drawRect(float left, float top, float right, float bottom, const SkPaint* paint);
+ void drawRect(float left, float top, float right, float bottom, SkPaint* paint);
void drawPath(SkPath* path, SkPaint* paint);
- void drawLines(float* points, int count, const SkPaint* paint);
+ void drawLines(float* points, int count, SkPaint* paint);
void drawText(const char* text, int bytesCount, int count, float x, float y,
SkPaint* paint);
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 633d778..17ef598 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -252,7 +252,7 @@ bool OpenGLRenderer::restoreSnapshot() {
///////////////////////////////////////////////////////////////////////////////
int OpenGLRenderer::saveLayer(float left, float top, float right, float bottom,
- const SkPaint* p, int flags) {
+ SkPaint* p, int flags) {
const GLuint previousFbo = mSnapshot->fbo;
const int count = saveSnapshot(flags);
@@ -623,7 +623,7 @@ bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom,
// Drawing
///////////////////////////////////////////////////////////////////////////////
-void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, const SkPaint* paint) {
+void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
const float right = left + bitmap->width();
const float bottom = top + bitmap->height();
@@ -639,7 +639,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, const S
drawTextureRect(left, top, right, bottom, texture, paint);
}
-void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, const SkMatrix* matrix, const SkPaint* paint) {
+void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) {
Rect r(0.0f, 0.0f, bitmap->width(), bitmap->height());
const mat4 transform(*matrix);
transform.mapRect(r);
@@ -659,7 +659,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, const SkMatrix* matrix, const
void OpenGLRenderer::drawBitmap(SkBitmap* bitmap,
float srcLeft, float srcTop, float srcRight, float srcBottom,
float dstLeft, float dstTop, float dstRight, float dstBottom,
- const SkPaint* paint) {
+ SkPaint* paint) {
if (quickReject(dstLeft, dstTop, dstRight, dstBottom)) {
return;
}
@@ -693,7 +693,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap,
void OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
- float left, float top, float right, float bottom, const SkPaint* paint) {
+ float left, float top, float right, float bottom, SkPaint* paint) {
if (quickReject(left, top, right, bottom)) {
return;
}
@@ -719,7 +719,7 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int
}
}
-void OpenGLRenderer::drawLines(float* points, int count, const SkPaint* paint) {
+void OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) {
if (mSnapshot->invisible) return;
int alpha;
@@ -791,7 +791,7 @@ void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color, mode, true);
}
-void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, const SkPaint* p) {
+void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, SkPaint* p) {
if (quickReject(left, top, right, bottom)) {
return;
}
@@ -1206,7 +1206,7 @@ void OpenGLRenderer::setupColorRect(float left, float top, float right, float bo
}
void OpenGLRenderer::drawTextureRect(float left, float top, float right, float bottom,
- const Texture* texture, const SkPaint* paint) {
+ const Texture* texture, SkPaint* paint) {
int alpha;
SkXfermode::Mode mode;
getAlphaAndMode(paint, &alpha, &mode);
@@ -1334,7 +1334,7 @@ void OpenGLRenderer::resetDrawTextureTexCoords(float u1, float v1, float u2, flo
TextureVertex::setUV(v++, u2, v2);
}
-void OpenGLRenderer::getAlphaAndMode(const SkPaint* paint, int* alpha, SkXfermode::Mode* mode) {
+void OpenGLRenderer::getAlphaAndMode(SkPaint* paint, int* alpha, SkXfermode::Mode* mode) {
if (paint) {
if (!mExtensions.hasFramebufferFetch()) {
const bool isMode = SkXfermode::IsMode(paint->getXfermode(), mode);
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 1d8a3d9..b7615fe 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -79,7 +79,7 @@ public:
virtual void restoreToCount(int saveCount);
virtual int saveLayer(float left, float top, float right, float bottom,
- const SkPaint* p, int flags);
+ SkPaint* p, int flags);
virtual int saveLayerAlpha(float left, float top, float right, float bottom,
int alpha, int flags);
@@ -96,18 +96,18 @@ public:
bool quickReject(float left, float top, float right, float bottom);
virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
- virtual void drawBitmap(SkBitmap* bitmap, float left, float top, const SkPaint* paint);
- virtual void drawBitmap(SkBitmap* bitmap, const SkMatrix* matrix, const SkPaint* paint);
+ virtual void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
+ virtual void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
virtual void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop,
- float dstRight, float dstBottom, const SkPaint* paint);
+ float dstRight, float dstBottom, SkPaint* paint);
virtual void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
- float left, float top, float right, float bottom, const SkPaint* paint);
+ float left, float top, float right, float bottom, SkPaint* paint);
virtual void drawColor(int color, SkXfermode::Mode mode);
- virtual void drawRect(float left, float top, float right, float bottom, const SkPaint* paint);
+ virtual void drawRect(float left, float top, float right, float bottom, SkPaint* paint);
virtual void drawPath(SkPath* path, SkPaint* paint);
- virtual void drawLines(float* points, int count, const SkPaint* paint);
+ virtual void drawLines(float* points, int count, SkPaint* paint);
virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
SkPaint* paint);
@@ -231,7 +231,7 @@ private:
* @param paint The paint containing the alpha, blending mode, etc.
*/
void drawTextureRect(float left, float top, float right, float bottom,
- const Texture* texture, const SkPaint* paint);
+ const Texture* texture, SkPaint* paint);
/**
* Draws a textured mesh with the specified texture. If the indices are omitted,
@@ -357,7 +357,7 @@ private:
* @param alpha Where to store the resulting alpha
* @param mode Where to store the resulting xfermode
*/
- inline void getAlphaAndMode(const SkPaint* paint, int* alpha, SkXfermode::Mode* mode);
+ inline void getAlphaAndMode(SkPaint* paint, int* alpha, SkXfermode::Mode* mode);
/**
* Binds the specified texture with the specified wrap modes.
diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp
new file mode 100644
index 0000000..20b8d6c
--- /dev/null
+++ b/libs/hwui/ResourceCache.cpp
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#include <SkPixelRef.h>
+#include "ResourceCache.h"
+#include "Caches.h"
+
+namespace android {
+namespace uirenderer {
+
+///////////////////////////////////////////////////////////////////////////////
+// Resource cache
+///////////////////////////////////////////////////////////////////////////////
+
+void ResourceCache::logCache() {
+ LOGD("ResourceCache: cacheReport:");
+ for (size_t i = 0; i < mCache->size(); ++i) {
+ ResourceReference* ref = mCache->valueAt(i);
+ LOGD(" ResourceCache: mCache(%d): resource, ref = 0x%p, 0x%p",
+ i, mCache->keyAt(i), mCache->valueAt(i));
+ LOGD(" ResourceCache: mCache(%d): refCount, recycled, destroyed, type = %d, %d, %d, %d",
+ i, ref->refCount, ref->recycled, ref->destroyed, ref->resourceType);
+ }
+}
+
+ResourceCache::ResourceCache() {
+ mCache = new KeyedVector<void *, ResourceReference *>();
+}
+
+ResourceCache::~ResourceCache() {
+ delete mCache;
+}
+
+void ResourceCache::incrementRefcount(void* resource, ResourceType resourceType) {
+ for (size_t i = 0; i < mCache->size(); ++i) {
+ void* ref = mCache->valueAt(i);
+ }
+ ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
+ if (ref == NULL || mCache->size() == 0) {
+ ref = new ResourceReference(resourceType);
+ mCache->add(resource, ref);
+ }
+ ref->refCount++;
+}
+
+void ResourceCache::incrementRefcount(SkBitmap* bitmapResource) {
+ bitmapResource->pixelRef()->safeRef();
+ bitmapResource->getColorTable()->safeRef();
+ 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);
+}
+
+void ResourceCache::decrementRefcount(void* resource) {
+ ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
+ if (ref == NULL) {
+ // Should not get here - shouldn't get a call to decrement if we're not yet tracking it
+ return;
+ }
+ ref->refCount--;
+ if (ref->refCount == 0) {
+ deleteResourceReference(resource, ref);
+ }
+}
+
+void ResourceCache::decrementRefcount(SkBitmap* bitmapResource) {
+ bitmapResource->pixelRef()->safeUnref();
+ bitmapResource->getColorTable()->safeUnref();
+ decrementRefcount((void*)bitmapResource);
+}
+
+void ResourceCache::decrementRefcount(SkiaShader* shaderResource) {
+ shaderResource->getSkShader()->safeUnref();
+ decrementRefcount((void*)shaderResource);
+}
+
+void ResourceCache::recycle(SkBitmap* resource) {
+ if (mCache->indexOfKey(resource) < 0) {
+ // not tracking this resource; just recycle the pixel data
+ resource->setPixels(NULL, NULL);
+ return;
+ }
+ recycle((void*) resource);
+}
+
+void ResourceCache::recycle(void* resource) {
+ ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
+ if (ref == NULL) {
+ // Should not get here - shouldn't get a call to recycle if we're not yet tracking it
+ return;
+ }
+ ref->recycled = true;
+ if (ref->refCount == 0) {
+ deleteResourceReference(resource, ref);
+ }
+}
+
+void ResourceCache::destructor(SkBitmap* resource) {
+ ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
+ if (ref == NULL) {
+ // If we're not tracking this resource, just delete it
+ if (Caches::hasInstance()) {
+ Caches::getInstance().textureCache.remove(resource);
+ }
+ delete resource;
+ return;
+ }
+ ref->destroyed = true;
+ if (ref->refCount == 0) {
+ deleteResourceReference(resource, ref);
+ return;
+ }
+}
+
+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) {
+ // If we're not tracking this resource, just delete it
+ if (Caches::hasInstance()) {
+ Caches::getInstance().gradientCache.remove(resource->getSkShader());
+ }
+ delete resource;
+ return;
+ }
+ ref->destroyed = true;
+ if (ref->refCount == 0) {
+ deleteResourceReference(resource, ref);
+ return;
+ }
+}
+
+void ResourceCache::deleteResourceReference(void* resource, ResourceReference* ref) {
+ if (ref->recycled && ref->resourceType == kBitmap) {
+ ((SkBitmap*) resource)->setPixels(NULL, NULL);
+ }
+ if (ref->destroyed) {
+ switch (ref->resourceType) {
+ case kBitmap:
+ {
+ SkBitmap* bitmap = (SkBitmap*)resource;
+ if (Caches::hasInstance()) {
+ Caches::getInstance().textureCache.remove(bitmap);
+ }
+ delete bitmap;
+ }
+ break;
+ case kMatrix:
+ delete (SkMatrix*) resource;
+ break;
+ case kPaint:
+ delete (SkPaint*) resource;
+ break;
+ case kShader:
+ SkiaShader* shader = (SkiaShader*)resource;
+ if (Caches::hasInstance()) {
+ Caches::getInstance().gradientCache.remove(shader->getSkShader());
+ }
+ delete shader;
+ break;
+ }
+ }
+ mCache->removeItem(resource);
+ delete ref;
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/ResourceCache.h b/libs/hwui/ResourceCache.h
new file mode 100644
index 0000000..cda2718
--- /dev/null
+++ b/libs/hwui/ResourceCache.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2010 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_UI_RESOURCE_CACHE_H
+#define ANDROID_UI_RESOURCE_CACHE_H
+
+#include <SkBitmap.h>
+#include <SkMatrix.h>
+#include <SkPaint.h>
+#include <SkiaShader.h>
+#include <utils/KeyedVector.h>
+
+namespace android {
+namespace uirenderer {
+
+/**
+ * Type of Resource being cached
+ */
+enum ResourceType {
+ kBitmap,
+ kMatrix,
+ kPaint,
+ kShader,
+};
+
+class ResourceReference {
+public:
+
+ ResourceReference() { refCount = 0; recycled = false; destroyed = false;}
+ ResourceReference(ResourceType type) {
+ refCount = 0; recycled = false; destroyed = false; resourceType = type;
+ }
+
+ int refCount;
+ bool recycled;
+ bool destroyed;
+ ResourceType resourceType;
+};
+
+class ResourceCache {
+ KeyedVector<void *, ResourceReference *>* mCache;
+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);
+ void decrementRefcount(SkBitmap* resource);
+ void decrementRefcount(SkiaShader* resource);
+ 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);
+ void incrementRefcount(void* resource, ResourceType resourceType);
+ void logCache();
+};
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_UI_RESOURCE_CACHE_H
diff --git a/libs/hwui/SkiaShader.h b/libs/hwui/SkiaShader.h
index 2565e65..011991a 100644
--- a/libs/hwui/SkiaShader.h
+++ b/libs/hwui/SkiaShader.h
@@ -60,6 +60,10 @@ struct SkiaShader {
virtual void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
GLuint* textureUnit);
+ inline SkShader *getSkShader() {
+ return mKey;
+ }
+
inline bool blend() const {
return mBlend;
}