Merge "Fix unused struct in VkGraphicsPipelineCreateInfo" into tm-dev
diff --git a/shared/OpenglCodecCommon/GLClientState.cpp b/shared/OpenglCodecCommon/GLClientState.cpp
index 3e32bbf..a6dbbd6 100644
--- a/shared/OpenglCodecCommon/GLClientState.cpp
+++ b/shared/OpenglCodecCommon/GLClientState.cpp
@@ -1203,7 +1203,7 @@
             pack ? 0 : m_pixelStore.unpack_skip_images);
 }
 
-size_t GLClientState::pboNeededDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack) const
+size_t GLClientState::pboNeededDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack, int ignoreTrailing) const
 {
     if (width <= 0 || height <= 0 || depth <= 0) return 0;
 
@@ -1231,7 +1231,8 @@
             pack ? 0 : m_pixelStore.unpack_image_height,
             pack ? m_pixelStore.pack_skip_pixels : m_pixelStore.unpack_skip_pixels,
             pack ? m_pixelStore.pack_skip_rows : m_pixelStore.unpack_skip_rows,
-            pack ? 0 : m_pixelStore.unpack_skip_images);
+            pack ? 0 : m_pixelStore.unpack_skip_images,
+            ignoreTrailing);
 }
 
 
diff --git a/shared/OpenglCodecCommon/GLClientState.h b/shared/OpenglCodecCommon/GLClientState.h
index 0639962..308b737 100644
--- a/shared/OpenglCodecCommon/GLClientState.h
+++ b/shared/OpenglCodecCommon/GLClientState.h
@@ -332,7 +332,7 @@
     void setLastEncodedBufferBind(GLenum target, GLuint id);
 
     size_t pixelDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack) const;
-    size_t pboNeededDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack) const;
+    size_t pboNeededDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack, int ignoreTrailing = 0) const;
     size_t clearBufferNumElts(GLenum buffer) const;
     void getPackingOffsets2D(GLsizei width, GLsizei height, GLenum format, GLenum type, int* bpp, int* startOffset, int* pixelRowSize, int* totalRowSize, int* skipRows) const;
     void getUnpackingOffsets2D(GLsizei width, GLsizei height, GLenum format, GLenum type, int* bpp, int* startOffset, int* pixelRowSize, int* totalRowSize, int* skipRows) const;
diff --git a/shared/OpenglCodecCommon/GLESTextureUtils.cpp b/shared/OpenglCodecCommon/GLESTextureUtils.cpp
index 87d6312..0fa0e23 100644
--- a/shared/OpenglCodecCommon/GLESTextureUtils.cpp
+++ b/shared/OpenglCodecCommon/GLESTextureUtils.cpp
@@ -1,5 +1,7 @@
 #include "GLESTextureUtils.h"
 
+#include <algorithm>
+
 #include "glUtils.h"
 #include "etc.h"
 #include "astc-codec.h"
@@ -254,7 +256,8 @@
         int unpackSkipRows,
         int unpackSkipImages,
         int* start,
-        int* end) {
+        int* end,
+        int ignoreTrailing) {
 
     GLsizei inputWidth = (unpackRowLength == 0) ? width : unpackRowLength;
     GLsizei inputPitch = computePitch(inputWidth, format, type, unpackAlignment);
@@ -263,7 +266,17 @@
     ALOGV("%s: input idim %d %d %d w p h %d %d %d:", __FUNCTION__, width, height, depth, inputWidth, inputPitch, inputHeight);
 
     int startVal = computePackingOffset(format, type, inputWidth, inputHeight, unpackAlignment, unpackSkipPixels, unpackSkipRows, unpackSkipImages);
-    int endVal = startVal + inputPitch * inputHeight * depth;
+    int endVal;
+    if (ignoreTrailing) {
+        // The last row needs to have just enough data per spec, and could
+        // ignore alignment.
+        // b/223402256
+        endVal = startVal + inputPitch * inputHeight * (depth - 1);
+        endVal += inputPitch * (std::min(height, inputHeight) - 1);
+        endVal += computePitch(std::min(width, inputWidth), format, type, 1);
+    } else {
+        endVal = startVal + inputPitch * inputHeight * depth;
+    }
 
     if (start) *start = startVal;
     if (end) *end = endVal;
@@ -293,7 +306,8 @@
             unpackSkipRows,
             unpackSkipImages,
             &start,
-            &end);
+            &end,
+            0);
     return end;
 }
 
@@ -305,7 +319,8 @@
         int unpackImageHeight,
         int unpackSkipPixels,
         int unpackSkipRows,
