Clamp gradient textures to max GL texture size

Change-Id: I8ce4e50988f5194fe5ce4bde7945ec01673af3cd
diff --git a/libs/hwui/GradientCache.cpp b/libs/hwui/GradientCache.cpp
index 0016b81..c7ab9c5 100644
--- a/libs/hwui/GradientCache.cpp
+++ b/libs/hwui/GradientCache.cpp
@@ -16,8 +16,6 @@
 
 #define LOG_TAG "OpenGLRenderer"
 
-#include <GLES2/gl2.h>
-
 #include <SkCanvas.h>
 #include <SkGradientShader.h>
 
@@ -45,6 +43,8 @@
         INIT_LOGD("  Using default gradient cache size of %.2fMB", DEFAULT_GRADIENT_CACHE_SIZE);
     }
 
+    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
+
     mCache.setOnEntryRemovedListener(this);
 }
 
@@ -116,8 +116,11 @@
 
 Texture* GradientCache::addLinearGradient(GradientCacheEntry& gradient,
         uint32_t* colors, float* positions, int count, SkShader::TileMode tileMode) {
+    int width = 256 * (count - 1);
+    width = width < mMaxTextureSize ? width : mMaxTextureSize;
+
     SkBitmap bitmap;
-    bitmap.setConfig(SkBitmap::kARGB_8888_Config, 256 * (count - 1), 1);
+    bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, 1);
     bitmap.allocPixels();
     bitmap.eraseColor(0);
 
diff --git a/libs/hwui/GradientCache.h b/libs/hwui/GradientCache.h
index ac34684..59515a1 100644
--- a/libs/hwui/GradientCache.h
+++ b/libs/hwui/GradientCache.h
@@ -17,6 +17,8 @@
 #ifndef ANDROID_HWUI_GRADIENT_CACHE_H
 #define ANDROID_HWUI_GRADIENT_CACHE_H
 
+#include <GLES2/gl2.h>
+
 #include <SkShader.h>
 
 #include <utils/Mutex.h>
@@ -152,6 +154,8 @@
     uint32_t mSize;
     uint32_t mMaxSize;
 
+    GLint mMaxTextureSize;
+
     Vector<SkShader*> mGarbage;
     mutable Mutex mLock;
 }; // class GradientCache
diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp
index cf5f822..2153a8b 100644
--- a/libs/hwui/ResourceCache.cpp
+++ b/libs/hwui/ResourceCache.cpp
@@ -48,7 +48,8 @@
 
 void ResourceCache::incrementRefcount(void* resource, ResourceType resourceType) {
     Mutex::Autolock _l(mLock);
-    ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
+    ssize_t index = mCache->indexOfKey(resource);
+    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
     if (ref == NULL || mCache->size() == 0) {
         ref = new ResourceReference(resourceType);
         mCache->add(resource, ref);
@@ -78,7 +79,8 @@
 
 void ResourceCache::decrementRefcount(void* resource) {
     Mutex::Autolock _l(mLock);
-    ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
+    ssize_t index = mCache->indexOfKey(resource);
+    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
     if (ref == NULL) {
         // Should not get here - shouldn't get a call to decrement if we're not yet tracking it
         return;
@@ -111,12 +113,13 @@
 
 void ResourceCache::recycle(SkBitmap* resource) {
     Mutex::Autolock _l(mLock);
-    if (mCache->indexOfKey(resource) < 0) {
+    ssize_t index = mCache->indexOfKey(resource);
+    if (index < 0) {
         // not tracking this resource; just recycle the pixel data
         resource->setPixels(NULL, NULL);
         return;
     }
-    ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
+    ResourceReference* ref = mCache->valueAt(index);
     if (ref == NULL) {
         // Should not get here - shouldn't get a call to recycle if we're not yet tracking it
         return;
@@ -129,7 +132,8 @@
 
 void ResourceCache::destructor(SkPath* resource) {
     Mutex::Autolock _l(mLock);
-    ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
+    ssize_t index = mCache->indexOfKey(resource);
+    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
     if (ref == NULL) {
         // If we're not tracking this resource, just delete it
         if (Caches::hasInstance()) {
@@ -146,7 +150,8 @@
 
 void ResourceCache::destructor(SkBitmap* resource) {
     Mutex::Autolock _l(mLock);
-    ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
+    ssize_t index = mCache->indexOfKey(resource);
+    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
     if (ref == NULL) {
         // If we're not tracking this resource, just delete it
         if (Caches::hasInstance()) {
@@ -163,7 +168,8 @@
 
 void ResourceCache::destructor(SkiaShader* resource) {
     Mutex::Autolock _l(mLock);
-    ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
+    ssize_t index = mCache->indexOfKey(resource);
+    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
     if (ref == NULL) {
         // If we're not tracking this resource, just delete it
         delete resource;
@@ -177,7 +183,8 @@
 
 void ResourceCache::destructor(SkiaColorFilter* resource) {
     Mutex::Autolock _l(mLock);
-    ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
+    ssize_t index = mCache->indexOfKey(resource);
+    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
     if (ref == NULL) {
         // If we're not tracking this resource, just delete it
         delete resource;