Set maximum output size for scaled-image-cache images

Accessable via:
  SkScaledImageCache::{G,S}etMaximumOutputSizeForHighQualityFilter

Also, a unit test.

BUG=389439
R=humper@google.com, tomhudson@google.com, reveman@chromium.org, vangelis@chromium.org, reed@google.com

Author: halcanary@google.com

Review URL: https://codereview.chromium.org/394003003
diff --git a/src/core/SkScaledImageCache.cpp b/src/core/SkScaledImageCache.cpp
index 6d63edb..dca7596 100644
--- a/src/core/SkScaledImageCache.cpp
+++ b/src/core/SkScaledImageCache.cpp
@@ -140,12 +140,13 @@
 #else
     fHash = NULL;
 #endif
-    fBytesUsed = 0;
+    fTotalBytesUsed = 0;
     fCount = 0;
+    fSingleAllocationByteLimit = 0;
     fAllocator = NULL;
 
     // One of these should be explicit set by the caller after we return.
-    fByteLimit = 0;
+    fTotalByteLimit = 0;
     fDiscardableFactory = NULL;
 }
 
@@ -270,7 +271,7 @@
 
 SkScaledImageCache::SkScaledImageCache(size_t byteLimit) {
     this->init();
-    fByteLimit = byteLimit;
+    fTotalByteLimit = byteLimit;
 }
 
 SkScaledImageCache::~SkScaledImageCache() {
@@ -475,10 +476,10 @@
         byteLimit = SK_MaxU32;  // no limit based on bytes
     } else {
         countLimit = SK_MaxS32; // no limit based on count
-        byteLimit = fByteLimit;
+        byteLimit = fTotalByteLimit;
     }
 
-    size_t bytesUsed = fBytesUsed;
+    size_t bytesUsed = fTotalBytesUsed;
     int    countUsed = fCount;
 
     Rec* rec = fTail;
@@ -504,13 +505,13 @@
         rec = prev;
     }
 
-    fBytesUsed = bytesUsed;
+    fTotalBytesUsed = bytesUsed;
     fCount = countUsed;
 }
 
-size_t SkScaledImageCache::setByteLimit(size_t newLimit) {
-    size_t prevLimit = fByteLimit;
-    fByteLimit = newLimit;
+size_t SkScaledImageCache::setTotalByteLimit(size_t newLimit) {
+    size_t prevLimit = fTotalByteLimit;
+    fTotalByteLimit = newLimit;
     if (newLimit < prevLimit) {
         this->purgeAsNeeded();
     }
@@ -570,7 +571,7 @@
     if (!fTail) {
         fTail = rec;
     }
-    fBytesUsed += rec->bytesUsed();
+    fTotalBytesUsed += rec->bytesUsed();
     fCount += 1;
 
     this->validate();
@@ -582,14 +583,14 @@
 void SkScaledImageCache::validate() const {
     if (NULL == fHead) {
         SkASSERT(NULL == fTail);
-        SkASSERT(0 == fBytesUsed);
+        SkASSERT(0 == fTotalBytesUsed);
         return;
     }
 
     if (fHead == fTail) {
         SkASSERT(NULL == fHead->fPrev);
         SkASSERT(NULL == fHead->fNext);
-        SkASSERT(fHead->bytesUsed() == fBytesUsed);
+        SkASSERT(fHead->bytesUsed() == fTotalBytesUsed);
         return;
     }
 
@@ -604,7 +605,7 @@
     while (rec) {
         count += 1;
         used += rec->bytesUsed();
-        SkASSERT(used <= fBytesUsed);
+        SkASSERT(used <= fTotalBytesUsed);
         rec = rec->fNext;
     }
     SkASSERT(fCount == count);
@@ -634,10 +635,20 @@
     }
 
     SkDebugf("SkScaledImageCache: count=%d bytes=%d locked=%d %s\n",
-             fCount, fBytesUsed, locked,
+             fCount, fTotalBytesUsed, locked,
              fDiscardableFactory ? "discardable" : "malloc");
 }
 
+size_t SkScaledImageCache::setSingleAllocationByteLimit(size_t newLimit) {
+    size_t oldLimit = fSingleAllocationByteLimit;
+    fSingleAllocationByteLimit = newLimit;
+    return oldLimit;
+}
+
+size_t SkScaledImageCache::getSingleAllocationByteLimit() const {
+    return fSingleAllocationByteLimit;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 #include "SkThread.h"
@@ -724,19 +735,19 @@
 //    get_cache()->dump();
 }
 
-size_t SkScaledImageCache::GetBytesUsed() {
+size_t SkScaledImageCache::GetTotalBytesUsed() {
     SkAutoMutexAcquire am(gMutex);
-    return get_cache()->getBytesUsed();
+    return get_cache()->getTotalBytesUsed();
 }
 
-size_t SkScaledImageCache::GetByteLimit() {
+size_t SkScaledImageCache::GetTotalByteLimit() {
     SkAutoMutexAcquire am(gMutex);
-    return get_cache()->getByteLimit();
+    return get_cache()->getTotalByteLimit();
 }
 
-size_t SkScaledImageCache::SetByteLimit(size_t newLimit) {
+size_t SkScaledImageCache::SetTotalByteLimit(size_t newLimit) {
     SkAutoMutexAcquire am(gMutex);
-    return get_cache()->setByteLimit(newLimit);
+    return get_cache()->setTotalByteLimit(newLimit);
 }
 
 SkBitmap::Allocator* SkScaledImageCache::GetAllocator() {
@@ -749,18 +760,37 @@
     get_cache()->dump();
 }
 
+size_t SkScaledImageCache::SetSingleAllocationByteLimit(size_t size) {
+    SkAutoMutexAcquire am(gMutex);
+    return get_cache()->setSingleAllocationByteLimit(size);
+}
+
+size_t SkScaledImageCache::GetSingleAllocationByteLimit() {
+    SkAutoMutexAcquire am(gMutex);
+    return get_cache()->getSingleAllocationByteLimit();
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 #include "SkGraphics.h"
 
-size_t SkGraphics::GetImageCacheBytesUsed() {
-    return SkScaledImageCache::GetBytesUsed();
+size_t SkGraphics::GetImageCacheTotalBytesUsed() {
+    return SkScaledImageCache::GetTotalBytesUsed();
 }
 
-size_t SkGraphics::GetImageCacheByteLimit() {
-    return SkScaledImageCache::GetByteLimit();
+size_t SkGraphics::GetImageCacheTotalByteLimit() {
+    return SkScaledImageCache::GetTotalByteLimit();
 }
 
-size_t SkGraphics::SetImageCacheByteLimit(size_t newLimit) {
-    return SkScaledImageCache::SetByteLimit(newLimit);
+size_t SkGraphics::SetImageCacheTotalByteLimit(size_t newLimit) {
+    return SkScaledImageCache::SetTotalByteLimit(newLimit);
 }
+
+size_t SkGraphics::GetImageCacheSingleAllocationByteLimit() {
+    return SkScaledImageCache::GetSingleAllocationByteLimit();
+}
+
+size_t SkGraphics::SetImageCacheSingleAllocationByteLimit(size_t newLimit) {
+    return SkScaledImageCache::SetSingleAllocationByteLimit(newLimit);
+}
+