From dd98b13a9d5944a14ea739fc21b265ccac437730 Mon Sep 17 00:00:00 2001
From: halx99 <halx99@live.com>
Date: Tue, 20 Oct 2020 23:27:20 +0800
Subject: [PATCH] Refine pixel format a. make RGB565, RGB5A1 identical between
 GL and MTL backend b. make texture internal format compatible on GLES-2.0
 ONLY GPU devices

---
 cocos/renderer/backend/TextureUtils.cpp   | 89 ++++++++++-------------
 cocos/renderer/backend/TextureUtils.h     |  2 +-
 cocos/renderer/backend/metal/UtilsMTL.mm  |  2 +-
 cocos/renderer/backend/opengl/UtilsGL.cpp |  4 +-
 4 files changed, 44 insertions(+), 53 deletions(-)

diff --git a/cocos/renderer/backend/TextureUtils.cpp b/cocos/renderer/backend/TextureUtils.cpp
index 697ffa02af..2036603073 100644
--- a/cocos/renderer/backend/TextureUtils.cpp
+++ b/cocos/renderer/backend/TextureUtils.cpp
@@ -204,8 +204,9 @@ namespace backend { namespace PixelFormatUtils {
         }
     }
     
+#if 0 // unused
     // IIIIIIIIAAAAAAAA -> BBBBBGGG GGGRRRR
