am 87465f02: Merge "Fixes cache misses and extra allocations. Bug #3421454" into honeycomb

* commit '87465f02e4113542bb203232fed0c0f1f67f9a17':
  Fixes cache misses and extra allocations. Bug #3421454
This commit is contained in:
Romain Guy
2011-02-03 16:34:06 -08:00
committed by Android Git Automerger
6 changed files with 60 additions and 152 deletions

View File

@@ -104,7 +104,7 @@ public class Canvas {
public Canvas() {
// 0 means no native bitmap
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(" CircleShapeCache %8d / %8d",
circleShapeCache.getSize(), circleShapeCache.getMaxSize());
LOGD(" OvalShapeCache %8d / %8d",
ovalShapeCache.getSize(), ovalShapeCache.getMaxSize());
LOGD(" RoundRectShapeCache %8d / %8d",
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(),
dropShadowCache.getMaxSize());
for (uint32_t i = 0; i < fontRenderer.getFontRendererCount(); i++) {
@@ -94,6 +100,11 @@ void Caches::dumpMemoryUsage() {
total += gradientCache.getSize();
total += pathCache.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++) {
total += fontRenderer.getFontRendererSize(i);
}

View File

@@ -21,62 +21,6 @@
namespace android {
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
///////////////////////////////////////////////////////////////////////////////
@@ -143,17 +87,15 @@ DisplayList::~DisplayList() {
}
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++) {
delete mMatrices.itemAt(i);
}
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) {
@@ -169,12 +111,6 @@ void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorde
writer.flatten(buffer);
mReader.setMemory(buffer, size);
mRCPlayback.reset(&recorder.mRCRecorder);
mRCPlayback.setupBuffer(mReader);
mTFPlayback.reset(&recorder.mTFRecorder);
mTFPlayback.setupBuffer(mReader);
Caches& caches = Caches::getInstance();
const Vector<SkBitmap*> &bitmapResources = recorder.getBitmapResources();
@@ -196,19 +132,18 @@ void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorde
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();
for (size_t i = 0; i < matrices.size(); i++) {
mMatrices.add(matrices.itemAt(i));
}
mPathHeap = recorder.mPathHeap;
if (mPathHeap) {
mPathHeap->safeRef();
}
}
void DisplayList::init() {
mPathHeap = NULL;
}
bool DisplayList::replay(OpenGLRenderer& renderer, uint32_t level) {
@@ -557,9 +492,7 @@ bool DisplayList::replay(OpenGLRenderer& renderer, uint32_t level) {
// Base structure
///////////////////////////////////////////////////////////////////////////////
DisplayListRenderer::DisplayListRenderer():
mHeap(HEAP_BLOCK_SIZE), mWriter(MIN_WRITER_SIZE) {
mPathHeap = NULL;
DisplayListRenderer::DisplayListRenderer(): mWriter(MIN_WRITER_SIZE) {
mDisplayList = NULL;
}
@@ -568,16 +501,7 @@ DisplayListRenderer::~DisplayListRenderer() {
}
void DisplayListRenderer::reset() {
if (mPathHeap) {
mPathHeap->unref();
mPathHeap = NULL;
}
mWriter.reset();
mHeap.reset();
mRCRecorder.reset();
mTFRecorder.reset();
Caches& caches = Caches::getInstance();
for (size_t i = 0; i < mBitmapResources.size(); i++) {
@@ -594,6 +518,8 @@ void DisplayListRenderer::reset() {
mPaints.clear();
mPaintMap.clear();
mPaths.clear();
mPathMap.clear();
mMatrices.clear();
}

View File

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

View File

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

View File

@@ -32,7 +32,7 @@ namespace android {
namespace uirenderer {
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):
@@ -42,20 +42,11 @@ struct ShadowText {
textSize = paint->getTextSize();
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):
radius(shadow.radius), len(shadow.len), hash(shadow.hash),
textSize(shadow.textSize), typeface(shadow.typeface), str(shadow.str) {
radius(shadow.radius), len(shadow.len), textSize(shadow.textSize),
typeface(shadow.typeface), str(shadow.str) {
}
~ShadowText() {
@@ -63,20 +54,17 @@ struct ShadowText {
uint32_t radius;
uint32_t len;
uint32_t hash;
float textSize;
SkTypeface* typeface;
String8 str;
bool operator<(const ShadowText& rhs) const {
LTE_INT(hash) {
LTE_INT(len) {
LTE_INT(radius) {
LTE_FLOAT(textSize) {
if (typeface < rhs.typeface) return true;
else if (typeface == rhs.typeface) {
return str.compare(rhs.str) < 0;
}
LTE_INT(len) {
LTE_INT(radius) {
LTE_FLOAT(textSize) {
if (typeface < rhs.typeface) return true;
else if (typeface == rhs.typeface) {
return str.compare(rhs.str) < 0;
}
}
}