SurfaceTextureClient: support for application buffer dimensions

Add a new API native_window_set_buffers_user_dimensions to allow native
applications to override the native window size for the default buffer size.
This has lower precedence than the existing
native_window_set_buffers_dimensions and allows the two to co-exist.

Change-Id: Ie73590e1c94ef0dadbce500bd0941dfabbcace3c
diff --git a/include/gui/SurfaceTextureClient.h b/include/gui/SurfaceTextureClient.h
index 8c1e505..c0e90b3 100644
--- a/include/gui/SurfaceTextureClient.h
+++ b/include/gui/SurfaceTextureClient.h
@@ -73,6 +73,7 @@
     int dispatchSetBufferCount(va_list args);
     int dispatchSetBuffersGeometry(va_list args);
     int dispatchSetBuffersDimensions(va_list args);
+    int dispatchSetBuffersUserDimensions(va_list args);
     int dispatchSetBuffersFormat(va_list args);
     int dispatchSetScalingMode(va_list args);
     int dispatchSetBuffersTransform(va_list args);
@@ -95,6 +96,7 @@
     virtual int disconnect(int api);
     virtual int setBufferCount(int bufferCount);
     virtual int setBuffersDimensions(int w, int h);
+    virtual int setBuffersUserDimensions(int w, int h);
     virtual int setBuffersFormat(int format);
     virtual int setScalingMode(int mode);
     virtual int setBuffersTransform(int transform);
@@ -157,13 +159,23 @@
     // buffer that gets queued. It is set by calling setTransform.
     uint32_t mTransform;
 
-    // mDefaultWidth is default width of the window, regardless of the
-    // native_window_set_buffers_dimensions call
-    uint32_t mDefaultWidth;
+     // mDefaultWidth is default width of the buffers, regardless of the
+     // native_window_set_buffers_dimensions call.
+     uint32_t mDefaultWidth;
 
-    // mDefaultHeight is default width of the window, regardless of the
-    // native_window_set_buffers_dimensions call
-    uint32_t mDefaultHeight;
+     // mDefaultHeight is default height of the buffers, regardless of the
+     // native_window_set_buffers_dimensions call.
+     uint32_t mDefaultHeight;
+
+     // mUserWidth, if non-zero, is an application-specified override
+     // of mDefaultWidth.  This is lower priority than the width set by
+     // native_window_set_buffers_dimensions.
+     uint32_t mUserWidth;
+
+     // mUserHeight, if non-zero, is an application-specified override
+     // of mDefaultHeight.  This is lower priority than the height set
+     // by native_window_set_buffers_dimensions.
+     uint32_t mUserHeight;
 
     // mTransformHint is the transform probably applied to buffers of this
     // window. this is only a hint, actual transform may differ.
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index 592658b..aa114ed 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -80,6 +80,8 @@
     mTransform = 0;
     mDefaultWidth = 0;
     mDefaultHeight = 0;
+    mUserWidth = 0;
+    mUserHeight = 0;
     mTransformHint = 0;
     mConnectedToCpu = false;
 }
@@ -159,7 +161,9 @@
     ALOGV("SurfaceTextureClient::dequeueBuffer");
     Mutex::Autolock lock(mMutex);
     int buf = -1;
-    status_t result = mSurfaceTexture->dequeueBuffer(&buf, mReqWidth, mReqHeight,
+    int reqW = mReqWidth ? mReqWidth : mUserWidth;
+    int reqH = mReqHeight ? mReqHeight : mUserHeight;
+    status_t result = mSurfaceTexture->dequeueBuffer(&buf, reqW, reqH,
             mReqFormat, mReqUsage);
     if (result < 0) {
         ALOGV("dequeueBuffer: ISurfaceTexture::dequeueBuffer(%d, %d, %d, %d)"
@@ -269,10 +273,10 @@
                 *value = NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT;
                 return NO_ERROR;
             case NATIVE_WINDOW_DEFAULT_WIDTH:
-                *value = mDefaultWidth;
+                *value = mUserWidth ? mUserWidth : mDefaultWidth;
                 return NO_ERROR;
             case NATIVE_WINDOW_DEFAULT_HEIGHT:
-                *value = mDefaultHeight;
+                *value = mUserHeight ? mUserHeight : mDefaultHeight;
                 return NO_ERROR;
             case NATIVE_WINDOW_TRANSFORM_HINT:
                 *value = mTransformHint;
@@ -313,6 +317,9 @@
     case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS:
         res = dispatchSetBuffersDimensions(args);
         break;
+    case NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS:
+        res = dispatchSetBuffersUserDimensions(args);
+        break;
     case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
         res = dispatchSetBuffersFormat(args);
         break;
@@ -380,6 +387,12 @@
     return setBuffersDimensions(w, h);
 }
 
+int SurfaceTextureClient::dispatchSetBuffersUserDimensions(va_list args) {
+    int w = va_arg(args, int);
+    int h = va_arg(args, int);
+    return setBuffersUserDimensions(w, h);
+}
+
 int SurfaceTextureClient::dispatchSetBuffersFormat(va_list args) {
     int f = va_arg(args, int);
     return setBuffersFormat(f);
@@ -504,6 +517,24 @@
     return NO_ERROR;
 }
 
+int SurfaceTextureClient::setBuffersUserDimensions(int w, int h)
+{
+    ATRACE_CALL();
+    ALOGV("SurfaceTextureClient::setBuffersUserDimensions");
+
+    if (w<0 || h<0)
+        return BAD_VALUE;
+
+    if ((w && !h) || (!w && h))
+        return BAD_VALUE;
+
+    Mutex::Autolock lock(mMutex);
+    mUserWidth = w;
+    mUserHeight = h;
+    mCrop.clear();
+    return NO_ERROR;
+}
+
 int SurfaceTextureClient::setBuffersFormat(int format)
 {
     ALOGV("SurfaceTextureClient::setBuffersFormat");