mesa: rename logging functions to reflect that they format strings
[mesa.git] / src / mesa / main / format_utils.c
index 5fdabd5b97f54d5523c185e74103e515e6a6779b..6959bf062a1210b0b0dba66425b73bd31daa6b2f 100644 (file)
@@ -22,6 +22,7 @@
  * OTHER DEALINGS IN THE SOFTWARE.
  */
 
+#include "errors.h"
 #include "format_utils.h"
 #include "glformats.h"
 #include "format_pack.h"
@@ -179,6 +180,63 @@ _mesa_compute_rgba2base2rgba_component_mapping(GLenum baseFormat, uint8_t *map)
    }
 }
 
+
+/**
+ * Special case conversion function to swap r/b channels from the source
+ * image to the dest image.
+ */
+static void
+convert_ubyte_rgba_to_bgra(size_t width, size_t height,
+                           const uint8_t *src, size_t src_stride,
+                           uint8_t *dst, size_t dst_stride)
+{
+   int row;
+
+   if (sizeof(void *) == 8 &&
+       src_stride % 8 == 0 &&
+       dst_stride % 8 == 0 &&
+       (GLsizeiptr) src % 8 == 0 &&
+       (GLsizeiptr) dst % 8 == 0) {
+      /* use 64-bit word to swizzle two 32-bit pixels.  We need 8-byte
+       * alignment for src/dst addresses and strides.
+       */
+      for (row = 0; row < height; row++) {
+         const GLuint64 *s = (const GLuint64 *) src;
+         GLuint64 *d = (GLuint64 *) dst;
+         int i;
+         for (i = 0; i < width/2; i++) {
+            d[i] = ( (s[i] & 0xff00ff00ff00ff00) |
+                    ((s[i] &       0xff000000ff) << 16) |
+                    ((s[i] &   0xff000000ff0000) >> 16));
+         }
+         if (width & 1) {
+            /* handle the case of odd widths */
+            const GLuint s = ((const GLuint *) src)[width - 1];
+            GLuint *d = (GLuint *) dst + width - 1;
+            *d = ( (s & 0xff00ff00) |
+                  ((s &       0xff) << 16) |
+                  ((s &   0xff0000) >> 16));
+         }
+         src += src_stride;
+         dst += dst_stride;
+      }
+   } else {
+      for (row = 0; row < height; row++) {
+         const GLuint *s = (const GLuint *) src;
+         GLuint *d = (GLuint *) dst;
+         int i;
+         for (i = 0; i < width; i++) {
+            d[i] = ( (s[i] & 0xff00ff00) |
+                    ((s[i] &       0xff) << 16) |
+                    ((s[i] &   0xff0000) >> 16));
+         }
+         src += src_stride;
+         dst += dst_stride;
+      }
+   }
+}
+
+
 /**
  * This can be used to convert between most color formats.
  *
@@ -255,6 +313,20 @@ _mesa_format_convert(void *void_dst, uint32_t dst_format, size_t dst_stride,
     * enable it for specific combinations that are known to work.
     */
    if (!rebase_swizzle) {
+      /* Do a direct memcpy where possible */
+      if ((dst_format_is_mesa_array_format &&
+           src_format_is_mesa_array_format &&
+           src_array_format == dst_array_format) ||
+          src_format == dst_format) {
+         int format_size = _mesa_get_format_bytes(src_format);
+         for (row = 0; row < height; row++) {
+            memcpy(dst, src, width * format_size);
+            src += src_stride;
+            dst += dst_stride;
+         }
+         return;
+      }
+
       /* Handle the cases where we can directly unpack */
       if (!src_format_is_mesa_array_format) {
          if (dst_array_format == RGBA32_FLOAT) {
@@ -299,11 +371,18 @@ _mesa_format_convert(void *void_dst, uint32_t dst_format, size_t dst_stride,
             return;
          } else if (src_array_format == RGBA8_UBYTE) {
             assert(!_mesa_is_format_integer_color(dst_format));
-            for (row = 0; row < height; ++row) {
-               _mesa_pack_ubyte_rgba_row(dst_format, width,
-                                         (const uint8_t (*)[4])src, dst);
-               src += src_stride;
-               dst += dst_stride;
+
+            if (dst_format == MESA_FORMAT_B8G8R8A8_UNORM) {
+               convert_ubyte_rgba_to_bgra(width, height, src, src_stride,
+                                          dst, dst_stride);
+            }
+            else {
+               for (row = 0; row < height; ++row) {
+                  _mesa_pack_ubyte_rgba_row(dst_format, width,
+                                            (const uint8_t (*)[4])src, dst);
+                  src += src_stride;
+                  dst += dst_stride;
+               }
             }
             return;
          } else if (src_array_format == RGBA32_UINT &&