Never use more than 16bpp on textures
authorAlberto Mardegan <mardy@users.sourceforge.net>
Sun, 10 Jul 2011 08:17:33 +0000 (11:17 +0300)
committerAlberto Mardegan <mardy@users.sourceforge.net>
Tue, 12 Jul 2011 12:26:50 +0000 (15:26 +0300)
The N900 display is set to 16bpp anyways, so anything more than that is just a
waste of memory. This brings a notable performance gain, as the FPS change from
about 15 to 20.
Note that the image_scale function should also be adjusted to cope with these
changes.

share/image.c

index 8ee9ccb..b63cb66 100644 (file)
@@ -105,6 +105,9 @@ static GLuint make_texture(const void *p, int w, int h, int b)
 {
     static const GLenum format[] =
         { 0, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA };
+    static const GLenum type[] =
+        { 0, GL_UNSIGNED_BYTE, GL_UNSIGNED_BYTE,
+            GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_4_4_4_4 };
 
     GLuint o = 0;
 
@@ -157,7 +160,7 @@ static GLuint make_texture(const void *p, int w, int h, int b)
 
     glTexImage2D(GL_TEXTURE_2D, 0,
                  format[b], W, H, 0,
-                 format[b], GL_UNSIGNED_BYTE, q ? q : p);
+                 format[b], type[b], q ? q : p);
 
     if (q) free(q);
 
@@ -165,6 +168,41 @@ static GLuint make_texture(const void *p, int w, int h, int b)
     return o;
 }
 
+static void *image_to_16bpp(unsigned char *data, int w, int h, int b)
+{
+    unsigned char *p, *row;
+    int i, j;
+
+    if (b <= 2) return data;
+
+    if ((p = malloc(w * h * 2)))
+    {
+        for (i = 0; i < h; i++)
+        {
+            row = data + i * w * b;
+            for (j = 0; j < w; j++)
+            {
+                unsigned short packed, *pp;
+                if (b == 4)
+                    packed =
+                        (row[j * b] >> 4) << 12 |
+                        (row[j * b + 1] >> 4) << 8 |
+                        (row[j * b + 2] >> 4) << 4 |
+                        row[j * b + 3] >> 4;
+                else
+                    packed =
+                        (row[j * b] >> 3) << 11 |
+                        (row[j * b + 1] >> 2) << 5 |
+                        (row[j * b + 2] >> 3);
+                pp = (unsigned short *)&p[i * w * 2 + j * 2];
+                *pp = packed;
+            }
+        }
+    }
+    free(data);
+    return p;
+}
+
 /*
  * Load an image from the named file.  Return an OpenGL texture object.
  */
@@ -180,6 +218,7 @@ GLuint make_image_from_file(const char *filename)
 
     if ((p = image_load(filename, &w, &h, &b)))
     {
+        p = image_to_16bpp(p, w, h, b);
         o = make_texture(p, w, h, b);
         free(p);
     }
@@ -251,6 +290,7 @@ GLuint make_image_from_font(int *W, int *H,
 
             /* Create the OpenGL texture object. */
 
+            p = image_to_16bpp(p, w2, h2, b);
             o = make_texture(p, w2, h2, b);
 
             free(p);