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