Add BGR format host frame buffer support in Epson LCD controller emulation
authorJuha Riihimäki <juhriihi@esdhcp039173.research.nokia.com>
Tue, 20 Jan 2009 12:32:50 +0000 (14:32 +0200)
committerJuha Riihimäki <juhriihi@esdhcp039173.research.nokia.com>
Tue, 20 Jan 2009 12:32:50 +0000 (14:32 +0200)
Current Epson LCD controller emulation assumes that the host frame buffers are in RGB format. This patch adds support for BGR format host frame buffers in the Epson LCD controller emulation thus making it more usable in such systems (e.g. OS X).

hw/blizzard.c
hw/blizzard_template.h

index eeaacdd..80f2800 100644 (file)
@@ -967,24 +967,24 @@ void *s1d13745_init(qemu_irq gpio_int, DisplayState *ds)
                 qemu_mallocz(sizeof(blizzard_fn_t) * 0x10);
         break;
     case 8:
-        s->line_fn_tab[0] = blizzard_draw_fn_8;
-        s->line_fn_tab[1] = blizzard_draw_fn_r_8;
+        s->line_fn_tab[0] = ds->bgr ? blizzard_draw_fn_bgr_8 : blizzard_draw_fn_8;
+        s->line_fn_tab[1] = ds->bgr ? blizzard_draw_fn_r_bgr_8 : blizzard_draw_fn_r_8;
         break;
     case 15:
-        s->line_fn_tab[0] = blizzard_draw_fn_15;
-        s->line_fn_tab[1] = blizzard_draw_fn_r_15;
+        s->line_fn_tab[0] = ds->bgr ? blizzard_draw_fn_bgr_15 : blizzard_draw_fn_15;
+        s->line_fn_tab[1] = ds->bgr ? blizzard_draw_fn_r_bgr_15 : blizzard_draw_fn_r_15;
         break;
     case 16:
-        s->line_fn_tab[0] = blizzard_draw_fn_16;
-        s->line_fn_tab[1] = blizzard_draw_fn_r_16;
+        s->line_fn_tab[0] = ds->bgr ? blizzard_draw_fn_bgr_16 : blizzard_draw_fn_16;
+        s->line_fn_tab[1] = ds->bgr ? blizzard_draw_fn_r_bgr_16 : blizzard_draw_fn_r_16;
         break;
     case 24:
-        s->line_fn_tab[0] = blizzard_draw_fn_24;
-        s->line_fn_tab[1] = blizzard_draw_fn_r_24;
+        s->line_fn_tab[0] = ds->bgr ? blizzard_draw_fn_bgr_24 : blizzard_draw_fn_24;
+        s->line_fn_tab[1] = ds->bgr ? blizzard_draw_fn_r_bgr_24 : blizzard_draw_fn_r_24;
         break;
     case 32:
-        s->line_fn_tab[0] = blizzard_draw_fn_32;
-        s->line_fn_tab[1] = blizzard_draw_fn_r_32;
+        s->line_fn_tab[0] = ds->bgr ? blizzard_draw_fn_bgr_32 : blizzard_draw_fn_32;
+        s->line_fn_tab[1] = ds->bgr ? blizzard_draw_fn_r_bgr_32 : blizzard_draw_fn_r_32;
         break;
     default:
         fprintf(stderr, "%s: Bad color depth\n", __FUNCTION__);
index ae51525..78d053a 100644 (file)
@@ -68,6 +68,28 @@ static void glue(blizzard_draw_line16_, DEPTH)(PIXEL_TYPE *dest,
 #endif
 }
 
