Make SkDeferredCanvas query SkGPipeWriter for space allocated for bitmaps.
SkGPipe now has a method to report how much memory is used for its shared heap.
BUG=http://code.google.com/p/skia/issues/detail?id=738
TEST=DeferredCanvasTest
Review URL: https://codereview.appspot.com/6445046
git-svn-id: http://skia.googlecode.com/svn/trunk@4791 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/pipe/SkGPipeWrite.cpp b/src/pipe/SkGPipeWrite.cpp
index dff3e14..a6ffae1 100644
--- a/src/pipe/SkGPipeWrite.cpp
+++ b/src/pipe/SkGPipeWrite.cpp
@@ -161,19 +161,32 @@
, fMostRecentlyUsed(NULL)
, fLeastRecentlyUsed(NULL)
, fCanDoShallowCopies(shallow)
- , fNumberOfReaders(numOfReaders) {}
+ , fNumberOfReaders(numOfReaders)
+ , fBytesAllocated(0) {}
~SharedHeap() {
BitmapInfo* iter = fMostRecentlyUsed;
while (iter != NULL) {
+ SkDEBUGCODE(fBytesAllocated -= (iter->fBytesAllocated + sizeof(BitmapInfo)));
BitmapInfo* next = iter->fLessRecentlyUsed;
SkDELETE(iter);
fBitmapCount--;
iter = next;
}
SkASSERT(0 == fBitmapCount);
+ SkASSERT(0 == fBytesAllocated);
}
/*
+ * Get the approximate number of bytes allocated.
+ *
+ * Not exact. Some SkBitmaps may share SkPixelRefs, in which case only one
+ * SkBitmap will take the size of the SkPixelRef into account (the first
+ * one). It is possible that the one which accounts for the SkPixelRef has
+ * been removed, in which case we will no longer be counting those bytes.
+ */
+ size_t bytesAllocated() { return fBytesAllocated; }
+
+ /*
* Add a copy of a bitmap to the heap.
* @param bm The SkBitmap to be copied and placed in the heap.
* @return void* Pointer to the BitmapInfo stored in the heap, which
@@ -190,6 +203,10 @@
while (iter != NULL) {
if (genID == iter->fGenID) {
SkBitmap* storedBitmap = iter->fBitmap;
+ // TODO: Perhaps we can share code with
+ // SkPictureRecord::PixelRefDictionaryEntry/
+ // BitmapIndexCacheEntry so we can do a binary search for a
+ // matching bitmap
if (orig.pixelRefOffset() != storedBitmap->pixelRefOffset()
|| orig.width() != storedBitmap->width()
|| orig.height() != storedBitmap->height()) {
@@ -246,13 +263,23 @@
}
BitmapInfo* info;
if (NULL == replace) {
+ fBytesAllocated += sizeof(BitmapInfo);
info = SkNEW_ARGS(BitmapInfo, (copy, genID, fNumberOfReaders));
fBitmapCount++;
} else {
+ fBytesAllocated -= replace->fBytesAllocated;
replace->fGenID = genID;
replace->addDraws(fNumberOfReaders);
info = replace;
}
+ // Always include the size of the SkBitmap struct.
+ info->fBytesAllocated = sizeof(SkBitmap);
+ // If the SkBitmap does not share an SkPixelRef with an SkBitmap already
+ // in the SharedHeap, also include the size of its pixels.
+ if (NULL == sharedPixelRef) {
+ info->fBytesAllocated += orig.getSize();
+ }
+ fBytesAllocated += info->fBytesAllocated;
this->setMostRecentlyUsed(info);
return info;
}
@@ -265,6 +292,7 @@
BitmapInfo* fMostRecentlyUsed;
const bool fCanDoShallowCopies;
const int fNumberOfReaders;
+ size_t fBytesAllocated;
};
// We just "used" info. Update our LRU accordingly
@@ -352,6 +380,10 @@
void flushRecording(bool detachCurrentBlock);
+ size_t storageAllocatedForRecording() {
+ return fSharedHeap.bytesAllocated();
+ }
+
// overrides from SkCanvas
virtual int save(SaveFlags) SK_OVERRIDE;
virtual int saveLayer(const SkRect* bounds, const SkPaint*,
@@ -1251,3 +1283,7 @@
fCanvas->flushRecording(detachCurrentBlock);
}
+size_t SkGPipeWriter::storageAllocatedForRecording() {
+ return NULL == fCanvas ? 0 : fCanvas->storageAllocatedForRecording();
+}
+