combine glyph and image bulk alloc, and adjust initial alloc size, to reduce total...
authorreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 19 Jun 2013 19:25:36 +0000 (19:25 +0000)
committerreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 19 Jun 2013 19:25:36 +0000 (19:25 +0000)
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

include/core/SkChunkAlloc.h
src/core/SkChunkAlloc.cpp
src/core/SkGlyphCache.cpp
src/core/SkGlyphCache.h
tests/MemsetTest.cpp

index 1b52a35..e13e2b9 100644 (file)
@@ -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);
index 30cc4e1..8251eae 100644 (file)
@@ -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;
index a1f738e..8d9fb03 100644 (file)
@@ -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
index 155ba7b..918a758 100644 (file)
@@ -230,7 +230,6 @@ private:
     SkGlyph*            fGlyphHash[kHashCount];
     SkTDArray<SkGlyph*> fGlyphArray;
     SkChunkAlloc        fGlyphAlloc;
-    SkChunkAlloc        fImageAlloc;
 
     int fMetricsCount, fAdvanceCount;
 
index c799159..9da7850 100644 (file)
@@ -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());
 }
 
 ///////////////////////////////////////////////////////////////////////////////