+static void glue(blizzard_draw_line16_bgr_, DEPTH)(PIXEL_TYPE *dest,
+                                                                                          const uint16_t *src, unsigned int width)
+{
+#if !defined(SWAP_WORDS) && DEPTH == 16
+    memcpy(dest, src, width);
+#else
+    uint16_t data;
+    unsigned int r, g, b;
+    const uint16_t *end = (const void *) src + width;
+    while (src < end) {
+        data = lduw_raw(src ++);
+        r = (data & 0x1f) << 3;
+        data >>= 5;
+        g = (data & 0x3f) << 2;
+        data >>= 6;
+        b = (data & 0x1f) << 3;
+        data >>= 5;
+        COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b));
+    }
+#endif
+}
+
 static void glue(blizzard_draw_line24mode1_, DEPTH)(PIXEL_TYPE *dest,
                 const uint8_t *src, unsigned int width)
 {
@@ -87,6 +109,25 @@ static void glue(blizzard_draw_line24mode1_, DEPTH)(PIXEL_TYPE *dest,
     }
 }
 
+static void glue(blizzard_draw_line24mode1_bgr_, DEPTH)(PIXEL_TYPE *dest,
+                                                                                                       const uint8_t *src, unsigned int width)
+{
+    /* TODO: check if SDL 24-bit planes are not in the same format and
+     * if so, use memcpy */
+    unsigned int r[2], g[2], b[2];
+    const uint8_t *end = src + width;
+    while (src < end) {
+        g[0] = *src ++;
+        b[0] = *src ++;
+        b[1] = *src ++;
+        r[0] = *src ++;
+        COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r[0], g[0], b[0]));
+        r[1] = *src ++;
+        g[1] = *src ++;
+        COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r[1], g[1], b[1]));
+    }
+}
+
 static void glue(blizzard_draw_line24mode2_, DEPTH)(PIXEL_TYPE *dest,
                 const uint8_t *src, unsigned int width)
 {
@@ -101,6 +142,20 @@ static void glue(blizzard_draw_line24mode2_, DEPTH)(PIXEL_TYPE *dest,
     }
 }
 
+static void glue(blizzard_draw_line24mode2_bgr_, DEPTH)(PIXEL_TYPE *dest,
+                                                                                                       const uint8_t *src, unsigned int width)
+{
+    unsigned int r, g, b;
+    const uint8_t *end = src + width;
+    while (src < end) {
+        b = *src ++;
+        src ++;
+        r = *src ++;
+        g = *src ++;
+        COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b));
+    }
+}
+
 /* No rotation */
 static blizzard_fn_t glue(blizzard_draw_fn_, DEPTH)[0x10] = {
     NULL,
@@ -122,12 +177,39 @@ static blizzard_fn_t glue(blizzard_draw_fn_, DEPTH)[0x10] = {
     NULL, NULL, NULL, NULL, NULL, NULL,
 };
 
+/* No rotation, BGR */
+static blizzard_fn_t glue(blizzard_draw_fn_bgr_, DEPTH)[0x10] = {
+    NULL,
+    /* RGB 5:6:5*/
+    (blizzard_fn_t) glue(blizzard_draw_line16_bgr_, DEPTH),
+    /* RGB 6:6:6 mode 1 */
+    (blizzard_fn_t) glue(blizzard_draw_line24mode1_bgr_, DEPTH),
+    /* RGB 8:8:8 mode 1 */
+    (blizzard_fn_t) glue(blizzard_draw_line24mode1_bgr_, DEPTH),
+    NULL, NULL,
+    /* RGB 6:6:6 mode 2 */
+    (blizzard_fn_t) glue(blizzard_draw_line24mode2_bgr_, DEPTH),
+    /* RGB 8:8:8 mode 2 */
+    (blizzard_fn_t) glue(blizzard_draw_line24mode2_bgr_, DEPTH),
+    /* YUV 4:2:2 */
+    NULL,
+    /* YUV 4:2:0 */
+    NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL,
+};
+
 /* 90deg, 180deg and 270deg rotation */
 static blizzard_fn_t glue(blizzard_draw_fn_r_, DEPTH)[0x10] = {
     /* TODO */
     [0 ... 0xf] = NULL,
 };
 
+/* 90deg, 180deg and 270deg rotation, BGR */
+static blizzard_fn_t glue(blizzard_draw_fn_r_bgr_, DEPTH)[0x10] = {
+    /* TODO */
+    [0 ... 0xf] = NULL,
+};
+
 #undef DEPTH
 #undef SKIP_PIXEL
 #undef COPY_PIXEL