aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--android/skin/window.c59
-rw-r--r--android/utils/duff.h71
-rw-r--r--hw/goldfish_fb.c53
3 files changed, 135 insertions, 48 deletions
diff --git a/android/skin/window.c b/android/skin/window.c
index 018c184..e32a51f 100644
--- a/android/skin/window.c
+++ b/android/skin/window.c
@@ -15,6 +15,7 @@
#include "android/charmap.h"
#include "android/utils/debug.h"
#include "android/utils/system.h"
+#include "android/utils/duff.h"
#include "android/ui-core-protocol.h"
#include <SDL_syswm.h>
#include "user-events.h"
@@ -313,9 +314,9 @@ lcd_brightness_argb32( unsigned char* pixels, SkinRect* r, int pitch, int br
for ( ; h > 0; h-- ) {
unsigned* line = (unsigned*) pixels;
- int nn;
+ int nn = 0;
- for (nn = 0; nn < w; nn++) {
+ DUFF4(w, {
unsigned c = line[nn];
unsigned ag = (c >> 8) & 0x00ff00ff;
unsigned rb = (c) & 0x00ff00ff;
@@ -324,7 +325,8 @@ lcd_brightness_argb32( unsigned char* pixels, SkinRect* r, int pitch, int br
rb = ((rb*alpha) >> 8) & 0x00ff00ff;
line[nn] = (unsigned)(ag | rb);
- }
+ nn++;
+ });
pixels += pitch;
}
}
@@ -339,9 +341,9 @@ lcd_brightness_argb32( unsigned char* pixels, SkinRect* r, int pitch, int br
for ( ; h > 0; h-- ) {
unsigned* line = (unsigned*) pixels;
- int nn;
+ int nn = 0;
- for (nn = 0; nn < w; nn++) {
+ DUFF4(w, {
unsigned c = line[nn];
unsigned ag = (c >> 8) & 0x00ff00ff;
unsigned rb = (c) & 0x00ff00ff;
@@ -351,7 +353,8 @@ lcd_brightness_argb32( unsigned char* pixels, SkinRect* r, int pitch, int br
rb = ((rb*ialpha + 0x00ff00ff*alpha) >> 8) & 0x00ff00ff;
line[nn] = (unsigned)(ag | rb);
- }
+ nn++;
+ });
pixels += pitch;
}
}
@@ -399,9 +402,11 @@ display_redraw_rect16( ADisplay* disp, SkinRect* rect, SDL_Surface* surface)
uint32_t* dst = (uint32_t*)dst_line;
uint16_t* src = (uint16_t*)src_line;
- for (xx = 0; xx < w; xx++) {
+ xx = 0;
+ DUFF4(w, {
dst[xx] = rgb565_to_argb32(src[xx]);
- }
+ xx++;
+ });
src_line += src_pitch;
dst_line += dst_pitch;
}
@@ -415,12 +420,11 @@ display_redraw_rect16( ADisplay* disp, SkinRect* rect, SDL_Surface* surface)
uint32_t* dst = (uint32_t*)dst_line;
uint8_t* src = src_line;
- for (xx = w; xx > 0; xx--)
- {
+ DUFF4(w, {
dst[0] = rgb565_to_argb32(((uint16_t*)src)[0]);
src -= src_pitch;
dst += 1;
- }
+ });
src_line += 2;
dst_line += dst_pitch;
}
@@ -434,12 +438,11 @@ display_redraw_rect16( ADisplay* disp, SkinRect* rect, SDL_Surface* surface)
uint16_t* src = (uint16_t*)src_line;
uint32_t* dst = (uint32_t*)dst_line;
- for (xx = w; xx > 0; xx--) {
+ DUFF4(w, {
dst[0] = rgb565_to_argb32(src[0]);
src -= 1;
dst += 1;
- }
-
+ });
src_line -= src_pitch;
dst_line += dst_pitch;
}
@@ -453,11 +456,11 @@ display_redraw_rect16( ADisplay* disp, SkinRect* rect, SDL_Surface* surface)
uint32_t* dst = (uint32_t*)dst_line;
uint8_t* src = src_line;
- for (xx = w; xx > 0; xx--) {
+ DUFF4(w, {
dst[0] = rgb565_to_argb32(((uint16_t*)src)[0]);
dst += 1;
src += src_pitch;
- }
+ });
src_line -= 2;
dst_line += dst_pitch;
}
@@ -477,7 +480,7 @@ display_redraw_rect32( ADisplay* disp, SkinRect* rect,SDL_Surface* surface)
uint8_t* dst_line = (uint8_t*)surface->pixels + rect->pos.x*4 + rect->pos.y*dst_pitch;
int src_pitch = disp->datasize.w*4;
uint8_t* src_line = (uint8_t*)disp->data;
- int yy, xx;
+ int yy;
switch ( disp->rotation & 3 )
{
@@ -488,9 +491,11 @@ display_redraw_rect32( ADisplay* disp, SkinRect* rect,SDL_Surface* surface)
uint32_t* src = (uint32_t*)src_line;
uint32_t* dst = (uint32_t*)dst_line;
- for (xx = 0; xx < w; xx++) {
- dst[xx] = xbgr_to_argb32(src[xx]);
- }
+ DUFF4(w, {
+ dst[0] = xbgr_to_argb32(src[0]);
+ dst++;
+ src++;
+ });
src_line += src_pitch;
dst_line += dst_pitch;
}
@@ -504,12 +509,11 @@ display_redraw_rect32( ADisplay* disp, SkinRect* rect,SDL_Surface* surface)
uint32_t* dst = (uint32_t*)dst_line;
uint8_t* src = src_line;
- for (xx = w; xx > 0; xx--)
- {
+ DUFF4(w, {
dst[0] = xbgr_to_argb32(*(uint32_t*)src);
src -= src_pitch;
dst += 1;
- }
+ });
src_line += 4;
dst_line += dst_pitch;
}
@@ -523,12 +527,11 @@ display_redraw_rect32( ADisplay* disp, SkinRect* rect,SDL_Surface* surface)
uint32_t* src = (uint32_t*)src_line;
uint32_t* dst = (uint32_t*)dst_line;
- for (xx = w; xx > 0; xx--) {
+ DUFF4(w, {
dst[0] = xbgr_to_argb32(src[0]);
src -= 1;
dst += 1;
- }
-
+ });
src_line -= src_pitch;
dst_line += dst_pitch;
}
@@ -542,11 +545,11 @@ display_redraw_rect32( ADisplay* disp, SkinRect* rect,SDL_Surface* surface)
uint32_t* dst = (uint32_t*)dst_line;
uint8_t* src = src_line;
- for (xx = w; xx > 0; xx--) {
+ DUFF4(w, {
dst[0] = xbgr_to_argb32(*(uint32_t*)src);
dst += 1;
src += src_pitch;
- }
+ });
src_line -= 4;
dst_line += dst_pitch;
}
diff --git a/android/utils/duff.h b/android/utils/duff.h
new file mode 100644
index 0000000..a00768c
--- /dev/null
+++ b/android/utils/duff.h
@@ -0,0 +1,71 @@
+/* Copyright (C) 2011 The Android Open Source Project
+**
+** This software is licensed under the terms of the GNU General Public
+** License version 2, as published by the Free Software Foundation, and
+** may be copied, distributed, and modified under those terms.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+*/
+#ifndef ANDROID_UTILS_DUFF_H
+#define ANDROID_UTILS_DUFF_H
+
+/*********************************************************************
+ *********************************************************************
+ *****
+ ***** DUFF'S DEVICES
+ *****
+ *****/
+
+#define DUFF1(_count,_stmnt) \
+ do { \
+ int __n = (_count); \
+ do { \
+ _stmnt; \
+ } while (--__n > 0); \
+ } while (0);
+
+#define DUFF2(_count,_stmnt) \
+ ({ \
+ int __count = (_count); \
+ int __n = (__count +1)/2; \
+ switch (__count & 1) { \
+ case 0: do { _stmnt; \
+ case 1: _stmnt; \
+ } while (--__n > 0); \
+ } \
+ })
+
+#define DUFF4(_count,_stmnt) \
+ ({ \
+ int __count = (_count); \
+ int __n = (__count +3)/4; \
+ switch (__count & 3) { \
+ case 0: do { _stmnt; \
+ case 3: _stmnt; \
+ case 2: _stmnt; \
+ case 1: _stmnt; \
+ } while (--__n > 0); \
+ } \
+ })
+
+#define DUFF8(_count,_stmnt) \
+ ({ \
+ int __count = (_count); \
+ int __n = (__count+7)/8; \
+ switch (__count & 7) { \
+ case 0: do { _stmnt; \
+ case 7: _stmnt; \
+ case 6: _stmnt; \
+ case 5: _stmnt; \
+ case 4: _stmnt; \
+ case 3: _stmnt; \
+ case 2: _stmnt; \
+ case 1: _stmnt; \
+ } while (--__n > 0); \
+ } \
+ })
+
+#endif /* ANDROID_UTILS_DUFF_H */
diff --git a/hw/goldfish_fb.c b/hw/goldfish_fb.c
index 72352fa..d74d797 100644
--- a/hw/goldfish_fb.c
+++ b/hw/goldfish_fb.c
@@ -12,6 +12,7 @@
#include "qemu_file.h"
#include "android/android.h"
#include "android/utils/debug.h"
+#include "android/utils/duff.h"
#include "goldfish_device.h"
#include "console.h"
@@ -316,26 +317,29 @@ compute_fb_update_rect_linear(FbUpdateState* fbs,
const uint16_t* src = (const uint16_t*) src_line;
uint16_t* dst = (uint16_t*) dst_line;
- for (xx1 = 0; xx1 < width; xx1++) {
- if (src[xx1] != dst[xx1]) {
+ xx1 = 0;
+ DUFF4(width, {
+ if (src[xx1] != dst[xx1])
break;
- }
- }
+ xx1++;
+ });
if (xx1 == width) {
break;
}
- for (xx2 = width-1; xx2 > xx1; xx2--) {
- if (src[xx2] != dst[xx2]) {
+ xx2 = width-1;
+ DUFF4(xx2-xx1, {
+ if (src[xx2] != dst[xx2])
break;
- }
- }
+ xx2--;
+ });
#if HOST_WORDS_BIGENDIAN
/* Convert the guest little-endian pixels into big-endian ones */
int xx = xx1;
- for ( ; xx <= xx2; xx++ ) {
+ DUFF4(xx2-xx1+1,{
unsigned spix = src[xx];
dst[xx] = (uint16_t)((spix << 8) | (spix >> 8));
- }
+ xx++;
+ });
#else
memcpy( dst+xx1, src+xx1, (xx2-xx1+1)*2 );
#endif
@@ -344,25 +348,29 @@ compute_fb_update_rect_linear(FbUpdateState* fbs,
case 3:
{
- for (xx1 = 0; xx1 < width; xx1 += 1) {
+ xx1 = 0;
+ DUFF4(width, {
int xx = xx1*3;
if (src_line[xx+0] != dst_line[xx+0] ||
src_line[xx+1] != dst_line[xx+1] ||
src_line[xx+2] != dst_line[xx+2]) {
break;
}
- }
+ xx1 ++;
+ });
if (xx1 == width) {
break;
}
- for (xx2 = width-1; xx2 > xx1; xx2--) {
+ xx2 = width-1;
+ DUFF4(xx2-xx1,{
int xx = xx2*3;
if (src_line[xx+0] != dst_line[xx+0] ||
src_line[xx+1] != dst_line[xx+1] ||
src_line[xx+2] != dst_line[xx+2]) {
break;
}
- }
+ xx2--;
+ });
memcpy( dst_line+xx1*3, src_line+xx1*3, (xx2-xx1+1)*3 );
break;
}
@@ -372,28 +380,33 @@ compute_fb_update_rect_linear(FbUpdateState* fbs,
const uint32_t* src = (const uint32_t*) src_line;
uint32_t* dst = (uint32_t*) dst_line;
- for (xx1 = 0; xx1 < width; xx1++) {
+ xx1 = 0;
+ DUFF4(width, {
if (src[xx1] != dst[xx1]) {
break;
}
- }
+ xx1++;
+ });
if (xx1 == width) {
break;
}
- for (xx2 = width-1; xx2 > xx1; xx2--) {
+ xx2 = width-1;
+ DUFF4(xx2-xx1,{
if (src[xx2] != dst[xx2]) {
break;
}
- }
+ xx2--;
+ });
#if HOST_WORDS_BIGENDIAN
/* Convert the guest little-endian pixels into big-endian ones */
int xx = xx1;
- for ( ; xx <= xx2; xx++ ) {
+ DUFF4(xx2-xx1+1,{
uint32_t spix = src[xx];
spix = (spix << 16) | (spix >> 16);
spix = ((spix << 8) & 0xff00ff00) | ((spix >> 8) & 0x00ff00ff);
dst[xx] = spix;
- }
+ xx++;
+ })
#else
memcpy( dst+xx1, src+xx1, (xx2-xx1+1)*4 );
#endif