Skip to content

Commit

Permalink
Graphics optimization.
Browse files Browse the repository at this point in the history
  • Loading branch information
max_mu committed Jan 5, 2011
1 parent 3c5c62b commit 171b869
Show file tree
Hide file tree
Showing 2 changed files with 177 additions and 27 deletions.
101 changes: 101 additions & 0 deletions midp/src/lowlevelui/graphics/gx_putpixel/native/gxj_graphics_asm.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,12 +157,18 @@ asm volatile(
#define ASM_LOOPOPTIMIZE 1 /* collapse multiple scanlines to 1 */
#endif

#ifdef PSP
#define MIPS_BLIT 1
#endif

#if (!UNDER_CE)
void unclipped_blit(unsigned short *dstRaster, int dstSpan,
unsigned short *srcRaster, int srcSpan,
int height, int width, gxj_screen_buffer *dst) {
(void)dst;

//printf("unclipped_blit: height=%d, width=%d, dstSpan=%d, srcSpan=%d\n", height, width, dstSpan, srcSpan);

#if ASM_BLIT
__asm {
mov r0, dstRaster;
Expand Down Expand Up @@ -354,6 +360,101 @@ void unclipped_blit(unsigned short *dstRaster, int dstSpan,

done:
}
#elif MIPS_BLIT
unsigned short* next_ps;
unsigned short* next_pd;
int w = width;
int flag1 = dstSpan > 8 && srcSpan > 8 && width > 8;
unsigned flag2 = (unsigned int)dstRaster | (unsigned int)srcRaster | dstSpan | srcSpan;

/* single memcpy optimization */
if ((width == srcSpan) && (srcSpan == dstSpan)) {
width = dstSpan * height;
height = 1;
}

dstSpan >>= 1;
srcSpan >>=1;

for (; height > 0; height--) {
next_ps = srcRaster + srcSpan;
next_pd = dstRaster + dstSpan;

if (flag1) {
if ((flag2 & 0x03) == 0) {
//align by 4

long * pd = (long*)dstRaster;
long * ps = (long*)srcRaster;

for (; width >= 32; width -= 32) {
long t1, t2;
t1 = *ps++;
t2 = *ps++;
*pd++ = t1;
*pd++ = t2;

t1 = *ps++;
t2 = *ps++;

*pd++ = t1;
*pd++ = t2;

t1 = *ps++;
t2 = *ps++;
*pd++ = t1;
*pd++ = t2;

t1 = *ps++;
t2 = *ps++;
*pd++ = t1;
*pd++ = t2;
}

dstRaster = (unsigned short*)pd;
srcRaster = (unsigned short*)ps;
}
}

for (; width >= 16; width -= 16 ) {
unsigned short t1, t2;

t1 = *srcRaster++;
t2 = *srcRaster++;
*dstRaster++ = t1;
*dstRaster++ = t2;

t1 = *srcRaster++;
t2 = *srcRaster++;
*dstRaster++ = t1;
*dstRaster++ = t2;

t1 = *srcRaster++;
t2 = *srcRaster++;
*dstRaster++ = t1;
*dstRaster++ = t2;

t1 = *srcRaster++;
t2 = *srcRaster++;
*dstRaster++ = t1;
*dstRaster++ = t2;
}

switch (width) {
case 14: *dstRaster++ = *srcRaster++;
case 12: *dstRaster++ = *srcRaster++;
case 10: *dstRaster++ = *srcRaster++;
case 8: *dstRaster++ = *srcRaster++;
case 6: *dstRaster++ = *srcRaster++;
case 4: *dstRaster++ = *srcRaster++;
case 2: *dstRaster++ = *srcRaster++;
}

srcRaster = next_ps;
dstRaster = next_pd;
width = w;
}

#else
dstSpan >>= 1; srcSpan >>= 1;
if (((unsigned int)dstRaster | (unsigned int)srcRaster |
Expand Down
103 changes: 76 additions & 27 deletions midp/src/lowlevelui/graphics/gx_putpixel/native/gxj_image.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,35 @@ create_transformed_imageregion(gxj_screen_buffer* src, gxj_screen_buffer* dest,
} /* for y */
}

#define COPY_1BYTE_WITH_ALPHA(n) \
do { \
if (sa##n == 0xFF) { \
CHECK_PTR_CLIP(dest, (pDest+n)); \
*(pDest+n) = sp##n; \
} \
else if (sa##n > 0x3) { \
gxj_pixel_type pd = *(pDest+n); \
r1 = (sp##n >> 11); \
g1 = ((sp##n >> 5) & 0x3F); \
b1 = (sp##n & 0x1F); \
\
r2 = (pd >> 11); \
g2 = ((pd >> 5) & 0x3F); \
b2 = (pd & 0x1F); \
\
a2 = sa##n >> 2; \
a3 = sa##n >> 3; \
\
r1 = (r1 * a3 + r2 * (31 - a3)) >> 5; \
g1 = (g1 * a2 + g2 * (63 - a2)) >> 6; \
b1 = (b1 * a3 + b2 * (31 - a3)) >> 5; \
\
*(pDest+n) = (gxj_pixel_type)((r1 << 11) | (g1 << 5) | (b1)); \
} \
}while(0);



/**
* Renders the contents of the specified region of this
* mutable image onto the destination specified.
Expand Down Expand Up @@ -438,34 +467,35 @@ copy_imageregion(gxj_screen_buffer* src, gxj_screen_buffer* dest, const jshort *
int srcWidthDiff = src->width - width;
int r1, g1, b1, a2, a3, r2, b2, g2;



if (src->alphaData != NULL) {
unsigned char *pSrcAlpha = src->alphaData + (y_src * src->width) + x_src;
unsigned char *pSrcAlpha = src->alphaData + (y_src * src->width) + x_src;

/* copy the source to the destination */
for (rowsCopied = 0; rowsCopied < height; rowsCopied++) {
for (limit = pDest + width; pDest < limit; pDest++, pSrc++, pSrcAlpha++) {
if ((*pSrcAlpha) == 0xFF) {
CHECK_PTR_CLIP(dest, pDest);
*pDest = *pSrc;
}
else if (*pSrcAlpha > 0x3) {
r1 = (*pSrc >> 11);
g1 = ((*pSrc >> 5) & 0x3F);
b1 = (*pSrc & 0x1F);

r2 = (*pDest >> 11);
g2 = ((*pDest >> 5) & 0x3F);
b2 = (*pDest & 0x1F);

a2 = *pSrcAlpha >> 2;
a3 = *pSrcAlpha >> 3;

r1 = (r1 * a3 + r2 * (31 - a3)) >> 5;
g1 = (g1 * a2 + g2 * (63 - a2)) >> 6;
b1 = (b1 * a3 + b2 * (31 - a3)) >> 5;

*pDest = (gxj_pixel_type)((r1 << 11) | (g1 << 5) | (b1));
}
limit = pDest + width;
for (; pDest < limit - 4; pDest+=4, pSrc+=4, pSrcAlpha+=4) {
unsigned char sa0 = *pSrcAlpha;
unsigned char sa1 = *(pSrcAlpha+1);
unsigned char sa2 = *(pSrcAlpha+2);
unsigned char sa3 = *(pSrcAlpha+3);
gxj_pixel_type sp0 = *pSrc;
gxj_pixel_type sp1 = *(pSrc+1);
gxj_pixel_type sp2 = *(pSrc+2);
gxj_pixel_type sp3 = *(pSrc+3);

COPY_1BYTE_WITH_ALPHA(0);
COPY_1BYTE_WITH_ALPHA(1);
COPY_1BYTE_WITH_ALPHA(2);
COPY_1BYTE_WITH_ALPHA(3);
}

for (; pDest < limit; pDest++, pSrc++, pSrcAlpha++) {
unsigned char sa0 = *pSrcAlpha;
gxj_pixel_type sp0 = *pSrc;

COPY_1BYTE_WITH_ALPHA(0);
}

pDest += destWidthDiff;
Expand All @@ -475,9 +505,28 @@ copy_imageregion(gxj_screen_buffer* src, gxj_screen_buffer* dest, const jshort *
} else {
/* copy the source to the destination */
for (rowsCopied = 0; rowsCopied < height; rowsCopied++) {
for (limit = pDest + width; pDest < limit; pDest++, pSrc++) {
CHECK_PTR_CLIP(dest, pDest);
*pDest = *pSrc;
limit = pDest + width;
for (; pDest < limit-4; pDest+=4, pSrc+=4) {
unsigned short sp0 = *(pSrc+0);
unsigned short sp1 = *(pSrc+1);
unsigned short sp2 = *(pSrc+2);
unsigned short sp3 = *(pSrc+3);

CHECK_PTR_CLIP(dest, (pDest+0));
CHECK_PTR_CLIP(dest, (pDest+1));
CHECK_PTR_CLIP(dest, (pDest+2));
CHECK_PTR_CLIP(dest, (pDest+3));
*(pDest+0) = sp0;
*(pDest+1) = sp1;
*(pDest+2) = sp2;
*(pDest+3) = sp3;
}

for (; pDest < limit; pDest++, pSrc++) {
unsigned short sp0 = *(pSrc+0);

CHECK_PTR_CLIP(dest, (pDest+0));
*(pDest+0) = sp0;
}

pDest += destWidthDiff;
Expand Down

0 comments on commit 171b869

Please sign in to comment.