combine glyph and image bulk alloc, and adjust initial alloc size, to reduce total waste from 50% to 30%
add diagnostics to measure cache efficiency BUG= Review URL: https://codereview.chromium.org/17449012 git-svn-id: http://skia.googlecode.com/svn/trunk@9691 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
3832da1e9c
commit
6757a3c71f
@ -42,6 +42,7 @@ public:
|
||||
size_t unalloc(void* ptr);
|
||||
|
||||
size_t totalCapacity() const { return fTotalCapacity; }
|
||||
size_t totalUsed() const { return fTotalUsed; }
|
||||
int blockCount() const { return fBlockCount; }
|
||||
|
||||
/**
|
||||
@ -58,6 +59,7 @@ private:
|
||||
size_t fMinSize;
|
||||
size_t fChunkSize;
|
||||
size_t fTotalCapacity;
|
||||
size_t fTotalUsed; // will be <= fTotalCapacity
|
||||
int fBlockCount;
|
||||
|
||||
Block* newBlock(size_t bytes, AllocFailType ftype);
|
||||
|
@ -52,6 +52,7 @@ SkChunkAlloc::SkChunkAlloc(size_t minSize) {
|
||||
fMinSize = minSize;
|
||||
fChunkSize = fMinSize;
|
||||
fTotalCapacity = 0;
|
||||
fTotalUsed = 0;
|
||||
fBlockCount = 0;
|
||||
}
|
||||
|
||||
@ -64,6 +65,7 @@ void SkChunkAlloc::reset() {
|
||||
fBlock = NULL;
|
||||
fChunkSize = fMinSize; // reset to our initial minSize
|
||||
fTotalCapacity = 0;
|
||||
fTotalUsed = 0;
|
||||
fBlockCount = 0;
|
||||
}
|
||||
|
||||
@ -90,6 +92,8 @@ SkChunkAlloc::Block* SkChunkAlloc::newBlock(size_t bytes, AllocFailType ftype) {
|
||||
}
|
||||
|
||||
void* SkChunkAlloc::alloc(size_t bytes, AllocFailType ftype) {
|
||||
fTotalUsed += bytes;
|
||||
|
||||
bytes = SkAlign4(bytes);
|
||||
|
||||
Block* block = fBlock;
|
||||
|
@ -48,14 +48,13 @@ bool gSkSuppressFontCachePurgeSpew;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define kMinGlphAlloc (sizeof(SkGlyph) * 64)
|
||||
#define kMinImageAlloc (24 * 64) // should be pointsize-dependent
|
||||
|
||||
#define METRICS_RESERVE_COUNT 128 // so we don't grow this array a lot
|
||||
// so we don't grow our arrays a lot
|
||||
#define kMinGlyphCount 16
|
||||
#define kMinGlyphImageSize (16*2)
|
||||
#define kMinAllocAmount ((sizeof(SkGlyph) + kMinGlyphImageSize) * kMinGlyphCount)
|
||||
|
||||
SkGlyphCache::SkGlyphCache(SkTypeface* typeface, const SkDescriptor* desc)
|
||||
: fGlyphAlloc(kMinGlphAlloc)
|
||||
, fImageAlloc(kMinImageAlloc) {
|
||||
: fGlyphAlloc(kMinAllocAmount) {
|
||||
SkASSERT(typeface);
|
||||
|
||||
fPrev = fNext = NULL;
|
||||
@ -69,9 +68,9 @@ SkGlyphCache::SkGlyphCache(SkTypeface* typeface, const SkDescriptor* desc)
|
||||
// init with 0xFF so that the charCode field will be -1, which is invalid
|
||||
memset(fCharToGlyphHash, 0xFF, sizeof(fCharToGlyphHash));
|
||||
|
||||
fMemoryUsed = sizeof(*this) + kMinGlphAlloc + kMinImageAlloc;
|
||||
fMemoryUsed = sizeof(*this);
|
||||
|
||||
fGlyphArray.setReserve(METRICS_RESERVE_COUNT);
|
||||
fGlyphArray.setReserve(kMinGlyphCount);
|
||||
|
||||
fMetricsCount = 0;
|
||||
fAdvanceCount = 0;
|
||||
@ -79,6 +78,30 @@ SkGlyphCache::SkGlyphCache(SkTypeface* typeface, const SkDescriptor* desc)
|
||||
}
|
||||
|
||||
SkGlyphCache::~SkGlyphCache() {
|
||||
#if 0
|
||||
{
|
||||
size_t ptrMem = fGlyphArray.count() * sizeof(SkGlyph*);
|
||||
size_t glyphAlloc = fGlyphAlloc.totalCapacity();
|
||||
size_t glyphHashUsed = 0;
|
||||
size_t uniHashUsed = 0;
|
||||
for (int i = 0; i < kHashCount; ++i) {
|
||||
glyphHashUsed += fGlyphHash[i] ? sizeof(fGlyphHash[0]) : 0;
|
||||
uniHashUsed += fCharToGlyphHash[i].fID != 0xFFFFFFFF ? sizeof(fCharToGlyphHash[0]) : 0;
|
||||
}
|
||||
size_t glyphUsed = fGlyphArray.count() * sizeof(SkGlyph);
|
||||
size_t imageUsed = 0;
|
||||
for (int i = 0; i < fGlyphArray.count(); ++i) {
|
||||
const SkGlyph& g = *fGlyphArray[i];
|
||||
if (g.fImage) {
|
||||
imageUsed += g.fHeight * g.rowBytes();
|
||||
}
|
||||
}
|
||||
|
||||
printf("glyphPtrArray,%zu, Alloc,%zu, imageUsed,%zu, glyphUsed,%zu, glyphHashAlloc,%zu, glyphHashUsed,%zu, unicharHashAlloc,%zu, unicharHashUsed,%zu\n",
|
||||
ptrMem, glyphAlloc, imageUsed, glyphUsed, sizeof(fGlyphHash), glyphHashUsed, sizeof(fCharToGlyphHash), uniHashUsed);
|
||||
|
||||
}
|
||||
#endif
|
||||
SkGlyph** gptr = fGlyphArray.begin();
|
||||
SkGlyph** stop = fGlyphArray.end();
|
||||
while (gptr < stop) {
|
||||
@ -296,7 +319,7 @@ const void* SkGlyphCache::findImage(const SkGlyph& glyph) {
|
||||
if (glyph.fWidth > 0 && glyph.fWidth < kMaxGlyphWidth) {
|
||||
if (glyph.fImage == NULL) {
|
||||
size_t size = glyph.computeImageSize();
|
||||
const_cast<SkGlyph&>(glyph).fImage = fImageAlloc.alloc(size,
|
||||
const_cast<SkGlyph&>(glyph).fImage = fGlyphAlloc.alloc(size,
|
||||
SkChunkAlloc::kReturnNil_AllocFailType);
|
||||
// check that alloc() actually succeeded
|
||||
if (glyph.fImage) {
|
||||
@ -708,7 +731,7 @@ void SkGlyphCache::validate() const {
|
||||
SkASSERT(glyph);
|
||||
SkASSERT(fGlyphAlloc.contains(glyph));
|
||||
if (glyph->fImage) {
|
||||
SkASSERT(fImageAlloc.contains(glyph->fImage));
|
||||
SkASSERT(fGlyphAlloc.contains(glyph->fImage));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -230,7 +230,6 @@ private:
|
||||
SkGlyph* fGlyphHash[kHashCount];
|
||||
SkTDArray<SkGlyph*> fGlyphArray;
|
||||
SkChunkAlloc fGlyphAlloc;
|
||||
SkChunkAlloc fImageAlloc;
|
||||
|
||||
int fMetricsCount, fAdvanceCount;
|
||||
|
||||
|
@ -14,22 +14,27 @@ static void test_chunkalloc(skiatest::Reporter* reporter) {
|
||||
SkChunkAlloc alloc(min);
|
||||
|
||||
REPORTER_ASSERT(reporter, 0 == alloc.totalCapacity());
|
||||
REPORTER_ASSERT(reporter, 0 == alloc.totalUsed());
|
||||
REPORTER_ASSERT(reporter, 0 == alloc.blockCount());
|
||||
REPORTER_ASSERT(reporter, !alloc.contains(NULL));
|
||||
REPORTER_ASSERT(reporter, !alloc.contains(reporter));
|
||||
|
||||
alloc.reset();
|
||||
REPORTER_ASSERT(reporter, 0 == alloc.totalCapacity());
|
||||
REPORTER_ASSERT(reporter, 0 == alloc.totalUsed());
|
||||
REPORTER_ASSERT(reporter, 0 == alloc.blockCount());
|
||||
|
||||
size_t size = min >> 1;
|
||||
void* ptr = alloc.allocThrow(size);
|
||||
REPORTER_ASSERT(reporter, alloc.totalCapacity() >= size);
|
||||
REPORTER_ASSERT(reporter, alloc.totalUsed() == size);
|
||||
REPORTER_ASSERT(reporter, alloc.blockCount() > 0);
|
||||
REPORTER_ASSERT(reporter, alloc.contains(ptr));
|
||||
|
||||
alloc.reset();
|
||||
REPORTER_ASSERT(reporter, !alloc.contains(ptr));
|
||||
REPORTER_ASSERT(reporter, 0 == alloc.totalCapacity());
|
||||
REPORTER_ASSERT(reporter, 0 == alloc.totalUsed());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
Loading…
Reference in New Issue
Block a user