added native_window_set_buffer_count()

this method can be used to change the number of buffers
associated to a native window. the default is two.

Change-Id: I608b959e6b29d77f95edb23c31dc9b099a758f2f
diff --git a/include/private/surfaceflinger/SharedBufferStack.h b/include/private/surfaceflinger/SharedBufferStack.h
index 0c5a2e4..c3ac317 100644
--- a/include/private/surfaceflinger/SharedBufferStack.h
+++ b/include/private/surfaceflinger/SharedBufferStack.h
@@ -80,6 +80,7 @@
     // file need to be updated.
     static const unsigned int NUM_LAYERS_MAX  = 31;
     static const unsigned int NUM_BUFFER_MAX  = 16;
+    static const unsigned int NUM_BUFFER_MIN  = 2;
     static const unsigned int NUM_DISPLAY_MAX = 4;
 
     struct Statistics { // 4 longs
diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h
index 973780f..e4d60af 100644
--- a/include/surfaceflinger/Surface.h
+++ b/include/surfaceflinger/Surface.h
@@ -212,6 +212,7 @@
     int  dispatch_connect(va_list args);
     int  dispatch_disconnect(va_list args);
     int  dispatch_crop(va_list args);
+    int  dispatch_set_buffer_count(va_list args);
     
     void setUsage(uint32_t reqUsage);
     int  connect(int api);
diff --git a/include/ui/egl/android_natives.h b/include/ui/egl/android_natives.h
index 49bfa2b..b44901f 100644
--- a/include/ui/egl/android_natives.h
+++ b/include/ui/egl/android_natives.h
@@ -81,6 +81,7 @@
     NATIVE_WINDOW_CONNECT,
     NATIVE_WINDOW_DISCONNECT,
     NATIVE_WINDOW_SET_CROP,
+    NATIVE_WINDOW_SET_BUFFER_COUNT,
 };
 
 /* parameter for NATIVE_WINDOW_[DIS]CONNECT */
@@ -190,6 +191,7 @@
      *     NATIVE_WINDOW_CONNECT
      *     NATIVE_WINDOW_DISCONNECT
      *     NATIVE_WINDOW_SET_CROP
+     *     NATIVE_WINDOW_SET_BUFFER_COUNT
      *  
      */
     
@@ -201,8 +203,9 @@
 
 
 /*
- *  native_window_set_usage() sets the intended usage flags for the next
- *  buffers acquired with (*lockBuffer)() and on.
+ *  native_window_set_usage(..., usage)
+ *  Sets the intended usage flags for the next buffers
+ *  acquired with (*lockBuffer)() and on.
  *  By default (if this function is never called), a usage of
  *      GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE
  *  is assumed.
@@ -217,8 +220,8 @@
 }
 
 /*
- * native_window_connect(..., NATIVE_WINDOW_API_EGL) must be called
- * by EGL when the window is made current.
+ * native_window_connect(..., NATIVE_WINDOW_API_EGL)
+ * Must be called by EGL when the window is made current.
  * Returns -EINVAL if for some reason the window cannot be connected, which
  * can happen if it's connected to some other API.
  */
@@ -229,8 +232,8 @@
 }
 
 /*
- * native_window_disconnect(..., NATIVE_WINDOW_API_EGL) must be called
- * by EGL when the window is made not current.
+ * native_window_disconnect(..., NATIVE_WINDOW_API_EGL)
+ * Must be called by EGL when the window is made not current.
  * An error is returned if for instance the window wasn't connected in the
  * first place.
  */
@@ -241,8 +244,8 @@
 }
 
 /*
- * native_window_set_crop(..., crop) sets which region of the next queued
- * buffers needs to be considered.
+ * native_window_set_crop(..., crop)
+ * Sets which region of the next queued buffers needs to be considered.
  * A buffer's crop region is scaled to match the surface's size.
  *
  * The specified crop region applies to all buffers queued after it is called.
@@ -259,6 +262,17 @@
     return window->perform(window, NATIVE_WINDOW_SET_CROP, crop);
 }
 
+/*
+ * native_window_set_buffer_count(..., count)
+ * Sets the number of buffers associated with this native window.
+ */
+static inline int native_window_set_buffer_count(
+        android_native_window_t* window,
+        size_t bufferCount)
+{
+    return window->perform(window, NATIVE_WINDOW_SET_BUFFER_COUNT, bufferCount);
+}
+
 // ---------------------------------------------------------------------------
 
 /* FIXME: this is legacy for pixmaps */
diff --git a/libs/surfaceflinger_client/SharedBufferStack.cpp b/libs/surfaceflinger_client/SharedBufferStack.cpp
index 5deeabb..e2e1591 100644
--- a/libs/surfaceflinger_client/SharedBufferStack.cpp
+++ b/libs/surfaceflinger_client/SharedBufferStack.cpp
@@ -463,6 +463,9 @@
     if (uint32_t(bufferCount) >= SharedBufferStack::NUM_BUFFER_MAX)
         return BAD_VALUE;
 
+    if (uint32_t(bufferCount) < SharedBufferStack::NUM_BUFFER_MIN)
+        return BAD_VALUE;
+
     RWLock::AutoWLock _wr(mLock);
 
     status_t err = ipc(bufferCount);
diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp
index 4d5c0b6..5f42af0 100644
--- a/libs/surfaceflinger_client/Surface.cpp
+++ b/libs/surfaceflinger_client/Surface.cpp
@@ -584,6 +584,9 @@
     case NATIVE_WINDOW_SET_CROP:
         res = dispatch_crop( args );
         break;
+    case NATIVE_WINDOW_SET_BUFFER_COUNT:
+        res = dispatch_set_buffer_count( args );
+        break;
     default:
         res = NAME_NOT_FOUND;
         break;
@@ -607,6 +610,10 @@
     android_native_rect_t const* rect = va_arg(args, android_native_rect_t*);
     return crop( reinterpret_cast<Rect const*>(rect) );
 }
+int Surface::dispatch_set_buffer_count(va_list args) {
+    size_t bufferCount = va_arg(args, size_t);
+    return setBufferCount(bufferCount);
+}
 
 
 void Surface::setUsage(uint32_t reqUsage)
@@ -856,7 +863,7 @@
                 currentBuffer->setIndex(index);
             }
         } else {
-            err = err<0 ? err : NO_MEMORY;
+            err = err<0 ? err : status_t(NO_MEMORY);
         }
     }
     return err;