diff options
author | Jesse Hall <jessehall@google.com> | 2012-07-17 15:51:53 -0700 |
---|---|---|
committer | Jesse Hall <jessehall@google.com> | 2012-07-22 00:35:08 -0700 |
commit | 74b55003f76dbca96e4a26d98fe464081ca5341f (patch) | |
tree | 510572781982f652f95f9f28669928f3a3a6657f /android | |
parent | 3dcbebfd43e409c3bbff7fc79288e40666a947fd (diff) | |
download | external_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
Diffstat (limited to 'android')
-rw-r--r-- | android/skin/scaler.c | 28 | ||||
-rw-r--r-- | android/skin/window.c | 45 |
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; }); |