Adding API to SkGPipe and SkDeferredCanvas for controlling memory usage externally
BUG=http://code.google.com/p/chromium/issues/detail?id=136828
Review URL: https://codereview.appspot.com/6454102
git-svn-id: http://skia.googlecode.com/svn/trunk@4971 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/pipe/SkGPipeWrite.cpp b/src/pipe/SkGPipeWrite.cpp
index 2ea642e..e020bea 100644
--- a/src/pipe/SkGPipeWrite.cpp
+++ b/src/pipe/SkGPipeWrite.cpp
@@ -290,6 +290,38 @@
this->setMostRecentlyUsed(info);
return info;
}
+
+ size_t freeMemoryIfPossible(size_t bytesToFree) {
+ BitmapInfo* info = fLeastRecentlyUsed;
+ size_t origBytesAllocated = fBytesAllocated;
+ // Purge starting from LRU until a non-evictable bitmap is found
+ // or until everything is evicted.
+ while (info && info->drawCount() == 0) {
+ fBytesAllocated -= (info->fBytesAllocated + sizeof(BitmapInfo));
+ fBitmapCount--;
+ BitmapInfo* nextInfo = info->fMoreRecentlyUsed;
+ SkDELETE(info);
+ info = nextInfo;
+ if ((origBytesAllocated - fBytesAllocated) >= bytesToFree) {
+ break;
+ }
+ }
+
+ if (fLeastRecentlyUsed != info) { // at least one eviction
+ fLeastRecentlyUsed = info;
+ if (NULL != fLeastRecentlyUsed) {
+ fLeastRecentlyUsed->fLessRecentlyUsed = NULL;
+ } else {
+ // everything was evicted
+ fMostRecentlyUsed = NULL;
+ SkASSERT(0 == fBytesAllocated);
+ SkASSERT(0 == fBitmapCount);
+ }
+ }
+
+ return origBytesAllocated - fBytesAllocated;
+ }
+
private:
void setMostRecentlyUsed(BitmapInfo* info);
BitmapInfo* bitmapToReplace(const SkBitmap& bm) const;
@@ -386,6 +418,7 @@
}
void flushRecording(bool detachCurrentBlock);
+ size_t freeMemoryIfPossible(size_t bytesToFree);
size_t storageAllocatedForRecording() {
return fSharedHeap.bytesAllocated();
@@ -1156,6 +1189,10 @@
}
}
+size_t SkGPipeCanvas::freeMemoryIfPossible(size_t bytesToFree) {
+ return fSharedHeap.freeMemoryIfPossible(bytesToFree);
+}
+
///////////////////////////////////////////////////////////////////////////////
template <typename T> uint32_t castToU32(T value) {
@@ -1316,11 +1353,20 @@
}
}
-void SkGPipeWriter::flushRecording(bool detachCurrentBlock){
- fCanvas->flushRecording(detachCurrentBlock);
+void SkGPipeWriter::flushRecording(bool detachCurrentBlock) {
+ if (fCanvas) {
+ fCanvas->flushRecording(detachCurrentBlock);
+ }
}
-size_t SkGPipeWriter::storageAllocatedForRecording() {
+size_t SkGPipeWriter::freeMemoryIfPossible(size_t bytesToFree) {
+ if (fCanvas) {
+ return fCanvas->freeMemoryIfPossible(bytesToFree);
+ }
+ return 0;
+}
+
+size_t SkGPipeWriter::storageAllocatedForRecording() const {
return NULL == fCanvas ? 0 : fCanvas->storageAllocatedForRecording();
}