aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Hall <jessehall@google.com>2012-07-17 15:51:53 -0700
committerJesse Hall <jessehall@google.com>2012-07-22 00:35:08 -0700
commit74b55003f76dbca96e4a26d98fe464081ca5341f (patch)
tree510572781982f652f95f9f28669928f3a3a6657f
parent3dcbebfd43e409c3bbff7fc79288e40666a947fd (diff)
downloadexternal_qemu-74b55003f76dbca96e4a26d98fe464081ca5341f.zip
external_qemu-74b55003f76dbca96e4a26d98fe464081ca5341f.tar.gz
external_qemu-74b55003f76dbca96e4a26d98fe464081ca5341f.tar.bz2
Handle SDL windows with BGRA color
The switch to CoreGraphics on OSX (instead of QuickDraw) in SDL 1.2.15 means the SDL-created window now has BGRA color order instead of ARGB. This change makes the r5g6b5 and xbgr32 format converters handle whatever channel ordering the main SDL surface has. Skin regions don't need to change, since we draw them into auxiliary surfaces we created with ARGB order, and SDL does the conversion when we blit them into the main window. Change-Id: I2ae0529c66c11b60b3ade7a7a742368a2ab614bd
-rw-r--r--android/skin/scaler.c28
-rw-r--r--android/skin/window.c45
2 files changed, 56 insertions, 17 deletions
diff --git a/android/skin/scaler.c b/android/skin/scaler.c
index 5672869..bafd84e 100644
--- a/android/skin/scaler.c
+++ b/android/skin/scaler.c
@@ -150,6 +150,34 @@ skin_scaler_scale( SkinScaler* scaler,
else
scale_generic( &op );
}
+
+ // The optimized scale functions in argb.h assume the destination is ARGB.
+ // If that's not the case, do a channel reorder now.
+ if (dst_surface->format->Rshift != 16 ||
+ dst_surface->format->Gshift != 8 ||
+ dst_surface->format->Bshift != 0)
+ {
+ uint32_t rshift = dst_surface->format->Rshift;
+ uint32_t gshift = dst_surface->format->Gshift;
+ uint32_t bshift = dst_surface->format->Bshift;
+ uint32_t ashift = dst_surface->format->Ashift;
+ uint32_t amask = dst_surface->format->Amask; // may be 0x00
+ int x, y;
+
+ for (y = 0; y < op.rd.h; y++)
+ {
+ uint32_t* line = (uint32_t*)(op.dst_line + y*op.dst_pitch);
+ for (x = 0; x < op.rd.w; x++) {
+ uint32_t r = (line[x] & 0x00ff0000) >> 16;
+ uint32_t g = (line[x] & 0x0000ff00) >> 8;
+ uint32_t b = (line[x] & 0x000000ff) >> 0;
+ uint32_t a = (line[x] & 0xff000000) >> 24;
+ line[x] = (r << rshift) | (g << gshift) | (b << bshift) |
+ ((a << ashift) & amask);
+ }
+ }
+ }
+
SDL_UnlockSurface( dst_surface );
SDL_UnlockSurface( src_surface );
diff --git a/android/skin/window.c b/android/skin/window.c
index 5d8c684..65276ac 100644
--- a/android/skin/window.c
+++ b/android/skin/window.c
@@ -148,22 +148,25 @@ display_init( ADisplay* disp, SkinDisplay* sdisp, SkinLocation* loc, SkinRect
return (disp->data == NULL) ? -1 : 0;
}
-static __inline__ uint32_t rgb565_to_argb32( uint32_t pix )
+static __inline__ uint32_t rgb565_to_rgba32(uint32_t pix,
+ uint32_t rshift, uint32_t gshift, uint32_t bshift, uint32_t amask)
{
- uint32_t r = ((pix & 0xf800) << 8) | ((pix & 0xe000) << 3);
- uint32_t g = ((pix & 0x07e0) << 5) | ((pix & 0x0600) >> 1);
- uint32_t b = ((pix & 0x001f) << 3) | ((pix & 0x001c) >> 2);
- return 0xff000000 | r | g | b;
+ uint32_t r8 = ((pix & 0xf800) >> 8) | ((pix & 0xe000) >> 13);
+ uint32_t g8 = ((pix & 0x07e0) >> 3) | ((pix & 0x0600) >> 9);
+ uint32_t b8 = ((pix & 0x001f) << 3) | ((pix & 0x001c) >> 2);
+ return (r8 << rshift) | (g8 << gshift) | (b8 << bshift) | amask;
}
/* The framebuffer format is R,G,B,X in framebuffer memory, on a
* little-endian system, this translates to XBGR after a load.
*/
-static __inline__ uint32_t xbgr_to_argb32( uint32_t pix )
+static __inline__ uint32_t xbgr_to_rgba32(uint32_t pix,
+ uint32_t rshift, uint32_t gshift, uint32_t bshift, uint32_t amask)
{
- uint32_t g = (pix & 0x0000ff00);
- uint32_t rb = (pix & 0xff00ff);
- return 0xff000000 | (rb << 16) | g | (rb >> 16);
+ uint32_t r8 = (pix & 0x00ff0000) >> 16;
+ uint32_t g8 = (pix & 0x0000ff00) >> 8;
+ uint32_t b8 = (pix & 0x000000ff) >> 0;
+ return (r8 << rshift) | (g8 << gshift) | (b8 << bshift) | amask;
}
static void
@@ -392,6 +395,10 @@ display_redraw_rect16( ADisplay* disp, SkinRect* rect, SDL_Surface* surface)
int src_pitch = disp->datasize.w*2;
uint8_t* src_line = (uint8_t*)disp->data;
int yy, xx;
+ uint32_t rshift = surface->format->Rshift;
+ uint32_t gshift = surface->format->Gshift;
+ uint32_t bshift = surface->format->Bshift;
+ uint32_t amask = surface->format->Amask; // may be 0x00 for non-alpha format
switch ( disp->rotation & 3 )
{
@@ -405,7 +412,7 @@ display_redraw_rect16( ADisplay* disp, SkinRect* rect, SDL_Surface* surface)
xx = 0;
DUFF4(w, {
- dst[xx] = rgb565_to_argb32(src[xx]);
+ dst[xx] = rgb565_to_rgba32(src[xx], rshift, gshift, bshift, amask);
xx++;
});
src_line += src_pitch;
@@ -422,7 +429,7 @@ display_redraw_rect16( ADisplay* disp, SkinRect* rect, SDL_Surface* surface)
uint8_t* src = src_line;
DUFF4(w, {
- dst[0] = rgb565_to_argb32(((uint16_t*)src)[0]);
+ dst[0] = rgb565_to_rgba32(((uint16_t*)src)[0], rshift, gshift, bshift, amask);
src -= src_pitch;
dst += 1;
});
@@ -440,7 +447,7 @@ display_redraw_rect16( ADisplay* disp, SkinRect* rect, SDL_Surface* surface)
uint32_t* dst = (uint32_t*)dst_line;
DUFF4(w, {
- dst[0] = rgb565_to_argb32(src[0]);
+ dst[0] = rgb565_to_rgba32(src[0], rshift, gshift, bshift, amask);
src -= 1;
dst += 1;
});
@@ -458,7 +465,7 @@ display_redraw_rect16( ADisplay* disp, SkinRect* rect, SDL_Surface* surface)
uint8_t* src = src_line;
DUFF4(w, {
- dst[0] = rgb565_to_argb32(((uint16_t*)src)[0]);
+ dst[0] = rgb565_to_rgba32(((uint16_t*)src)[0], rshift, gshift, bshift, amask);
dst += 1;
src += src_pitch;
});
@@ -482,6 +489,10 @@ display_redraw_rect32( ADisplay* disp, SkinRect* rect,SDL_Surface* surface)
int src_pitch = disp->datasize.w*4;
uint8_t* src_line = (uint8_t*)disp->data;
int yy;
+ uint32_t rshift = surface->format->Rshift;
+ uint32_t gshift = surface->format->Gshift;
+ uint32_t bshift = surface->format->Bshift;
+ uint32_t amask = surface->format->Amask; // may be 0x00 for non-alpha format
switch ( disp->rotation & 3 )
{
@@ -493,7 +504,7 @@ display_redraw_rect32( ADisplay* disp, SkinRect* rect,SDL_Surface* surface)
uint32_t* dst = (uint32_t*)dst_line;
DUFF4(w, {
- dst[0] = xbgr_to_argb32(src[0]);
+ dst[0] = xbgr_to_rgba32(src[0], rshift, gshift, bshift, amask);
dst++;
src++;
});
@@ -511,7 +522,7 @@ display_redraw_rect32( ADisplay* disp, SkinRect* rect,SDL_Surface* surface)
uint8_t* src = src_line;
DUFF4(w, {
- dst[0] = xbgr_to_argb32(*(uint32_t*)src);
+ dst[0] = xbgr_to_rgba32(*(uint32_t*)src, rshift, gshift, bshift, amask);
src -= src_pitch;
dst += 1;
});
@@ -529,7 +540,7 @@ display_redraw_rect32( ADisplay* disp, SkinRect* rect,SDL_Surface* surface)
uint32_t* dst = (uint32_t*)dst_line;
DUFF4(w, {
- dst[0] = xbgr_to_argb32(src[0]);
+ dst[0] = xbgr_to_rgba32(src[0], rshift, gshift, bshift, amask);
src -= 1;
dst += 1;
});
@@ -547,7 +558,7 @@ display_redraw_rect32( ADisplay* disp, SkinRect* rect,SDL_Surface* surface)
uint8_t* src = src_line;
DUFF4(w, {
- dst[0] = xbgr_to_argb32(*(uint32_t*)src);
+ dst[0] = xbgr_to_rgba32(*(uint32_t*)src, rshift, gshift, bshift, amask);
dst += 1;
src += src_pitch;
});