Merge "CpuConsumer: lock buffers that could be YUV as ycbcr" into lmp-mr1-dev
diff --git a/include/gui/CpuConsumer.h b/include/gui/CpuConsumer.h
index 6f4c2ec..4c6822a 100644
--- a/include/gui/CpuConsumer.h
+++ b/include/gui/CpuConsumer.h
@@ -54,8 +54,12 @@
         uint32_t    scalingMode;
         int64_t     timestamp;
         uint64_t    frameNumber;
-        // Values below are only valid when using
-        // HAL_PIXEL_FORMAT_YCbCr_420_888, in which case LockedBuffer::data
+        // this is the same as format, except for formats that are compatible with
+        // a flexible format (e.g. HAL_PIXEL_FORMAT_YCbCr_420_888). In the latter
+        // case this contains that flexible format
+        PixelFormat flexFormat;
+        // Values below are only valid when using HAL_PIXEL_FORMAT_YCbCr_420_888
+        // or compatible format, in which case LockedBuffer::data
         // contains the Y channel, and stride is the Y channel stride. For other
         // formats, these will all be 0.
         uint8_t    *dataCb;
diff --git a/libs/gui/CpuConsumer.cpp b/libs/gui/CpuConsumer.cpp
index cefd7f1..c541ff4 100644
--- a/libs/gui/CpuConsumer.cpp
+++ b/libs/gui/CpuConsumer.cpp
@@ -67,6 +67,34 @@
     return mConsumer->setDefaultBufferFormat(defaultFormat);
 }
 
+static bool isPossiblyYUV(PixelFormat format) {
+    switch ((int)format) {
+        case HAL_PIXEL_FORMAT_RGBA_8888:
+        case HAL_PIXEL_FORMAT_RGBX_8888:
+        case HAL_PIXEL_FORMAT_RGB_888:
+        case HAL_PIXEL_FORMAT_RGB_565:
+        case HAL_PIXEL_FORMAT_BGRA_8888:
+        case HAL_PIXEL_FORMAT_sRGB_A_8888:
+        case HAL_PIXEL_FORMAT_sRGB_X_8888:
+        case HAL_PIXEL_FORMAT_Y8:
+        case HAL_PIXEL_FORMAT_Y16:
+        case HAL_PIXEL_FORMAT_RAW16: // same as HAL_PIXEL_FORMAT_RAW_SENSOR
+        case HAL_PIXEL_FORMAT_RAW10:
+        case HAL_PIXEL_FORMAT_RAW_OPAQUE:
+        case HAL_PIXEL_FORMAT_BLOB:
+        case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
+            return false;
+
+        case HAL_PIXEL_FORMAT_YV12:
+        case HAL_PIXEL_FORMAT_YCbCr_420_888:
+        case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+        case HAL_PIXEL_FORMAT_YCbCr_422_I:
+        default:
+            return true;
+    }
+}
+
 status_t CpuConsumer::lockNextBuffer(LockedBuffer *nativeBuffer) {
     status_t err;
 
@@ -96,59 +124,51 @@
     void *bufferPointer = NULL;
     android_ycbcr ycbcr = android_ycbcr();
 
-    if (b.mFence.get()) {
-        if (mSlots[buf].mGraphicBuffer->getPixelFormat() ==
-                HAL_PIXEL_FORMAT_YCbCr_420_888) {
+    PixelFormat format = mSlots[buf].mGraphicBuffer->getPixelFormat();
+    PixelFormat flexFormat = format;
+    if (isPossiblyYUV(format)) {
+        if (b.mFence.get()) {
             err = mSlots[buf].mGraphicBuffer->lockAsyncYCbCr(
                 GraphicBuffer::USAGE_SW_READ_OFTEN,
                 b.mCrop,
                 &ycbcr,
                 b.mFence->dup());
-
-            if (err != OK) {
-                CC_LOGE("Unable to lock YCbCr buffer for CPU reading: %s (%d)",
-                        strerror(-err), err);
-                return err;
-            }
-            bufferPointer = ycbcr.y;
         } else {
+            err = mSlots[buf].mGraphicBuffer->lockYCbCr(
+                GraphicBuffer::USAGE_SW_READ_OFTEN,
+                b.mCrop,
+                &ycbcr);
+        }
+        if (err == OK) {
+            bufferPointer = ycbcr.y;
+            flexFormat = HAL_PIXEL_FORMAT_YCbCr_420_888;
+            if (format != HAL_PIXEL_FORMAT_YCbCr_420_888) {
+                CC_LOGV("locking buffer of format %#x as flex YUV", format);
+            }
+        } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
+            CC_LOGE("Unable to lock YCbCr buffer for CPU reading: %s (%d)",
+                    strerror(-err), err);
+            return err;
+        }
+    }
+
+    if (bufferPointer == NULL) { // not flexible YUV
+        if (b.mFence.get()) {
             err = mSlots[buf].mGraphicBuffer->lockAsync(
                 GraphicBuffer::USAGE_SW_READ_OFTEN,
                 b.mCrop,
                 &bufferPointer,
                 b.mFence->dup());
-
-            if (err != OK) {
-                CC_LOGE("Unable to lock buffer for CPU reading: %s (%d)",
-                        strerror(-err), err);
-                return err;
-            }
-        }
-    } else {
-        if (mSlots[buf].mGraphicBuffer->getPixelFormat() ==
-                HAL_PIXEL_FORMAT_YCbCr_420_888) {
-            err = mSlots[buf].mGraphicBuffer->lockYCbCr(
-                GraphicBuffer::USAGE_SW_READ_OFTEN,
-                b.mCrop,
-                &ycbcr);
-
-            if (err != OK) {
-                CC_LOGE("Unable to lock YCbCr buffer for CPU reading: %s (%d)",
-                        strerror(-err), err);
-                return err;
-            }
-            bufferPointer = ycbcr.y;
         } else {
             err = mSlots[buf].mGraphicBuffer->lock(
                 GraphicBuffer::USAGE_SW_READ_OFTEN,
                 b.mCrop,
                 &bufferPointer);
-
-            if (err != OK) {
-                CC_LOGE("Unable to lock buffer for CPU reading: %s (%d)",
-                        strerror(-err), err);
-                return err;
-            }
+        }
+        if (err != OK) {
+            CC_LOGE("Unable to lock buffer for CPU reading: %s (%d)",
+                    strerror(-err), err);
+            return err;
         }
     }
 
@@ -170,7 +190,8 @@
             reinterpret_cast<uint8_t*>(bufferPointer);
     nativeBuffer->width  = mSlots[buf].mGraphicBuffer->getWidth();
     nativeBuffer->height = mSlots[buf].mGraphicBuffer->getHeight();
-    nativeBuffer->format = mSlots[buf].mGraphicBuffer->getPixelFormat();
+    nativeBuffer->format = format;
+    nativeBuffer->flexFormat = flexFormat;
     nativeBuffer->stride = (ycbcr.y != NULL) ?
             ycbcr.ystride :
             mSlots[buf].mGraphicBuffer->getStride();