Merge "don't call hwc with non-empty layer lists for blanked displays" into jb-mr1-dev
diff --git a/include/private/ui/RegionHelper.h b/include/private/ui/RegionHelper.h
index 421bdda..8c190dd 100644
--- a/include/private/ui/RegionHelper.h
+++ b/include/private/ui/RegionHelper.h
@@ -26,10 +26,10 @@
 template<typename RECT>
 class region_operator
 {
+public:
     typedef typename RECT::value_type TYPE;    
     static const TYPE max_value = 0x7FFFFFF;
 
-public:
     /* 
      * Common boolean operations:
      * value is computed as 0b101 op 0b110
diff --git a/include/ui/Region.h b/include/ui/Region.h
index 0049fde..43a4450 100644
--- a/include/ui/Region.h
+++ b/include/ui/Region.h
@@ -161,7 +161,8 @@
     static void translate(Region& reg, int dx, int dy);
     static void translate(Region& dst, const Region& reg, int dx, int dy);
 
-    static bool validate(const Region& reg, const char* name);
+    static bool validate(const Region& reg,
+            const char* name, bool silent = false);
     
     // mStorage is a (manually) sorted array of Rects describing the region
     // with an extra Rect as the last element which is set to the
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
index 94fb1d5..932ef68 100644
--- a/libs/ui/Region.cpp
+++ b/libs/ui/Region.cpp
@@ -20,6 +20,7 @@
 
 #include <utils/Log.h>
 #include <utils/String8.h>
+#include <utils/CallStack.h>
 
 #include <ui/Rect.h>
 #include <ui/Region.h>
@@ -113,10 +114,6 @@
     Rect rect(l,t,r,b);
     size_t where = mStorage.size() - 1;
     mStorage.insertAt(rect, where, 1);
-
-#if VALIDATE_REGIONS
-    validate(*this, "addRectUnchecked");
-#endif
 }
 
 // ----------------------------------------------------------------------------
@@ -338,47 +335,72 @@
     }
 };
 
-bool Region::validate(const Region& reg, const char* name)
+bool Region::validate(const Region& reg, const char* name, bool silent)
 {
     bool result = true;
     const_iterator cur = reg.begin();
     const_iterator const tail = reg.end();
-    const_iterator prev = cur++;
+    const_iterator prev = cur;
     Rect b(*prev);
     while (cur != tail) {
-        b.left   = b.left   < cur->left   ? b.left   : cur->left;
-        b.top    = b.top    < cur->top    ? b.top    : cur->top;
-        b.right  = b.right  > cur->right  ? b.right  : cur->right;
-        b.bottom = b.bottom > cur->bottom ? b.bottom : cur->bottom;
-        if (cur->top == prev->top) {
-            if (cur->bottom != prev->bottom) {
-                ALOGE("%s: invalid span %p", name, cur);
+        if (cur->isValid() == false) {
+            ALOGE_IF(!silent, "%s: region contains an invalid Rect", name);
+            result = false;
+        }
+        if (cur->right > region_operator<Rect>::max_value) {
+            ALOGE_IF(!silent, "%s: rect->right > max_value", name);
+            result = false;
+        }
+        if (cur->bottom > region_operator<Rect>::max_value) {
+            ALOGE_IF(!silent, "%s: rect->right > max_value", name);
+            result = false;
+        }
+        if (prev != cur) {
+            b.left   = b.left   < cur->left   ? b.left   : cur->left;
+            b.top    = b.top    < cur->top    ? b.top    : cur->top;
+            b.right  = b.right  > cur->right  ? b.right  : cur->right;
+            b.bottom = b.bottom > cur->bottom ? b.bottom : cur->bottom;
+            if ((*prev < *cur) == false) {
+                ALOGE_IF(!silent, "%s: region's Rects not sorted", name);
                 result = false;
-            } else if (cur->left < prev->right) {
-                ALOGE("%s: spans overlap horizontally prev=%p, cur=%p",
+            }
+            if (cur->top == prev->top) {
+                if (cur->bottom != prev->bottom) {
+                    ALOGE_IF(!silent, "%s: invalid span %p", name, cur);
+                    result = false;
+                } else if (cur->left < prev->right) {
+                    ALOGE_IF(!silent,
+                            "%s: spans overlap horizontally prev=%p, cur=%p",
+                            name, prev, cur);
+                    result = false;
+                }
+            } else if (cur->top < prev->bottom) {
+                ALOGE_IF(!silent,
+                        "%s: spans overlap vertically prev=%p, cur=%p",
                         name, prev, cur);
                 result = false;
             }
-        } else if (cur->top < prev->bottom) {
-            ALOGE("%s: spans overlap vertically prev=%p, cur=%p",
-                    name, prev, cur);
-            result = false;
+            prev = cur;
         }
-        prev = cur;
         cur++;
     }
     if (b != reg.getBounds()) {
         result = false;
-        ALOGE("%s: invalid bounds [%d,%d,%d,%d] vs. [%d,%d,%d,%d]", name,
+        ALOGE_IF(!silent,
+                "%s: invalid bounds [%d,%d,%d,%d] vs. [%d,%d,%d,%d]", name,
                 b.left, b.top, b.right, b.bottom,
                 reg.getBounds().left, reg.getBounds().top, 
                 reg.getBounds().right, reg.getBounds().bottom);
     }
     if (reg.mStorage.size() == 2) {
-        ALOGE("mStorage size is 2, which is never valid");
+        result = false;
+        ALOGE_IF(!silent, "%s: mStorage size is 2, which is never valid", name);
     }
-    if (result == false) {
+    if (result == false && !silent) {
         reg.dump(name);
+        CallStack stack;
+        stack.update();
+        stack.dump("");
     }
     return result;
 }
@@ -564,27 +586,37 @@
 }
 
 status_t Region::flatten(void* buffer) const {
+#if VALIDATE_REGIONS
+    validate(*this, "Region::flatten");
+#endif
     Rect* rects = reinterpret_cast<Rect*>(buffer);
     memcpy(rects, mStorage.array(), mStorage.size() * sizeof(Rect));
     return NO_ERROR;
 }
 
 status_t Region::unflatten(void const* buffer, size_t size) {
-    mStorage.clear();
+    Region result;
     if (size >= sizeof(Rect)) {
         Rect const* rects = reinterpret_cast<Rect const*>(buffer);
         size_t count = size / sizeof(Rect);
         if (count > 0) {
-            ssize_t err = mStorage.insertAt(0, count);
+            result.mStorage.clear();
+            ssize_t err = result.mStorage.insertAt(0, count);
             if (err < 0) {
                 return status_t(err);
             }
-            memcpy(mStorage.editArray(), rects, count*sizeof(Rect));
+            memcpy(result.mStorage.editArray(), rects, count*sizeof(Rect));
         }
     }
 #if VALIDATE_REGIONS
-    validate(*this, "Region::unflatten");
+    validate(result, "Region::unflatten");
 #endif
+
+    if (!result.validate(result, "Region::unflatten", true)) {
+        ALOGE("Region::unflatten() failed, invalid region");
+        return BAD_VALUE;
+    }
+    mStorage = result.mStorage;
     return NO_ERROR;
 }
 
diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk
index eea79f8..31bfcd7 100644
--- a/opengl/libs/Android.mk
+++ b/opengl/libs/Android.mk
@@ -57,6 +57,10 @@
   LOCAL_CFLAGS += -DMAX_EGL_CACHE_ENTRY_SIZE=$(MAX_EGL_CACHE_ENTRY_SIZE)
 endif
 
+ifneq ($(MAX_EGL_CACHE_KEY_SIZE),)
+  LOCAL_CFLAGS += -DMAX_EGL_CACHE_KEY_SIZE=$(MAX_EGL_CACHE_KEY_SIZE)
+endif
+
 ifneq ($(MAX_EGL_CACHE_SIZE),)
   LOCAL_CFLAGS += -DMAX_EGL_CACHE_SIZE=$(MAX_EGL_CACHE_SIZE)
 endif
diff --git a/opengl/libs/EGL/egl_cache.cpp b/opengl/libs/EGL/egl_cache.cpp
index ed2bef3..72655df 100644
--- a/opengl/libs/EGL/egl_cache.cpp
+++ b/opengl/libs/EGL/egl_cache.cpp
@@ -29,12 +29,16 @@
 #define MAX_EGL_CACHE_ENTRY_SIZE (16 * 1024);
 #endif
 
+#ifndef MAX_EGL_CACHE_KEY_SIZE
+#define MAX_EGL_CACHE_KEY_SIZE (1024);
+#endif
+
 #ifndef MAX_EGL_CACHE_SIZE
 #define MAX_EGL_CACHE_SIZE (64 * 1024);
 #endif
 
 // Cache size limits.
-static const size_t maxKeySize = 1024;
+static const size_t maxKeySize = MAX_EGL_CACHE_KEY_SIZE;
 static const size_t maxValueSize = MAX_EGL_CACHE_ENTRY_SIZE;
 static const size_t maxTotalSize = MAX_EGL_CACHE_SIZE;