From f97a167c445790fb380c2f730c377271e80e0d97 Mon Sep 17 00:00:00 2001
From: Andrei Karas <akaras@inbox.ru>
Date: Sun, 4 Aug 2013 00:13:18 +0300
Subject: improve OpenGL A,S dye speed.

---
 src/resources/dye.cpp               | 96 ++++++++++++++++++++++++-------------
 src/resources/dye.h                 |  4 +-
 src/resources/dye_unittest.cc       | 12 ++---
 src/resources/openglimagehelper.cpp | 21 +-------
 4 files changed, 73 insertions(+), 60 deletions(-)

(limited to 'src')

diff --git a/src/resources/dye.cpp b/src/resources/dye.cpp
index b3ac8ea46..905f3bcab 100644
--- a/src/resources/dye.cpp
+++ b/src/resources/dye.cpp
@@ -272,50 +272,80 @@ void DyePalette::replaceAColor(uint32_t *pixels, const int bufSize) const
     }
 }
 
-void DyePalette::replaceSOGLColor(uint8_t *const color) const
+void DyePalette::replaceSOGLColor(uint32_t *pixels, const int bufSize) const
 {
-    std::vector<DyeColor>::const_iterator it = mColors.begin();
-    const std::vector<DyeColor>::const_iterator it_end = mColors.end();
-    while (it != it_end)
+    std::vector<DyeColor>::const_iterator it_end = mColors.end();
+    const int sz = mColors.size();
+    if (!sz)
+        return;
+    if (sz % 2)
+        -- it_end;
+
+    for (uint32_t *p_end = pixels + bufSize; pixels != p_end; ++pixels)
     {
-        const DyeColor &col = *it;
-        ++ it;
-        if (it == it_end)
-            return;
-        const DyeColor &col2 = *it;
-        if (color[0] == col.value[0] && color[1] == col.value[1]
-            && color[2] == col.value[2])
+        uint8_t *const p = reinterpret_cast<uint8_t *>(pixels);
+        if (!(*pixels & 0xff000000))
+            continue;
+
+        std::vector<DyeColor>::const_iterator it = mColors.begin();
+        while (it != it_end)
         {
-            color[0] = col2.value[0];
-            color[1] = col2.value[1];
-            color[2] = col2.value[2];
-            return;
+            const DyeColor &col = *it;
+            ++ it;
+            const DyeColor &col2 = *it;
+
+            const unsigned int data = (*pixels) & 0x00ffffff;
+            const unsigned int coldata = (col.value[0])
+                | (col.value[1] << 8) | (col.value[2] << 16);
+
+            if (data == coldata)
+            {
+                p[0] = col2.value[0];
+                p[1] = col2.value[1];
+                p[2] = col2.value[2];
+                break;
+            }
+
+            ++ it;
         }
-        ++ it;
     }
 }
 
-void DyePalette::replaceAOGLColor(uint8_t *const color) const
+void DyePalette::replaceAOGLColor(uint32_t *pixels, const int bufSize) const
 {
-    std::vector<DyeColor>::const_iterator it = mColors.begin();
-    const std::vector<DyeColor>::const_iterator it_end = mColors.end();
-    while (it != it_end)
+    std::vector<DyeColor>::const_iterator it_end = mColors.end();
+    const int sz = mColors.size();
+    if (!sz)
+        return;
+    if (sz % 2)
+        -- it_end;
+
+    for (uint32_t *p_end = pixels + bufSize; pixels != p_end; ++pixels)
     {
-        const DyeColor &col = *it;
-        ++ it;
-        if (it == it_end)
-            return;
-        const DyeColor &col2 = *it;
-        if (color[0] == col.value[0] && color[1] == col.value[1]
-            && color[2] == col.value[2] && color[3] == col.value[3])
+        uint8_t *const p = reinterpret_cast<uint8_t *>(pixels);
+
+        std::vector<DyeColor>::const_iterator it = mColors.begin();
+        while (it != it_end)
         {
-            color[0] = col2.value[0];
-            color[1] = col2.value[1];
-            color[2] = col2.value[2];
-            color[3] = col2.value[3];
-            return;
+            const DyeColor &col = *it;
+            ++ it;
+            const DyeColor &col2 = *it;
+
+            const unsigned int data = *pixels;
+            const unsigned int coldata = (col.value[0]) | (col.value[1] << 8)
+                | (col.value[2] << 16) | (col.value[3] << 24);
+
+            if (data == coldata)
+            {
+                p[0] = col2.value[0];
+                p[1] = col2.value[1];
+                p[2] = col2.value[2];
+                p[3] = col2.value[3];
+                break;
+            }
+
+            ++ it;
         }
-        ++ it;
     }
 }
 
diff --git a/src/resources/dye.h b/src/resources/dye.h
index 2976c984d..e8b4ae94e 100644
--- a/src/resources/dye.h
+++ b/src/resources/dye.h
@@ -73,12 +73,12 @@ class DyePalette final
         /**
          * replace colors for OpenGL for S dye.
          */
