added the notion of fixed-size buffers

the new native_window_set_buffers_geometry allows
to specify a size and format for all buffers to be
dequeued. the buffer will be scalled to the window's
size.

Change-Id: I2c378b85c88d29cdd827a5f319d5c704d79ba381
diff --git a/include/private/surfaceflinger/SharedBufferStack.h b/include/private/surfaceflinger/SharedBufferStack.h
index de54870..ea8391d 100644
--- a/include/private/surfaceflinger/SharedBufferStack.h
+++ b/include/private/surfaceflinger/SharedBufferStack.h
@@ -279,7 +279,8 @@
     ssize_t retireAndLock();
     status_t unlock(int buffer);
     void setStatus(status_t status);
-    status_t reallocate();
+    status_t reallocateAll();
+    status_t reallocateAllExcept(int buffer);
     status_t assertReallocate(int buffer);
     int32_t getQueuedCount() const;
     Region getDirtyRegion(int buffer) const;
diff --git a/include/surfaceflinger/ISurface.h b/include/surfaceflinger/ISurface.h
index 9476686..18e7950 100644
--- a/include/surfaceflinger/ISurface.h
+++ b/include/surfaceflinger/ISurface.h
@@ -53,7 +53,8 @@
 public: 
     DECLARE_META_INTERFACE(Surface);
 
-    virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, int usage) = 0; 
+    virtual sp<GraphicBuffer> requestBuffer(int bufferIdx,
+            uint32_t w, uint32_t h, uint32_t format, uint32_t usage) = 0;
     virtual status_t setBufferCount(int bufferCount) = 0;
     
     class BufferHeap {
diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h
index e4d60af..77e4a61 100644
--- a/include/surfaceflinger/Surface.h
+++ b/include/surfaceflinger/Surface.h
@@ -36,6 +36,7 @@
 
 // ---------------------------------------------------------------------------
 
+class GraphicBuffer;
 class GraphicBufferMapper;
 class IOMX;
 class Rect;
@@ -213,12 +214,14 @@
     int  dispatch_disconnect(va_list args);
     int  dispatch_crop(va_list args);
     int  dispatch_set_buffer_count(va_list args);
+    int  dispatch_set_buffers_geometry(va_list args);
     
     void setUsage(uint32_t reqUsage);
     int  connect(int api);
     int  disconnect(int api);
     int  crop(Rect const* rect);
     int  setBufferCount(int bufferCount);
+    int  setBuffersGeometry(int w, int h, int format);
 
     /*
      *  private stuff...
@@ -231,12 +234,34 @@
     inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; }
     inline GraphicBufferMapper& getBufferMapper() { return mBufferMapper; }
 
-    status_t getBufferLocked(int index, int usage);
+    status_t getBufferLocked(int index,
+            uint32_t w, uint32_t h, uint32_t format, uint32_t usage);
     int getBufferIndex(const sp<GraphicBuffer>& buffer) const;
 
-    uint32_t getUsage() const;
-    int      getConnectedApi() const;
+    int getConnectedApi() const;
     
+    bool needNewBuffer(int bufIdx,
+            uint32_t *pWidth, uint32_t *pHeight,
+            uint32_t *pFormat, uint32_t *pUsage) const;
+
+    class BufferInfo {
+        uint32_t mWidth;
+        uint32_t mHeight;
+        uint32_t mFormat;
+        uint32_t mUsage;
+        mutable uint32_t mDirty;
+        enum {
+            GEOMETRY = 0x01
+        };
+    public:
+        BufferInfo();
+        void set(uint32_t w, uint32_t h, uint32_t format);
+        void set(uint32_t usage);
+        void get(uint32_t *pWidth, uint32_t *pHeight,
+                uint32_t *pFormat, uint32_t *pUsage) const;
+        bool validateBuffer(const sp<GraphicBuffer>& buffer) const;
+    };
+
     // constants
     sp<SurfaceComposerClient>   mClient;
     sp<ISurface>                mSurface;
@@ -249,13 +274,12 @@
 
     // protected by mSurfaceLock
     Rect                        mSwapRectangle;
-    uint32_t                    mUsage;
     int                         mConnected;
     Rect                        mNextBufferCrop;
+    BufferInfo                  mBufferInfo;
     
     // protected by mSurfaceLock. These are also used from lock/unlock
     // but in that case, they must be called form the same thread.
-    sp<GraphicBuffer>           mBuffers[2];
     mutable Region              mDirtyRegion;
 
     // must be used from the lock/unlock thread
@@ -264,6 +288,9 @@
     mutable Region              mOldDirtyRegion;
     bool                        mReserved;
 
+    // only used from dequeueBuffer()
+    Vector< sp<GraphicBuffer> > mBuffers;
+
     // query() must be called from dequeueBuffer() thread
     uint32_t                    mWidth;
     uint32_t                    mHeight;
diff --git a/include/ui/egl/android_natives.h b/include/ui/egl/android_natives.h
index b44901f..171f3df 100644
--- a/include/ui/egl/android_natives.h
+++ b/include/ui/egl/android_natives.h
@@ -82,6 +82,7 @@
     NATIVE_WINDOW_DISCONNECT,
     NATIVE_WINDOW_SET_CROP,
     NATIVE_WINDOW_SET_BUFFER_COUNT,
+    NATIVE_WINDOW_SET_BUFFERS_GEOMETRY,
 };
 
 /* parameter for NATIVE_WINDOW_[DIS]CONNECT */
@@ -192,6 +193,7 @@
      *     NATIVE_WINDOW_DISCONNECT
      *     NATIVE_WINDOW_SET_CROP
      *     NATIVE_WINDOW_SET_BUFFER_COUNT
+     *     NATIVE_WINDOW_SET_BUFFERS_GEOMETRY
      *  
      */
     
@@ -273,6 +275,25 @@
     return window->perform(window, NATIVE_WINDOW_SET_BUFFER_COUNT, bufferCount);
 }
 
+/*
+ * native_window_set_buffers_geometry(..., int w, int h, int format)
+ * All buffers dequeued after this call will have the geometry specified.
+ * In particular, all buffers will have a fixed-size, independent form the
+ * native-window size. They will be appropriately scaled to the window-size
+ * upon composition.
+ *
+ * If all parameters are 0, the normal behavior is restored. That is,
+ * dequeued buffers following this call will be sized to the window's size.
+ *
+ */
+static inline int native_window_set_buffers_geometry(
+        android_native_window_t* window,
+        int w, int h, int format)
+{
+    return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_GEOMETRY,
+            w, h, format);
+}
+
 // ---------------------------------------------------------------------------
 
 /* FIXME: this is legacy for pixmaps */