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

hw/omap3_lcd_panel_template.h
hw/omap_dss.c

index 4448ade..651a65f 100644 (file)
@@ -75,6 +75,28 @@ static void glue(omap3_lcd_panel_draw_line16_, DEPTH)(PIXEL_TYPE *dest,
 #endif\r
 }\r
 \r
+static void glue(omap3_lcd_panel_draw_line16_bgr_, DEPTH)(PIXEL_TYPE *dest,\r
+                                                      const uint16_t *src, unsigned int width)\r
+{\r
+#if !defined(SWAP_WORDS) && DEPTH == 16\r
+    memcpy(dest, src, width);\r
+#else\r
+    uint16_t data;\r
+    unsigned int r, g, b;\r
+    const uint16_t *end = (const void *) src + width;\r
+    while (src < end) {\r
+        data = lduw_raw(src ++);\r
+        r = (data & 0x1f) << 3;\r
+        data >>= 5;\r
+        g = (data & 0x3f) << 2;\r
+        data >>= 6;\r
+        b = (data & 0x1f) << 3;\r
+        data >>= 5;\r
+        COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b));\r
+    }\r
+#endif\r
+}\r
+\r
 \r
 /*\r
 LCD: 0x4: RGB 12      \r
@@ -109,12 +131,34 @@ static omap3_lcd_panel_fn_t glue(omap3_lcd_panel_draw_fn_, DEPTH)[0x10] = {
     NULL,  /*0xe: RGBx 32 (24-bit RGB aligned on MSB of the 32-bit container) */\r
     NULL,  /*0xf */\r
 };\r
+static omap3_lcd_panel_fn_t glue(omap3_lcd_panel_draw_fn_bgr_, DEPTH)[0x10] = {\r
+    NULL,   /*0x0*/\r
+    NULL,   /*0x1*/\r
+    NULL,   /*0x2*/\r
+    NULL,   /*0x3*/\r
+    NULL,  /*0x4:RGB 12 */\r
+    NULL,  /*0x5: ARGB16 */\r
+    (omap3_lcd_panel_fn_t)glue(omap3_lcd_panel_draw_line16_bgr_, DEPTH),  /*0x6: RGB 16 */\r
+    NULL,  /*0x7*/\r
+    NULL,  /*0x8: RGB 24 (un-packed in 32-bit container) */\r
+    NULL,  /*0x9: RGB 24 (packed in 24-bit container) */\r
+    NULL,  /*0xa */\r
+    NULL,  /*0xb */\r
+    NULL,  /*0xc: ARGB32 */\r
+    NULL,  /*0xd: RGBA32 */\r
+    NULL,  /*0xe: RGBx 32 (24-bit RGB aligned on MSB of the 32-bit container) */\r
+    NULL,  /*0xf */\r
+};\r
 \r
 /* 90deg, 180deg and 270deg rotation */\r
 static omap3_lcd_panel_fn_t glue(omap3_lcd_panel_draw_fn_r_, DEPTH)[0x10] = {\r
     /* TODO */\r
     [0 ... 0xf] = NULL,\r
 };\r
+static omap3_lcd_panel_fn_t glue(omap3_lcd_panel_draw_fn_r_bgr_, DEPTH)[0x10] = {\r
+    /* TODO */\r
+    [0 ... 0xf] = NULL,\r
+};\r
 \r
 #undef DEPTH\r
 #undef SKIP_PIXEL\r
index da6b14b..1d005b7 100644 (file)
@@ -1233,24 +1233,24 @@ void *omap3_lcd_panel_init(DisplayState *ds)
             qemu_mallocz(sizeof(omap3_lcd_panel_fn_t) * 0x10);
         break;
     case 8:
-        s->line_fn_tab[0] = omap3_lcd_panel_draw_fn_8;
-        s->line_fn_tab[1] = omap3_lcd_panel_draw_fn_r_8;
+        s->line_fn_tab[0] = ds->bgr ? omap3_lcd_panel_draw_fn_bgr_8 : omap3_lcd_panel_draw_fn_8;
+        s->line_fn_tab[1] = ds->bgr ? omap3_lcd_panel_draw_fn_r_bgr_8 : omap3_lcd_panel_draw_fn_r_8;
         break;
     case 15:
-        s->line_fn_tab[0] = omap3_lcd_panel_draw_fn_15;
-        s->line_fn_tab[1] = omap3_lcd_panel_draw_fn_r_15;
+        s->line_fn_tab[0] = ds->bgr ? omap3_lcd_panel_draw_fn_bgr_15 : omap3_lcd_panel_draw_fn_15;
+        s->line_fn_tab[1] = ds->bgr ? omap3_lcd_panel_draw_fn_r_bgr_15 : omap3_lcd_panel_draw_fn_r_15;
         break;
     case 16:
-        s->line_fn_tab[0] = omap3_lcd_panel_draw_fn_16;
-        s->line_fn_tab[1] = omap3_lcd_panel_draw_fn_r_16;
+        s->line_fn_tab[0] = ds->bgr ? omap3_lcd_panel_draw_fn_bgr_16 : omap3_lcd_panel_draw_fn_16;
+        s->line_fn_tab[1] = ds->bgr ? omap3_lcd_panel_draw_fn_r_bgr_16: omap3_lcd_panel_draw_fn_r_16;
         break;
     case 24:
-        s->line_fn_tab[0] = omap3_lcd_panel_draw_fn_24;
-        s->line_fn_tab[1] = omap3_lcd_panel_draw_fn_r_24;
+        s->line_fn_tab[0] = ds->bgr ? omap3_lcd_panel_draw_fn_bgr_24 : omap3_lcd_panel_draw_fn_24;
+        s->line_fn_tab[1] = ds->bgr ? omap3_lcd_panel_draw_fn_r_bgr_24 : omap3_lcd_panel_draw_fn_r_24;
         break;
     case 32:
-        s->line_fn_tab[0] = omap3_lcd_panel_draw_fn_32;
-        s->line_fn_tab[1] = omap3_lcd_panel_draw_fn_r_32;
+        s->line_fn_tab[0] = ds->bgr ? omap3_lcd_panel_draw_fn_bgr_32 : omap3_lcd_panel_draw_fn_32;
+        s->line_fn_tab[1] = ds->bgr ? omap3_lcd_panel_draw_fn_r_bgr_32 : omap3_lcd_panel_draw_fn_r_32;
         break;
     default:
         fprintf(stderr, "%s: Bad color depth\n", __FUNCTION__);