-        int unpackSkipImages) {
+        int unpackSkipImages,
+        int ignoreTrailing) {
 
     int start, end;
     computeTextureStartEnd(
@@ -318,7 +333,8 @@
             unpackSkipRows,
             unpackSkipImages,
             &start,
-            &end);
+            &end,
+            ignoreTrailing);
     return end - start;
 }
 
diff --git a/shared/OpenglCodecCommon/GLESTextureUtils.h b/shared/OpenglCodecCommon/GLESTextureUtils.h
index 0b636ac..45af27e 100644
--- a/shared/OpenglCodecCommon/GLESTextureUtils.h
+++ b/shared/OpenglCodecCommon/GLESTextureUtils.h
@@ -5,6 +5,11 @@
 
 namespace GLESTextureUtils {
 
+// By spec, the buffer is only required to provide just enough data. The
+// last row does not have to fill unpackRowLength. But our decoder is
+// written to always read full row. So we add "ignoreTrailing" here. When
+// ignoreTrailing == 1 we compute the real size as defined by spec. When
+// ignoreTrailing == 0 we compute the size used by decoder/encoder.
 void computeTextureStartEnd(
         GLsizei width, GLsizei height, GLsizei depth,
         GLenum format, GLenum type,
@@ -15,7 +20,8 @@
         int unpackSkipRows,
         int unpackSkipImages,
         int* start,
-        int* end);
+        int* end,
+        int ignoreTrailing);
 
 int computeTotalImageSize(
         GLsizei width, GLsizei height, GLsizei depth,
@@ -35,7 +41,8 @@
         int unpackImageHeight,
         int unpackSkipPixels,
         int unpackSkipRows,
-        int unpackSkipImages);
+        int unpackSkipImages,
+        int ignoreTrailing);
 
 // Writes out |height| offsets for glReadPixels to read back
 // data in separate rows of pixels. Returns:
diff --git a/system/GLESv2_enc/GL2Encoder.cpp b/system/GLESv2_enc/GL2Encoder.cpp
index 63b4ff4..65048cf 100755
--- a/system/GLESv2_enc/GL2Encoder.cpp
+++ b/system/GLESv2_enc/GL2Encoder.cpp
@@ -2721,10 +2721,9 @@
     }
 
     // If unpack buffer is nonzero, verify buffer data fits and is evenly divisible by the type.
-
     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
                  ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER) &&
-                 (state->pboNeededDataSize(width, height, 1, format, type, 0) + (uintptr_t)pixels >
+                 (state->pboNeededDataSize(width, height, 1, format, type, 0, 1) + (uintptr_t)pixels >
                   ctx->getBufferData(GL_PIXEL_UNPACK_BUFFER)->m_size),
                  GL_INVALID_OPERATION);
     SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
diff --git a/system/vulkan_enc/AndroidHardwareBuffer.cpp b/system/vulkan_enc/AndroidHardwareBuffer.cpp
index 40360a2..c49693d 100644
--- a/system/vulkan_enc/AndroidHardwareBuffer.cpp
+++ b/system/vulkan_enc/AndroidHardwareBuffer.cpp
@@ -75,8 +75,46 @@
         if (!(desc.usage & (gpu_usage))) {
             return VK_ERROR_INVALID_EXTERNAL_HANDLE;
         }
-
-        ahbFormatProps->format = vk_format_from_android(desc.format);
+        switch(desc.format) {
+            case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
+                  ahbFormatProps->format = VK_FORMAT_R8G8B8A8_UNORM;
+                  break;
+            case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
+                  ahbFormatProps->format = VK_FORMAT_R8G8B8A8_UNORM;
+                  break;
+            case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
+                  ahbFormatProps->format = VK_FORMAT_R8G8B8_UNORM;
+                  break;
+            case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
+                  ahbFormatProps->format = VK_FORMAT_R5G6B5_UNORM_PACK16;
+                  break;
+            case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
+                  ahbFormatProps->format = VK_FORMAT_R16G16B16A16_SFLOAT;
+                  break;
+            case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
+                  ahbFormatProps->format = VK_FORMAT_A2B10G10R10_UNORM_PACK32;
+                  break;
+            case AHARDWAREBUFFER_FORMAT_D16_UNORM:
+                  ahbFormatProps->format = VK_FORMAT_D16_UNORM;
+                  break;
+            case AHARDWAREBUFFER_FORMAT_D24_UNORM:
+                  ahbFormatProps->format = VK_FORMAT_X8_D24_UNORM_PACK32;
+                  break;
+            case AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT:
+                  ahbFormatProps->format = VK_FORMAT_D24_UNORM_S8_UINT;
+                  break;
+            case AHARDWAREBUFFER_FORMAT_D32_FLOAT:
+                  ahbFormatProps->format = VK_FORMAT_D32_SFLOAT;
+                  break;
+            case AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT:
+                  ahbFormatProps->format = VK_FORMAT_D32_SFLOAT_S8_UINT;
+                  break;
+            case AHARDWAREBUFFER_FORMAT_S8_UINT:
+                  ahbFormatProps->format = VK_FORMAT_S8_UINT;
+                  break;
+            default:
+                  ahbFormatProps->format = VK_FORMAT_UNDEFINED;
+        }
         ahbFormatProps->externalFormat = desc.format;
 
         // The formatFeatures member must include