-    void convertLA8ToBGR565(const unsigned char* data, size_t dataLen, unsigned char* outData)
+    static void convertLA8ToBGR565(const unsigned char* data, size_t dataLen, unsigned char* outData)
     {
         uint16_t* out16 = (uint16_t*)outData;
         for (ssize_t i = 0, l = dataLen - 1; i < l; i += 2)
@@ -217,7 +218,7 @@ namespace backend { namespace PixelFormatUtils {
     }
     
     // IIIIIIIIAAAAAAAA -> BBBBBGGG GGRRRRRA
-    void convertLA8ToBGR5A1(const unsigned char* data, size_t dataLen, unsigned char* outData)
+    static void convertLA8ToBGR5A1(const unsigned char* data, size_t dataLen, unsigned char* outData)
     {
         uint16_t* out16 = (uint16_t*)outData;
         for (ssize_t i = 0, l = dataLen - 1; i < l; i += 2)
@@ -228,9 +229,9 @@ namespace backend { namespace PixelFormatUtils {
             | (data[i + 1] & 0x0080) << 8;          //A
         }
     }
-    
+
     // IIIIIIIIAAAAAAAA -> AAAABBBB GGGGRRRR
-    void convertLA8ToABGR4(const unsigned char* data, size_t dataLen, unsigned char* outData)
+    static void convertLA8ToABGR4(const unsigned char* data, size_t dataLen, unsigned char* outData)
     {
         uint16_t* out16 = (uint16_t*)outData;
         for (ssize_t i = 0, l = dataLen - 1; i < l; i += 2)
@@ -241,7 +242,7 @@ namespace backend { namespace PixelFormatUtils {
             | (data[i + 1] & 0x00F0) >> 4;        //A
         }
     }
-    
+#endif
     
     // IIIIIIII -> RRRRRGGGGGBBBBBA
     void convertL8ToRGB5A1(const unsigned char* data, size_t dataLen, unsigned char* outData)
@@ -255,9 +256,10 @@ namespace backend { namespace PixelFormatUtils {
             | 0x0001;                         //A
         }
     }
-    
+
+#if 0 // unused
     /// IIIIIIII -> BBBBBGGG GGRRRRRA
-    void convertL8ToBGR5A1(const unsigned char* data, size_t dataLen, unsigned char* outData)
+    static void convertL8ToBGR5A1(const unsigned char* data, size_t dataLen, unsigned char* outData)
     {
         uint16_t *out16 = (uint16_t*)outData;
         for (size_t i = 0; i < dataLen; ++i)
@@ -270,7 +272,7 @@ namespace backend { namespace PixelFormatUtils {
     }
     
     // IIIIIIIII -> BBBBBGGG GGGRRRRR
-    void convertL8ToBGR565(const unsigned char* data, size_t dataLen, unsigned char* outData)
+    static void convertL8ToBGR565(const unsigned char* data, size_t dataLen, unsigned char* outData)
     {
         uint16_t *out16 = (uint16_t*)outData;
         for (size_t i = 0; i < dataLen; ++i)
@@ -283,7 +285,7 @@ namespace backend { namespace PixelFormatUtils {
     }
     
     // IIIIIIIII -> AAAABBBBB GGGGRRRR
-    void convertL8ToABGR4(const unsigned char* data, size_t dataLen, unsigned char* outData)
+    static void convertL8ToABGR4(const unsigned char* data, size_t dataLen, unsigned char* outData)
     {
         uint16_t *out16 = (uint16_t*)outData;
         for (size_t i = 0; i < dataLen; ++i)
@@ -294,7 +296,8 @@ namespace backend { namespace PixelFormatUtils {
             | 0x000F;
         }
     }
-    
+#endif
+
     // IIIIIIIIAAAAAAAA -> RRRRRGGGGGBBBBBA
     void convertLA8ToRGB5A1(const unsigned char* data, size_t dataLen, unsigned char* outData)
     {
@@ -479,9 +482,9 @@ namespace backend { namespace PixelFormatUtils {
             | 0x01;                          //A
         }
     }
-    
+#if 0 // unused
     // RRRRRRRRGGGGGGGGBBBBBBBB -> BBBBBGGG GGGRRRRR
-    void convertRGB8ToB5G6R5(const unsigned char *data, size_t dataLen, unsigned char *out)
+    static void convertRGB8ToBGR565(const unsigned char *data, size_t dataLen, unsigned char *out)
     {
         uint16_t *outData = (uint16_t*) out;
         for(size_t i = 0;i < dataLen ; i += 3)
@@ -493,7 +496,7 @@ namespace backend { namespace PixelFormatUtils {
     }
     
     // RRRRRRRRGGGGGGGGBBBBBBBB -> BBBBBGGG GGRRRRRA
-    void convertRGB8ToBGR5A1(const unsigned char *data, size_t dataLen, unsigned char *out)
+    static void convertRGB8ToBGR5A1(const unsigned char *data, size_t dataLen, unsigned char *out)
     {
         uint16_t *outData = (uint16_t*) out;
         for(size_t i = 0;i < dataLen ; i += 3)
@@ -505,7 +508,7 @@ namespace backend { namespace PixelFormatUtils {
     }
     
     // RRRRRRRRGGGGGGGGBBBBBBBB -> AAAABBBB GGGGRRRR
-    void convertRGB8ToABGR4(const unsigned char *data, size_t dataLen, unsigned char *out)
+    static void convertRGB8ToABGR4(const unsigned char *data, size_t dataLen, unsigned char *out)
     {
         uint16_t *outData = (uint16_t*) out;
         for(size_t i = 0;i < dataLen ; i += 3)
@@ -516,7 +519,8 @@ namespace backend { namespace PixelFormatUtils {
             0x000F;                                //a
         }
     }
-    
+#endif
+
     // RRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA -> RRRRRGGG GGBBBBBA
     void convertRGBA8ToRGB5A1(const unsigned char* data, size_t dataLen, unsigned char* outData)
     {
@@ -530,8 +534,9 @@ namespace backend { namespace PixelFormatUtils {
         }
     }
     
+#if 0 // unused
     // RRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA -> BBBBBGGG GGGRRRR
-    void convertRGBA8ToBGR565(const unsigned char *data, size_t dataLen, unsigned char *out)
+    static void convertRGBA8ToBGR565(const unsigned char *data, size_t dataLen, unsigned char *out)
     {
         uint16_t *outData = (uint16_t*)out;
         const size_t pixelCnt = dataLen / 4;
@@ -544,7 +549,7 @@ namespace backend { namespace PixelFormatUtils {
     }
 
     // RRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA -> AAAABBBB GGGGRRRR
-    void convertRGBA8ToABGR4(const unsigned char *data, size_t dataLen, unsigned char *out)
+    static void convertRGBA8ToABGR4(const unsigned char *data, size_t dataLen, unsigned char *out)
     {
         uint16_t *outData = (uint16_t*)out;
         for(size_t i=0;i < dataLen; i+=4 )
@@ -557,7 +562,7 @@ namespace backend { namespace PixelFormatUtils {
     }
     
     // RRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA -> BBBBBGGG GGRRRRRA
-    void convertRGBA8ToBGR5A1(const unsigned char *data, size_t dataLen, unsigned char *out)
+    static void convertRGBA8ToBGR5A1(const unsigned char *data, size_t dataLen, unsigned char *out)
     {
         uint16_t *outData = (uint16_t*)out;
         for(size_t i = 0; i < dataLen; i += 4)
@@ -568,7 +573,7 @@ namespace backend { namespace PixelFormatUtils {
             ((data[i + 3] & 0x80) << 8);                  //a
         }
     }
-    
+#endif
     
     void convertRGB5A1ToRGBA8(const unsigned char* data, size_t dataLen, unsigned char* outData)
     {
@@ -585,8 +590,9 @@ namespace backend { namespace PixelFormatUtils {
         }
     }
     
+#if 0 // unused
     // ABBBBBGG GGGRRRRR  -> BBBBBGGG GGRRRRRA
-    void convertRGB5A1ToBGR5A1(const unsigned char *data, size_t dataLen, unsigned char *out)
+    static void convertRGB5A1ToBGR5A1(const unsigned char *data, size_t dataLen, unsigned char *out)
     {
         const size_t pixelLen = dataLen / 2;
         const uint16_t *inData = (uint16_t*) data;
@@ -598,7 +604,7 @@ namespace backend { namespace PixelFormatUtils {
             outData[i] = (pixel >> 1) | ((pixel & 0x0001) << 15);
         }
     }
-    
+#endif    
     
     void convertRGB565ToRGBA8(const unsigned char* data, size_t dataLen, unsigned char* outData)
     {
@@ -615,10 +621,6 @@ namespace backend { namespace PixelFormatUtils {
         }
     }
     
-    // BBBBBGGG GGGRRRRR -> BBBGGG GGGRRRRR
-    // void convertRGB565ToB5G6R5(const unsigned char *data, ssize_t dataLen, unsigned char *out)
-    
-    
     void convertRGBA4ToRGBA8(const unsigned char* data, size_t dataLen, unsigned char* outData)
     {
         uint16_t *inData = (uint16_t*)data;
@@ -635,9 +637,6 @@ namespace backend { namespace PixelFormatUtils {
         
     }
     
-    // AAAABBBBGGGGRRRR -> AAAABBBB GGGGRRRR
-    //void convertRGBA4ToABGR4(const unsigned char *data, ssize_t dataLen, unsigned char *out)
-    
     void convertA8ToRGBA8(const unsigned char* data, size_t dataLen, unsigned char* outData)
     {
         for (size_t i = 0; i < dataLen; i++)
@@ -683,17 +682,17 @@ namespace backend { namespace PixelFormatUtils {
             case PixelFormat::RGB565:
                 *outDataLen = dataLen*2;
                 *outData = (unsigned char*)malloc(sizeof(unsigned char) * (*outDataLen));
-                convertL8ToBGR565(data, dataLen, *outData);
+                convertL8ToRGB565(data, dataLen, *outData);
                 break;
             case PixelFormat::RGBA4:
                 *outDataLen = dataLen * 2;
                 *outData = (unsigned char*)malloc(sizeof(unsigned char) * (*outDataLen));
-                convertL8ToABGR4(data, dataLen, *outData);
+                convertL8ToRGBA4(data, dataLen, *outData);
                 break;
             case PixelFormat::RGB5A1:
                 *outDataLen = dataLen * 2;
                 *outData = (unsigned char*)malloc(sizeof(unsigned char) * (*outDataLen));
-                convertL8ToBGR5A1(data, dataLen, *outData);
+                convertL8ToRGB5A1(data, dataLen, *outData);
                 break;
             case PixelFormat::A8:
                 *outData = (unsigned char*)data;
@@ -736,17 +735,17 @@ namespace backend { namespace PixelFormatUtils {
             case PixelFormat::RGB565:
                 *outDataLen = dataLen;
                 *outData = (unsigned char*)malloc(sizeof(unsigned char) * (*outDataLen));
-                convertLA8ToBGR565(data, dataLen, *outData);
+                convertLA8ToRGB565(data, dataLen, *outData);
                 break;
             case PixelFormat::RGBA4:
                 *outDataLen = dataLen;
                 *outData = (unsigned char*)malloc(sizeof(unsigned char) * (*outDataLen));
-                convertLA8ToABGR4(data, dataLen, *outData);
+                convertLA8ToRGBA4(data, dataLen, *outData);
                 break;
             case PixelFormat::RGB5A1:
                 *outDataLen = dataLen;
                 *outData = (unsigned char*)malloc(sizeof(unsigned char) * (*outDataLen));
-                convertLA8ToBGR5A1(data, dataLen, *outData);
+                convertLA8ToRGB5A1(data, dataLen, *outData);
                 break;
             case PixelFormat::A8:
                 *outDataLen = dataLen/2;
@@ -785,17 +784,17 @@ namespace backend { namespace PixelFormatUtils {
             case PixelFormat::RGB565:
                 *outDataLen = dataLen/3*2;
                 *outData = (unsigned char*)malloc(sizeof(unsigned char) * (*outDataLen));
-                convertRGB8ToB5G6R5(data, dataLen, *outData);
+                convertRGB8ToRGB565(data, dataLen, *outData);
                 break;
             case PixelFormat::RGBA4:
                 *outDataLen = dataLen / 3 * 2;
                 *outData = (unsigned char*)malloc(sizeof(unsigned char) * (*outDataLen));
-                convertRGB8ToABGR4(data, dataLen, *outData);
+                convertRGB8ToRGBA4(data, dataLen, *outData);
                 break;
             case PixelFormat::RGB5A1:
                 *outDataLen = dataLen / 3 * 2;
                 *outData = (unsigned char*)malloc(sizeof(unsigned char) * (*outDataLen));
-                convertRGB8ToBGR5A1(data, dataLen, *outData);
+                convertRGB8ToRGB5A1(data, dataLen, *outData);
                 break;
             case PixelFormat::A8:
                 *outDataLen = dataLen/3;
@@ -839,18 +838,17 @@ namespace backend { namespace PixelFormatUtils {
             case PixelFormat::RGB565:
                 *outDataLen = dataLen/2;
                 *outData = (unsigned char*)malloc(sizeof(unsigned char) * (*outDataLen));
-                convertRGBA8ToBGR565(data, dataLen, *outData);
+                convertRGBA8ToRGB565(data, dataLen, *outData);
                 break;
             case PixelFormat::RGBA4:
                 *outDataLen = dataLen / 2;
                 *outData = (unsigned char*)malloc(sizeof(unsigned char) * (*outDataLen));
-                // convertRGBA8ToABGR4(data, dataLen, *outData);
-                convertRGBA8ToRGBA4(data, dataLen, *outData); // == MTLPixelFormatABGR4Unorm ??
+                convertRGBA8ToRGBA4(data, dataLen, *outData);
                 break;
             case PixelFormat::RGB5A1:
                 *outDataLen = dataLen / 2;
                 *outData = (unsigned char*)malloc(sizeof(unsigned char) * (*outDataLen));
-                convertRGBA8ToBGR5A1(data, dataLen, *outData);
+                convertRGBA8ToRGB5A1(data, dataLen, *outData);
                 break;
             case PixelFormat::A8:
                 *outDataLen = dataLen/4;
@@ -893,8 +891,7 @@ namespace backend { namespace PixelFormatUtils {
                 break;
             case PixelFormat::RGB5A1:
                 *outDataLen = dataLen;
-                *outData = (unsigned char*)malloc(sizeof(unsigned char) * (*outDataLen));
-                convertRGB5A1ToBGR5A1(data, dataLen, *outData);
+                *outData = (unsigned char *)data;
                 break;
             default:
                 // unsupported conversion or don't need to convert
@@ -922,8 +919,6 @@ namespace backend { namespace PixelFormatUtils {
             case PixelFormat::RGB565:
                 *outDataLen = dataLen;
                 *outData = (unsigned char *)data;
-                // they are identical
-                //convertRGB565ToB5G6R5(data, dataLen, *outData);
                 break;
             default:
                 // unsupported conversion or don't need to convert
@@ -974,7 +969,6 @@ namespace backend { namespace PixelFormatUtils {
             case PixelFormat::RGBA4:
                 *outDataLen = dataLen;
                 *outData = (unsigned char *)data;
-                //convertRGBA4ToABGR4(data, dataLen, *outData);
                 break;
             default:
                 // unsupported conversion or don't need to convert
@@ -1046,13 +1040,10 @@ namespace backend { namespace PixelFormatUtils {
                 return convertRGB5A1ToFormat(data, dataLen, format, outData, outDataLen);
             case PixelFormat::RGB565:
                 return convertRGB565ToFormat(data, dataLen, format, outData, outDataLen);
-#ifdef CC_USE_METAL
             case PixelFormat::RGBA4:
                 return convertRGBA4ToFormat(data, dataLen, format, outData, outDataLen);
             case PixelFormat::A8:
                 return convertA8ToFormat(data, dataLen, format, outData, outDataLen);
-                
-#endif
             case PixelFormat::BGRA8:
                 return convertBGRA8ToFormat(data, dataLen, format, outData, outDataLen);
             default:
diff --git a/cocos/renderer/backend/TextureUtils.h b/cocos/renderer/backend/TextureUtils.h
index 080b0a13f8..dd8820a053 100644
--- a/cocos/renderer/backend/TextureUtils.h
+++ b/cocos/renderer/backend/TextureUtils.h
@@ -103,7 +103,7 @@ namespace backend {
         void convertRGBA8ToRGBA4(const unsigned char* data, size_t dataLen, unsigned char* outData);
         void convertRGBA8ToRGB5A1(const unsigned char* data, size_t dataLen, unsigned char* outData);
 
-
+        //XXX to RGBA8
         void convertRGB5A1ToRGBA8(const unsigned char* data, size_t dataLen, unsigned char* outData);
         void convertRGB565ToRGBA8(const unsigned char* data, size_t dataLen, unsigned char* outData);
         void convertA8ToRGBA8(const unsigned char* data, size_t dataLen, unsigned char* outData);
diff --git a/cocos/renderer/backend/metal/UtilsMTL.mm b/cocos/renderer/backend/metal/UtilsMTL.mm
index dcb6f32a52..f37389d967 100644
--- a/cocos/renderer/backend/metal/UtilsMTL.mm
+++ b/cocos/renderer/backend/metal/UtilsMTL.mm
@@ -102,7 +102,7 @@ static GPUTextureFormatInfo s_textureFormats[] =
     { MTLPixelFormatInvalid,                        MTLPixelFormatInvalid                       }, // RGB8
     { MTLPixelFormat(40/*B5G6R5Unorm*/),            MTLPixelFormatInvalid                       }, // R5G6B5
     { MTLPixelFormat(42/*ABGR4Unorm*/),             MTLPixelFormatInvalid                       }, // RGBA4
-    { MTLPixelFormat(43/*BGR5A1Unorm*/),            MTLPixelFormatInvalid                       }, // RGB5A1
+    { MTLPixelFormat(41/*A1BGR5Unorm*/),            MTLPixelFormatInvalid                       }, // RGB5A1
     { MTLPixelFormatA8Unorm,                        MTLPixelFormatInvalid                       }, // A8
     { MTLPixelFormatInvalid,                        MTLPixelFormatInvalid                       }, // L8
     { MTLPixelFormatInvalid,                        MTLPixelFormatInvalid                       }, // LA8
diff --git a/cocos/renderer/backend/opengl/UtilsGL.cpp b/cocos/renderer/backend/opengl/UtilsGL.cpp
index 8c96cd2502..78137a583b 100644
--- a/cocos/renderer/backend/opengl/UtilsGL.cpp
+++ b/cocos/renderer/backend/opengl/UtilsGL.cpp
@@ -95,9 +95,9 @@ static GPUTextureFormatInfo s_textureFormats[] =
     { GL_RGBA,                                     GL_SRGB8_ALPHA8_EXT,                          GL_RGBA,                                     GL_RGBA,                                     GL_UNSIGNED_BYTE, }, // RGBA8
     { GL_RGBA,                                     GL_SRGB8_ALPHA8_EXT,                          GL_BGRA_EXT,                                 GL_BGRA_EXT,                                 GL_UNSIGNED_BYTE, }, // BGRA8
     { GL_RGB,                                      GL_SRGB_EXT,                                  GL_RGB,                                      GL_RGB,                                      GL_UNSIGNED_BYTE, }, // RGB8
-    { GL_RGB565,                                   GL_ZERO,                                      GL_RGB,                                      GL_RGB,                                      GL_UNSIGNED_SHORT_5_6_5}, // RGB565 TO-CHECK: match to MTLPixelFormatB5G6R5Unorm
+    { GL_RGB,                                      GL_ZERO,                                      GL_RGB,                                      GL_RGB,                                      GL_UNSIGNED_SHORT_5_6_5}, // RGB565 === MTLPixelFormatB5G6R5Unorm
     { GL_RGBA,                                     GL_ZERO,                                      GL_RGBA,                                     GL_RGBA,                                     GL_UNSIGNED_SHORT_4_4_4_4}, // RGBA4 === MTLPixelFormatABGR4Unorm
-    { GL_RGB5_A1,                                  GL_ZERO,                                      GL_BGRA_EXT,                                 GL_BGRA_EXT/*GL_BGRA_EXT*/,                  GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT}, // RGB5A1 TO-CHECK: match to MTLPixelFormatBGR5A1Unorm
+    { GL_RGBA,                                     GL_ZERO,                                      GL_RGBA,                                     GL_RGBA/*GL_BGRA_EXT*/,                      GL_UNSIGNED_SHORT_5_5_5_1}, // RGB5A1 === MTLPixelFormatA1BGR5Unorm
     { GL_ALPHA,                                    GL_ZERO,                                      GL_ALPHA,                                    GL_ALPHA,                                    GL_UNSIGNED_BYTE, }, // A8
     { GL_LUMINANCE,                                GL_ZERO,                                      GL_LUMINANCE,                                GL_LUMINANCE,                                GL_UNSIGNED_BYTE, }, // L8
     { GL_LUMINANCE_ALPHA,                          GL_ZERO,                                      GL_LUMINANCE_ALPHA,                          GL_LUMINANCE_ALPHA,                          GL_UNSIGNED_BYTE, }, // LA8