-        void replaceSOGLColor(uint8_t *const color) const;
+        void replaceSOGLColor(uint32_t *pixels, const int bufSize) const;
 
         /**
          * replace colors for OpenGL for A dye.
          */
-        void replaceAOGLColor(uint8_t *const color) const;
+        void replaceAOGLColor(uint32_t *pixels, const int bufSize) const;
 
         static int hexDecode(const signed char c) A_WARN_UNUSED;
 
diff --git a/src/resources/dye_unittest.cc b/src/resources/dye_unittest.cc
index 10059ca34..dcea7bba6 100644
--- a/src/resources/dye_unittest.cc
+++ b/src/resources/dye_unittest.cc
@@ -32,7 +32,7 @@ TEST(Dye, replaceSOGLColor1)
     data[1] = 0x02;
     data[2] = 0x03;
     data[3] = 0x10;
-    palette.replaceSOGLColor(&data[0]);
+    palette.replaceSOGLColor(reinterpret_cast<uint32_t*>(&data[0]), 1);
     EXPECT_EQ(0x01, data[0]);
     EXPECT_EQ(0x02, data[1]);
     EXPECT_EQ(0x03, data[2]);
@@ -47,7 +47,7 @@ TEST(Dye, replaceSOGLColor2)
     data[1] = 0xff;
     data[2] = 0x00;
     data[3] = 0x20;
-    palette.replaceSOGLColor(&data[0]);
+    palette.replaceSOGLColor(reinterpret_cast<uint32_t*>(&data[0]), 1);
     EXPECT_EQ(0x00, data[0]);
     EXPECT_EQ(0x00, data[1]);
     EXPECT_EQ(0x11, data[2]);
@@ -62,7 +62,7 @@ TEST(Dye, replaceSOGLColor3)
     data[1] = 0x00;
     data[2] = 0xee;
     data[3] = 0x40;
-    palette.replaceSOGLColor(&data[0]);
+    palette.replaceSOGLColor(reinterpret_cast<uint32_t*>(&data[0]), 1);
     EXPECT_EQ(0x10, data[0]);
     EXPECT_EQ(0x20, data[1]);
     EXPECT_EQ(0x30, data[2]);
@@ -78,7 +78,7 @@ TEST(Dye, replaceAOGLColor1)
     data[1] = 0x02;
     data[2] = 0x03;
     data[3] = 0x10;
-    palette.replaceAOGLColor(&data[0]);
+    palette.replaceAOGLColor(reinterpret_cast<uint32_t*>(&data[0]), 1);
     EXPECT_EQ(0x01, data[0]);
     EXPECT_EQ(0x02, data[1]);
     EXPECT_EQ(0x03, data[2]);
@@ -93,7 +93,7 @@ TEST(Dye, replaceAOGLColor2)
     data[1] = 0xff;
     data[2] = 0x00;
     data[3] = 0x20;
-    palette.replaceAOGLColor(&data[0]);
+    palette.replaceAOGLColor(reinterpret_cast<uint32_t*>(&data[0]), 1);
     EXPECT_EQ(0x00, data[0]);
     EXPECT_EQ(0x00, data[1]);
     EXPECT_EQ(0x11, data[2]);
@@ -108,7 +108,7 @@ TEST(Dye, replaceAOGLColor3)
     data[1] = 0x00;
     data[2] = 0xee;
     data[3] = 0x40;
-    palette.replaceAOGLColor(&data[0]);
+    palette.replaceAOGLColor(reinterpret_cast<uint32_t*>(&data[0]), 1);
     EXPECT_EQ(0x10, data[0]);
     EXPECT_EQ(0x20, data[1]);
     EXPECT_EQ(0x30, data[2]);
diff --git a/src/resources/openglimagehelper.cpp b/src/resources/openglimagehelper.cpp
index 79cd12512..d392fead1 100644
--- a/src/resources/openglimagehelper.cpp
+++ b/src/resources/openglimagehelper.cpp
@@ -71,32 +71,15 @@ Image *OpenGLImageHelper::load(SDL_RWops *const rw, Dye const &dye) const
         case 1:
         {
             DyePalette *const pal = dye.getSPalete();
-
             if (pal)
-            {
-                for (uint32_t *p_end = pixels + surf->w * surf->h;
-                     pixels != p_end; ++pixels)
-                {
-                    uint8_t *p = reinterpret_cast<uint8_t *>(pixels);
-                    const int alpha = *p & 255;
-                    if (!alpha)
-                        continue;
-                    pal->replaceSOGLColor(p);
-                }
-            }
+                pal->replaceSOGLColor(pixels, surf->w * surf->h);
             break;
         }
         case 2:
         {
             DyePalette *const pal = dye.getAPalete();
             if (pal)
-            {
-                for (uint32_t *p_end = pixels + surf->w * surf->h;
-                     pixels != p_end; ++pixels)
-                {
-                    pal->replaceAOGLColor(reinterpret_cast<uint8_t *>(pixels));
-                }
-            }
+                pal->replaceAOGLColor(pixels, surf->w * surf->h);
             break;
         }
         case 0:
-- 
cgit v1.2.3-70-g09d2