Merge "Fixes cache misses and extra allocations. Bug #3421454" into honeycomb

This commit is contained in:
Romain Guy
2011-02-03 16:31:41 -08:00
committed by Android (Google) Code Review
6 changed files with 60 additions and 152 deletions

View File

@@ -104,7 +104,7 @@ public class Canvas {
public Canvas() { public Canvas() {
// 0 means no native bitmap // 0 means no native bitmap
mNativeCanvas = initRaster(0); mNativeCanvas = initRaster(0);
mFinalizer = new CanvasFinalizer(0); mFinalizer = new CanvasFinalizer(mNativeCanvas);
} }
/** /**

View File

@@ -76,8 +76,14 @@ void Caches::dumpMemoryUsage() {
LOGD(" PathCache %8d / %8d", pathCache.getSize(), pathCache.getMaxSize()); LOGD(" PathCache %8d / %8d", pathCache.getSize(), pathCache.getMaxSize());
LOGD(" CircleShapeCache %8d / %8d", LOGD(" CircleShapeCache %8d / %8d",
circleShapeCache.getSize(), circleShapeCache.getMaxSize()); circleShapeCache.getSize(), circleShapeCache.getMaxSize());
LOGD(" OvalShapeCache %8d / %8d",
ovalShapeCache.getSize(), ovalShapeCache.getMaxSize());
LOGD(" RoundRectShapeCache %8d / %8d", LOGD(" RoundRectShapeCache %8d / %8d",
roundRectShapeCache.getSize(), roundRectShapeCache.getMaxSize()); roundRectShapeCache.getSize(), roundRectShapeCache.getMaxSize());
LOGD(" RectShapeCache %8d / %8d",
rectShapeCache.getSize(), rectShapeCache.getMaxSize());
LOGD(" ArcShapeCache %8d / %8d",
arcShapeCache.getSize(), arcShapeCache.getMaxSize());
LOGD(" TextDropShadowCache %8d / %8d", dropShadowCache.getSize(), LOGD(" TextDropShadowCache %8d / %8d", dropShadowCache.getSize(),
dropShadowCache.getMaxSize()); dropShadowCache.getMaxSize());
for (uint32_t i = 0; i < fontRenderer.getFontRendererCount(); i++) { for (uint32_t i = 0; i < fontRenderer.getFontRendererCount(); i++) {
@@ -94,6 +100,11 @@ void Caches::dumpMemoryUsage() {
total += gradientCache.getSize(); total += gradientCache.getSize();
total += pathCache.getSize(); total += pathCache.getSize();
total += dropShadowCache.getSize(); total += dropShadowCache.getSize();
total += roundRectShapeCache.getSize();
total += circleShapeCache.getSize();
total += ovalShapeCache.getSize();
total += rectShapeCache.getSize();
total += arcShapeCache.getSize();
for (uint32_t i = 0; i < fontRenderer.getFontRendererCount(); i++) { for (uint32_t i = 0; i < fontRenderer.getFontRendererCount(); i++) {
total += fontRenderer.getFontRendererSize(i); total += fontRenderer.getFontRendererSize(i);
} }

View File

@@ -21,62 +21,6 @@
namespace android { namespace android {
namespace uirenderer { namespace uirenderer {
///////////////////////////////////////////////////////////////////////////////
// Defines
///////////////////////////////////////////////////////////////////////////////
#define PATH_HEAP_SIZE 64
///////////////////////////////////////////////////////////////////////////////
// Helpers
///////////////////////////////////////////////////////////////////////////////
PathHeap::PathHeap(): mHeap(PATH_HEAP_SIZE * sizeof(SkPath)) {
}
PathHeap::PathHeap(SkFlattenableReadBuffer& buffer): mHeap(PATH_HEAP_SIZE * sizeof(SkPath)) {
int count = buffer.readS32();
mPaths.setCount(count);
SkPath** ptr = mPaths.begin();
SkPath* p = (SkPath*) mHeap.allocThrow(count * sizeof(SkPath));
for (int i = 0; i < count; i++) {
new (p) SkPath;
p->unflatten(buffer);
*ptr++ = p;
p++;
}
}
PathHeap::~PathHeap() {
SkPath** iter = mPaths.begin();
SkPath** stop = mPaths.end();
while (iter < stop) {
(*iter)->~SkPath();
iter++;
}
}
int PathHeap::append(const SkPath& path) {
SkPath* p = (SkPath*) mHeap.allocThrow(sizeof(SkPath));
new (p) SkPath(path);
*mPaths.append() = p;
return mPaths.count();
}
void PathHeap::flatten(SkFlattenableWriteBuffer& buffer) const {
int count = mPaths.count();
buffer.write32(count);
SkPath** iter = mPaths.begin();
SkPath** stop = mPaths.end();
while (iter < stop) {
(*iter)->flatten(buffer);
iter++;
}
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Display list // Display list
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@@ -143,17 +87,15 @@ DisplayList::~DisplayList() {
} }
mPaints.clear(); mPaints.clear();
for (size_t i = 0; i < mPaths.size(); i++) {
delete mPaths.itemAt(i);
}
mPaths.clear();
for (size_t i = 0; i < mMatrices.size(); i++) { for (size_t i = 0; i < mMatrices.size(); i++) {
delete mMatrices.itemAt(i); delete mMatrices.itemAt(i);
} }
mMatrices.clear(); mMatrices.clear();
if (mPathHeap) {
for (int i = 0; i < mPathHeap->count(); i++) {
caches.pathCache.removeDeferred(&(*mPathHeap)[i]);
}
mPathHeap->safeUnref();
}
} }
void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorder) { void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorder) {
@@ -169,12 +111,6 @@ void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorde
writer.flatten(buffer); writer.flatten(buffer);
mReader.setMemory(buffer, size); mReader.setMemory(buffer, size);
mRCPlayback.reset(&recorder.mRCRecorder);
mRCPlayback.setupBuffer(mReader);
mTFPlayback.reset(&recorder.mTFRecorder);
mTFPlayback.setupBuffer(mReader);
Caches& caches = Caches::getInstance(); Caches& caches = Caches::getInstance();
const Vector<SkBitmap*> &bitmapResources = recorder.getBitmapResources(); const Vector<SkBitmap*> &bitmapResources = recorder.getBitmapResources();
@@ -196,19 +132,18 @@ void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorde
mPaints.add(paints.itemAt(i)); mPaints.add(paints.itemAt(i));
} }
const Vector<SkPath*> &paths = recorder.getPaths();
for (size_t i = 0; i < paths.size(); i++) {
mPaths.add(paths.itemAt(i));
}
const Vector<SkMatrix*> &matrices = recorder.getMatrices(); const Vector<SkMatrix*> &matrices = recorder.getMatrices();
for (size_t i = 0; i < matrices.size(); i++) { for (size_t i = 0; i < matrices.size(); i++) {
mMatrices.add(matrices.itemAt(i)); mMatrices.add(matrices.itemAt(i));
} }
mPathHeap = recorder.mPathHeap;
if (mPathHeap) {
mPathHeap->safeRef();
}
} }
void DisplayList::init() { void DisplayList::init() {
mPathHeap = NULL;
} }
bool DisplayList::replay(OpenGLRenderer& renderer, uint32_t level) { bool DisplayList::replay(OpenGLRenderer& renderer, uint32_t level) {
@@ -557,9 +492,7 @@ bool DisplayList::replay(OpenGLRenderer& renderer, uint32_t level) {
// Base structure // Base structure
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
DisplayListRenderer::DisplayListRenderer(): DisplayListRenderer::DisplayListRenderer(): mWriter(MIN_WRITER_SIZE) {
mHeap(HEAP_BLOCK_SIZE), mWriter(MIN_WRITER_SIZE) {
mPathHeap = NULL;
mDisplayList = NULL; mDisplayList = NULL;
} }
@@ -568,16 +501,7 @@ DisplayListRenderer::~DisplayListRenderer() {
} }
void DisplayListRenderer::reset() { void DisplayListRenderer::reset() {
if (mPathHeap) {
mPathHeap->unref();
mPathHeap = NULL;
}
mWriter.reset(); mWriter.reset();
mHeap.reset();
mRCRecorder.reset();
mTFRecorder.reset();
Caches& caches = Caches::getInstance(); Caches& caches = Caches::getInstance();
for (size_t i = 0; i < mBitmapResources.size(); i++) { for (size_t i = 0; i < mBitmapResources.size(); i++) {
@@ -594,6 +518,8 @@ void DisplayListRenderer::reset() {
mPaints.clear(); mPaints.clear();
mPaintMap.clear(); mPaintMap.clear();
mPaths.clear();
mPathMap.clear();
mMatrices.clear(); mMatrices.clear();
} }

View File

@@ -38,7 +38,6 @@ namespace uirenderer {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#define MIN_WRITER_SIZE 16384 #define MIN_WRITER_SIZE 16384
#define HEAP_BLOCK_SIZE 4096
// Debug // Debug
#if DEBUG_DISPLAY_LIST #if DEBUG_DISPLAY_LIST
@@ -47,31 +46,6 @@ namespace uirenderer {
#define DISPLAY_LIST_LOGD(...) #define DISPLAY_LIST_LOGD(...)
#endif #endif
///////////////////////////////////////////////////////////////////////////////
// Helpers
///////////////////////////////////////////////////////////////////////////////
class PathHeap: public SkRefCnt {
public:
PathHeap();
PathHeap(SkFlattenableReadBuffer& buffer);
~PathHeap();
int append(const SkPath& path);
int count() const { return mPaths.count(); }
SkPath& operator[](int index) const {
return *mPaths[index];
}
void flatten(SkFlattenableWriteBuffer& buffer) const;
private:
SkChunkAlloc mHeap;
SkTDArray<SkPath*> mPaths;
};
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Display list // Display list
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@@ -174,7 +148,7 @@ private:
} }
SkPath* getPath() { SkPath* getPath() {
return &(*mPathHeap)[getInt() - 1]; return (SkPath*) getInt();
} }
SkPaint* getPaint() { SkPaint* getPaint() {
@@ -209,19 +183,15 @@ private:
text->mText = (const char*) mReader.skip(length); text->mText = (const char*) mReader.skip(length);
} }
PathHeap* mPathHeap;
Vector<SkBitmap*> mBitmapResources; Vector<SkBitmap*> mBitmapResources;
Vector<SkiaColorFilter*> mFilterResources; Vector<SkiaColorFilter*> mFilterResources;
Vector<SkPaint*> mPaints; Vector<SkPaint*> mPaints;
Vector<SkPath*> mPaths;
Vector<SkMatrix*> mMatrices; Vector<SkMatrix*> mMatrices;
Vector<SkiaShader*> mShaders; Vector<SkiaShader*> mShaders;
mutable SkFlattenableReadBuffer mReader; mutable SkFlattenableReadBuffer mReader;
SkRefCntPlayback mRCPlayback;
SkTypefacePlayback mTFPlayback;
}; };
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@@ -317,6 +287,10 @@ public:
return mPaints; return mPaints;
} }
const Vector<SkPath*>& getPaths() const {
return mPaths;
}
const Vector<SkMatrix*>& getMatrices() const { const Vector<SkMatrix*>& getMatrices() const {
return mMatrices; return mMatrices;
} }
@@ -385,11 +359,24 @@ private:
mWriter.writePad(text, byteLength); mWriter.writePad(text, byteLength);
} }
inline void addPath(const SkPath* path) { inline void addPath(SkPath* path) {
if (mPathHeap == NULL) { if (!path) {
mPathHeap = new PathHeap(); addInt((int) NULL);
return;
} }
addInt(mPathHeap->append(*path));
SkPath* pathCopy = mPathMap.valueFor(path);
if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) {
if (pathCopy == NULL) {
pathCopy = path;
} else {
pathCopy = new SkPath(*path);
mPaths.add(pathCopy);
}
mPathMap.add(path, pathCopy);
}
addInt((int) pathCopy);
} }
inline void addPaint(SkPaint* paint) { inline void addPaint(SkPaint* paint) {
@@ -457,25 +444,22 @@ private:
caches.resourceCache.incrementRefcount(colorFilter); caches.resourceCache.incrementRefcount(colorFilter);
} }
SkChunkAlloc mHeap;
Vector<SkBitmap*> mBitmapResources; Vector<SkBitmap*> mBitmapResources;
Vector<SkiaColorFilter*> mFilterResources; Vector<SkiaColorFilter*> mFilterResources;
Vector<SkPaint*> mPaints; Vector<SkPaint*> mPaints;
DefaultKeyedVector<SkPaint*, SkPaint*> mPaintMap; DefaultKeyedVector<SkPaint*, SkPaint*> mPaintMap;
Vector<SkPath*> mPaths;
DefaultKeyedVector<SkPath*, SkPath*> mPathMap;
Vector<SkiaShader*> mShaders; Vector<SkiaShader*> mShaders;
DefaultKeyedVector<SkiaShader*, SkiaShader*> mShaderMap; DefaultKeyedVector<SkiaShader*, SkiaShader*> mShaderMap;
Vector<SkMatrix*> mMatrices; Vector<SkMatrix*> mMatrices;
PathHeap* mPathHeap;
SkWriter32 mWriter; SkWriter32 mWriter;
SkRefCntRecorder mRCRecorder;
SkRefCntRecorder mTFRecorder;
DisplayList *mDisplayList; DisplayList *mDisplayList;
int mRestoreSaveCount; int mRestoreSaveCount;

View File

@@ -65,7 +65,6 @@ void PathCache::clearGarbage() {
PathTexture* PathCache::get(SkPath* path, SkPaint* paint) { PathTexture* PathCache::get(SkPath* path, SkPaint* paint) {
PathCacheEntry entry(path, paint); PathCacheEntry entry(path, paint);
PathTexture* texture = mCache.get(entry); PathTexture* texture = mCache.get(entry);
if (!texture) { if (!texture) {

View File

@@ -32,7 +32,7 @@ namespace android {
namespace uirenderer { namespace uirenderer {
struct ShadowText { struct ShadowText {
ShadowText(): radius(0), len(0), hash(0), textSize(0.0f), typeface(NULL) { ShadowText(): radius(0), len(0), textSize(0.0f), typeface(NULL) {
} }
ShadowText(SkPaint* paint, uint32_t radius, uint32_t len, const char* srcText): ShadowText(SkPaint* paint, uint32_t radius, uint32_t len, const char* srcText):
@@ -42,20 +42,11 @@ struct ShadowText {
textSize = paint->getTextSize(); textSize = paint->getTextSize();
typeface = paint->getTypeface(); typeface = paint->getTypeface();
hash = 0;
uint32_t multiplier = 1;
const char* text = str.string();
for (uint32_t i = 0; i < len; i++) {
hash += text[i] * multiplier;
uint32_t shifted = multiplier << 5;
multiplier = shifted - multiplier;
}
} }
ShadowText(const ShadowText& shadow): ShadowText(const ShadowText& shadow):
radius(shadow.radius), len(shadow.len), hash(shadow.hash), radius(shadow.radius), len(shadow.len), textSize(shadow.textSize),
textSize(shadow.textSize), typeface(shadow.typeface), str(shadow.str) { typeface(shadow.typeface), str(shadow.str) {
} }
~ShadowText() { ~ShadowText() {
@@ -63,20 +54,17 @@ struct ShadowText {
uint32_t radius; uint32_t radius;
uint32_t len; uint32_t len;
uint32_t hash;
float textSize; float textSize;
SkTypeface* typeface; SkTypeface* typeface;
String8 str; String8 str;
bool operator<(const ShadowText& rhs) const { bool operator<(const ShadowText& rhs) const {
LTE_INT(hash) { LTE_INT(len) {
LTE_INT(len) { LTE_INT(radius) {
LTE_INT(radius) { LTE_FLOAT(textSize) {
LTE_FLOAT(textSize) { if (typeface < rhs.typeface) return true;
if (typeface < rhs.typeface) return true; else if (typeface == rhs.typeface) {
else if (typeface == rhs.typeface) { return str.compare(rhs.str) < 0;
return str.compare(rhs.str) < 0;
}
} }
} }
} }