diff options
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; }); |