implement: "Add an ANativeWindow API for SurfaceFlinger to suggest an optimal buffer orientation"

Bug: 4487161
Change-Id: I883f34efe542c2a566d04966f873374f40c50092
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index c29aeca..e0268fa 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -44,10 +44,6 @@
 
 namespace android {
 
-template <typename T> inline T min(T a, T b) {
-    return a<b ? a : b;
-}
-
 // ---------------------------------------------------------------------------
 
 Layer::Layer(SurfaceFlinger* flinger,
@@ -457,13 +453,22 @@
         // FIXME: mPostedDirtyRegion = dirty & bounds
         mPostedDirtyRegion.set(front.w, front.h);
 
-        sp<GraphicBuffer> newFrontBuffer(mActiveBuffer);
-        if ((newFrontBuffer->getWidth()  == front.requested_w &&
-            newFrontBuffer->getHeight() == front.requested_h) ||
-            isFixedSize())
+
+        if ((front.w != front.requested_w) ||
+            (front.h != front.requested_h))
         {
-            if ((front.w != front.requested_w) ||
-                (front.h != front.requested_h))
+            // check that we received a buffer of the right size
+            // (Take the buffer's orientation into account)
+            sp<GraphicBuffer> newFrontBuffer(mActiveBuffer);
+            uint32_t bufWidth  = newFrontBuffer->getWidth();
+            uint32_t bufHeight = newFrontBuffer->getHeight();
+            if (mCurrentTransform & Transform::ROT_90) {
+                swap(bufWidth, bufHeight);
+            }
+
+            if (isFixedSize() ||
+                    (bufWidth == front.requested_w &&
+                    bufHeight == front.requested_h))
             {
                 // Here we pretend the transaction happened by updating the
                 // current and drawing states. Drawing state is only accessed
@@ -483,10 +488,10 @@
 
                 // recompute visible region
                 recomputeVisibleRegions = true;
-            }
 
-            // we now have the correct size, unfreeze the screen
-            mFreezeLock.clear();
+                // we now have the correct size, unfreeze the screen
+                mFreezeLock.clear();
+            }
         }
     }
 }
diff --git a/services/surfaceflinger/SurfaceTextureLayer.cpp b/services/surfaceflinger/SurfaceTextureLayer.cpp
index a586d59..11f61cc 100644
--- a/services/surfaceflinger/SurfaceTextureLayer.cpp
+++ b/services/surfaceflinger/SurfaceTextureLayer.cpp
@@ -52,6 +52,20 @@
     return res;
 }
 
+status_t SurfaceTextureLayer::queueBuffer(int buf, int64_t timestamp,
+        uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
+
+    status_t res = SurfaceTexture::queueBuffer(buf, timestamp,
+            outWidth, outHeight, outTransform);
+
+    sp<Layer> layer(mLayer.promote());
+    if (layer != NULL) {
+        *outTransform = layer->getOrientation();
+    }
+
+    return res;
+}
+
 status_t SurfaceTextureLayer::dequeueBuffer(int *buf,
         uint32_t w, uint32_t h, uint32_t format, uint32_t usage) {
 
diff --git a/services/surfaceflinger/SurfaceTextureLayer.h b/services/surfaceflinger/SurfaceTextureLayer.h
index 7faff54..29a9cbe 100644
--- a/services/surfaceflinger/SurfaceTextureLayer.h
+++ b/services/surfaceflinger/SurfaceTextureLayer.h
@@ -45,6 +45,9 @@
     virtual status_t setBufferCount(int bufferCount);
 
 protected:
+    virtual status_t queueBuffer(int buf, int64_t timestamp,
+            uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform);
+
     virtual status_t dequeueBuffer(int *buf, uint32_t w, uint32_t h,
             uint32_t format, uint32_t usage);
 };
diff --git a/services/surfaceflinger/Transform.cpp b/services/surfaceflinger/Transform.cpp
index 4cedcbf..24d5f9a 100644
--- a/services/surfaceflinger/Transform.cpp
+++ b/services/surfaceflinger/Transform.cpp
@@ -20,6 +20,7 @@
 #include <utils/String8.h>
 #include <ui/Region.h>
 
+#include "clz.h"
 #include "Transform.h"
 
 // ---------------------------------------------------------------------------
@@ -28,42 +29,6 @@
 
 // ---------------------------------------------------------------------------
 
-template <typename T>
-static inline T min(T a, T b) {
-    return a<b ? a : b;
-}
-template <typename T>
-static inline T min(T a, T b, T c) {
-    return min(a, min(b, c));
-}
-template <typename T>
-static inline T min(T a, T b, T c, T d) {
-    return min(a, b, min(c, d));
-}
-
-template <typename T>
-static inline T max(T a, T b) {
-    return a>b ? a : b;
-}
-template <typename T>
-static inline T max(T a, T b, T c) {
-    return max(a, max(b, c));
-}
-template <typename T>
-static inline T max(T a, T b, T c, T d) {
-    return max(a, b, max(c, d));
-}
-
-template <typename T>
-static inline
-void swap(T& a, T& b) {
-    T t(a);
-    a = b;
-    b = t;
-}
-
-// ---------------------------------------------------------------------------
-
 Transform::Transform() {
     reset();
 }
diff --git a/services/surfaceflinger/clz.h b/services/surfaceflinger/clz.h
index ca44555..a4c5262 100644
--- a/services/surfaceflinger/clz.h
+++ b/services/surfaceflinger/clz.h
@@ -24,6 +24,41 @@
     return __builtin_clz(x);
 }
 
+template <typename T>
+static inline T min(T a, T b) {
+    return a<b ? a : b;
+}
+template <typename T>
+static inline T min(T a, T b, T c) {
+    return min(a, min(b, c));
+}
+template <typename T>
+static inline T min(T a, T b, T c, T d) {
+    return min(a, b, min(c, d));
+}
+
+template <typename T>
+static inline T max(T a, T b) {
+    return a>b ? a : b;
+}
+template <typename T>
+static inline T max(T a, T b, T c) {
+    return max(a, max(b, c));
+}
+template <typename T>
+static inline T max(T a, T b, T c, T d) {
+    return max(a, b, max(c, d));
+}
+
+template <typename T>
+static inline
+void swap(T& a, T& b) {
+    T t(a);
+    a = b;
+    b = t;
+}
+
+
 }; // namespace android
 
 #endif /* ANDROID_SURFACE_FLINGER_CLZ_H */