diff --git a/system/vulkan_enc/ResourceTracker.cpp b/system/vulkan_enc/ResourceTracker.cpp
index 3f5e2d0..6cc7010 100644
--- a/system/vulkan_enc/ResourceTracker.cpp
+++ b/system/vulkan_enc/ResourceTracker.cpp
@@ -362,6 +362,10 @@
         VkDeviceSize currentBackingSize = 0;
         bool baseRequirementsKnown = false;
         VkMemoryRequirements baseRequirements;
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+        bool hasExternalFormat = false;
+        unsigned androidFormat = 0;
+#endif
 #ifdef VK_USE_PLATFORM_FUCHSIA
         bool isSysmemBackedMemory = false;
 #endif
@@ -5055,6 +5059,11 @@
         info.createInfo = *pCreateInfo;
         info.createInfo.pNext = nullptr;
 
+        if (extFormatAndroidPtr && extFormatAndroidPtr->externalFormat) {
+            info.hasExternalFormat = true;
+            info.androidFormat = extFormatAndroidPtr->externalFormat;
+        }
+
         if (supportsCreateResourcesWithRequirements()) {
             info.baseRequirementsKnown = true;
         }
@@ -5192,7 +5201,8 @@
             vk_find_struct<VkSamplerYcbcrConversionInfo>(pCreateInfo);
         if (samplerYcbcrConversionInfo) {
             if (samplerYcbcrConversionInfo->conversion != VK_YCBCR_CONVERSION_DO_NOTHING) {
-                localVkSamplerYcbcrConversionInfo = vk_make_orphan_copy(*samplerYcbcrConversionInfo);
+                localVkSamplerYcbcrConversionInfo =
+                    vk_make_orphan_copy(*samplerYcbcrConversionInfo);
                 vk_append_struct(&structChainIter, &localVkSamplerYcbcrConversionInfo);
             }
         }
@@ -7575,14 +7585,24 @@
         (void)input_result;
 
         VkImageViewCreateInfo localCreateInfo = vk_make_orphan_copy(*pCreateInfo);
+        vk_struct_chain_iterator structChainIter = vk_make_chain_iterator(&localCreateInfo);
 
 #if defined(VK_USE_PLATFORM_ANDROID_KHR) || defined(__linux__)
-        const VkExternalFormatANDROID* extFormatAndroidPtr =
-            vk_find_struct<VkExternalFormatANDROID>(pCreateInfo);
-        if (extFormatAndroidPtr) {
-            if (extFormatAndroidPtr->externalFormat) {
-                localCreateInfo.format =
-                    vk_format_from_android(extFormatAndroidPtr->externalFormat);
+        if (pCreateInfo->format == VK_FORMAT_UNDEFINED) {
+            AutoLock<RecursiveLock> lock(mLock);
+
+            auto it = info_VkImage.find(pCreateInfo->image);
+            if (it != info_VkImage.end() && it->second.hasExternalFormat) {
+                localCreateInfo.format = vk_format_from_android(it->second.androidFormat);
+            }
+        }
+        VkSamplerYcbcrConversionInfo localVkSamplerYcbcrConversionInfo;
+        const VkSamplerYcbcrConversionInfo* samplerYcbcrConversionInfo =
+            vk_find_struct<VkSamplerYcbcrConversionInfo>(pCreateInfo);
+        if (samplerYcbcrConversionInfo) {
+            if (samplerYcbcrConversionInfo->conversion != VK_YCBCR_CONVERSION_DO_NOTHING) {
+                localVkSamplerYcbcrConversionInfo = vk_make_orphan_copy(*samplerYcbcrConversionInfo);
+                vk_append_struct(&structChainIter, &localVkSamplerYcbcrConversionInfo);
             }
         }
 #endif