Merge "Fixes cache misses and extra allocations. Bug #3421454" into honeycomb
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user