0,0 → 1,769 |
|
#include <mmintrin.h> |
|
|
static void HLine(char *addr,int width, color_t color) |
{ |
__m64 dst_color; |
|
dst_color = _mm_cvtsi32_si64(color); |
dst_color = _mm_unpacklo_pi32(dst_color, dst_color); |
|
while (width >= 8) |
{ |
__asm__ __volatile__ ( |
"movq %[clr], (%0)\n\t" |
"movq %[clr], 8(%0)\n\t" |
"movq %[clr], 16(%0)\n\t" |
"movq %[clr], 24(%0)\n\t" |
:: "r" (addr), [clr] "y" (dst_color)); |
addr += 32; |
width -= 8; |
} |
if (width >= 4) |
{ |
__asm__ __volatile__ ( |
"movq %[clr], (%0)\n\t" |
"movq %[clr], 8(%0)\n\t" |
:: "r" (addr), [clr] "y" (dst_color)); |
addr += 16; |
width -= 4; |
} |
if (width >= 2) |
{ |
__asm__ __volatile__ ( |
"movq %[clr], (%0)\n\t" |
:: "r" (addr), [clr] "y" (dst_color)); |
addr += 8; |
width -= 2; |
} |
if ( width ) |
__asm__ __volatile__ ( |
"movd %[clr], (%0)\n\t" |
:: "r" (addr), [clr] "y" (dst_color)); |
|
_mm_empty(); |
} |
|
static void pxDraw(char *dst_addr, int pitch, int w, int h, color_t dst_color) |
{ |
__m64 color; |
|
color = _mm_cvtsi32_si64(dst_color); |
color = _mm_unpacklo_pi32(color, color); |
|
while(h--) |
{ |
char *tmp_dst =dst_addr; |
int width = w; |
dst_addr += pitch; |
|
while(width >= 8) |
{ |
__asm__ __volatile__ |
("movq %[clr], (%0)\n\t" |
"movq %[clr], 8(%0)\n\t" |
"movq %[clr], 16(%0)\n\t" |
"movq %[clr], 24(%0)\n\t" |
:: "r" (tmp_dst), [clr] "y" (color)); |
tmp_dst += 32; |
width -= 8; |
}; |
if(width >= 4) |
{ |
__asm__ __volatile__ |
("movq %[clr], (%0)\n\t" |
"movq %[clr], 8(%0)\n\t" |
:: "r" (tmp_dst), [clr] "y" (color)); |
tmp_dst += 16; |
width -= 4; |
}; |
|
if (width >= 2) |
{ |
__asm__ __volatile__ |
("movq %[clr], (%0)\n\t" |
:: "r" (tmp_dst), [clr] "y" (color)); |
tmp_dst += 8; |
width -= 2; |
}; |
if(width) |
__asm__ __volatile__ |
("movd %[clr], (%0)\n\t" |
:: "r" (tmp_dst), [clr] "y" (color)); |
}; |
_mm_empty(); |
}; |
|
int ClearPixmap(pixmap_t *pixmap, color_t color) |
{ |
if( (srv_hw2d != 0) && |
( ((int)pixmap == -1) || |
( (pixmap->flags & PX_MEM_MASK)==PX_MEM_LOCAL) ) ) |
{ |
ioctl_t io; |
|
if((int)pixmap != -1) |
pixmap = (pixmap_t*)pixmap->handle; |
|
io.handle = srv_hw2d; |
io.io_code = PX_CLEAR; |
io.input = &pixmap; |
io.inp_size = 2; |
io.output = NULL; |
io.out_size = 0; |
|
return call_service(&io); |
} |
|
pixmap = (pixmap == (void*)-1) ? &scrn_pixmap : pixmap ; |
|
pxDraw(pixmap->mapped, pixmap->pitch, |
pixmap->width, pixmap->height, color); |
return ERR_OK; |
}; |
|
int Line(pixmap_t *pixmap, int x0, int y0, int x1, int y1, color_t color) |
{ |
|
clip_t clip; |
|
if( (srv_hw2d != 0) && |
( (pixmap == (void*)-1) || |
( (pixmap->flags & PX_MEM_MASK)==PX_MEM_LOCAL) ) ) |
{ |
ioctl_t io; |
|
if((int)pixmap != -1) |
pixmap = (pixmap_t*)pixmap->handle; |
|
io.handle = srv_hw2d; |
io.io_code = PX_LINE; |
io.input = &pixmap; |
io.inp_size = 6; |
io.output = NULL; |
io.out_size = 0; |
|
return call_service(&io); |
} |
|
pixmap = (pixmap == (void*)-1) ? &scrn_pixmap : pixmap ; |
|
clip.xmin = 0; |
clip.ymin = 0; |
clip.xmax = pixmap->width-1; |
clip.ymax = pixmap->height-1; |
|
if ( !LineClip( &clip, &x0, &y0, &x1, &y1 )) |
{ |
int dx, dy; |
int sx, sy; |
int e, e1, e2, e3; |
|
char *addr; |
|
dx = x1 - x0; |
dy = y1 - y0; |
|
if( dx || dy) |
{ |
if( dy == 0 ) |
{ |
if (dx < 0) |
{ |
dx = -dx; |
x0 = x1; |
}; |
|
addr = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x0*4]; |
HLine(addr, dx, color); |
|
return ERR_OK; |
}; |
if( dx == 0 ) |
{ |
if (dy < 0) |
{ |
dy = -dy; |
y0 = y1; |
}; |
addr = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x0*4]; |
|
while ( dy-- ) |
{ |
*(color_t*)addr = color; |
addr += pixmap->pitch; |
} |
return ERR_OK; |
} |
|
sx = 4; |
if ( dx < 0 ) |
{ |
dx = -dx; |
sx = -sx; |
} |
sy = pixmap->pitch; |
if ( dy < 0 ) |
{ |
dy = -dy; |
sy = -sy; |
}; |
|
addr = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x0*4]; |
|
if (dx > dy) |
{ |
e1 = dy << 1; |
e2 = e1 - (dx << 1); |
e = e1 - dx; |
|
e3 = e2 - e1; |
e = e - e1; |
|
|
while (dx--) |
{ |
*(color_t*)addr = color; |
addr += sx; |
e += e1; |
if (e >= 0) |
{ |
addr += sy; |
e += e3; |
} |
} |
} |
else |
{ |
e1 = dx << 1; |
e2 = e1 - (dy << 1); |
e = e1 - dy; |
e3 = e2 - e1; |
e = e - e1; |
|
while (dy--) |
{ |
*(color_t*)addr = color; |
addr += sy; |
e += e1; |
if (e >= 0) |
{ |
addr += sx; |
e += e3; |
} |
} |
} |
} /* ( dx || dy ) */ |
} |
return ERR_OK; |
} |
|
int DrawRect(pixmap_t *pixmap, int xorg, int yorg, |
int width, int height, |
color_t dst_color, color_t border) |
{ |
|
if( ( width <= 0 ) || ( height<=0 ) ) |
return ERR_PARAM; |
|
/* if "hardware acceleration present" and |
"destinastion is primary screen or local videomemory" |
*/ |
|
if( (srv_hw2d != 0) && |
( (pixmap == (void*)-1) || |
( (pixmap->flags & PX_MEM_MASK)==PX_MEM_LOCAL) ) ) |
{ |
ioctl_t io; |
|
if((int)pixmap != -1) |
pixmap = (pixmap_t*)pixmap->handle; |
|
io.handle = srv_hw2d; |
io.io_code = PX_DRAW_RECT; |
io.input = &pixmap; |
io.inp_size = 7; |
io.output = NULL; |
io.out_size = 0; |
|
return call_service(&io); |
} |
else |
/* no acceleration or destination in system memory */ |
{ |
clip_t clip; |
int x0, y0, x1, y1, xend, yend; |
|
pixmap = (pixmap == (void*)-1) ? &scrn_pixmap : pixmap ; |
|
x0 = xorg; |
y0 = yorg; |
|
xend = x1 = x0 + width - 1; |
yend = y1 = y0 + height - 1; |
|
clip.xmin = 0; |
clip.ymin = 0; |
clip.xmax = pixmap->width-1; |
clip.ymax = pixmap->height-1; |
|
if( ! BlockClip( &clip, &x0, &y0, &x1, &y1)) |
{ |
int w, h; |
|
char *dst_addr; |
|
w = x1 - x0 + 1; |
h = y1 - y0 + 1; |
|
if( (dst_color == border) || |
((border & 0xFF000000)==0)) |
{ |
dst_addr = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x0*4]; |
pxDraw(dst_addr, pixmap->pitch, w, h, dst_color); |
} |
else |
{ |
if( y0 == yorg) |
{ |
dst_addr = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x0*4]; |
HLine(dst_addr, w, border); |
y0++; |
h--; |
} |
if( y1 == yend ) |
{ |
dst_addr = &((char*)(pixmap->mapped))[pixmap->pitch*y1 + x0*4]; |
HLine(dst_addr, w, border); |
h--; |
} |
if( (h > 0) && (x0 == xorg)) |
{ |
int dy = h; |
|
dst_addr = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x0*4]; |
|
while ( dy-- ) |
{ |
*(color_t*)dst_addr = border; |
dst_addr += pixmap->pitch; |
} |
x0++; |
w--; |
} |
if( (h > 0) && (x1 == xend)) |
{ |
int dy = h; |
|
dst_addr = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x1*4]; |
|
while ( dy-- ) |
{ |
*(color_t*)dst_addr = border; |
dst_addr += pixmap->pitch; |
} |
w--; |
} |
if( (w > 0) && (h > 0) ) |
{ |
dst_addr = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x0*4]; |
pxDraw(dst_addr, pixmap->pitch, w, h, dst_color); |
} |
} |
}; |
}; |
return ERR_OK; |
}; |
|
int FillRect(pixmap_t *pixmap, int xorg, int yorg, |
int width, int height, |
brush_t *dst_brush, color_t border) |
{ |
if( ( width <= 0 ) || ( height<=0 ) ) |
return ERR_PARAM; |
|
/* if "hardware acceleration present" and |
"destinastion is primary screen or local videomemory" |
*/ |
|
if( (srv_hw2d != 0) && |
( (pixmap == (void*)-1) || |
( (pixmap->flags & PX_MEM_MASK)==PX_MEM_LOCAL) ) ) |
{ |
fill_t fill; |
ioctl_t io; |
|
fill.dstpix = ((int)pixmap == -1) ? (pixmap_t*)-1 : (pixmap_t*)pixmap->handle; |
fill.x = xorg; |
fill.y = yorg; |
fill.w = width; |
fill.h = height; |
fill.bkcolor = dst_brush->bkcolor; |
fill.fcolor = dst_brush->fcolor; |
fill.bmp0 = dst_brush->bmp[0]; |
fill.bmp1 = dst_brush->bmp[1]; |
fill.border = border; |
|
io.handle = srv_hw2d; |
io.io_code = PX_FILL_RECT; |
io.input = &fill; |
io.inp_size = 10; |
io.output = NULL; |
io.out_size = 0; |
|
return call_service(&io); |
} |
else |
/* no acceleration or destination in system memory */ |
{ |
clip_t clip; |
int x0, y0, x1, y1, xend, yend; |
|
pixmap = (pixmap == (void*)-1) ? &scrn_pixmap : pixmap ; |
|
x0 = xorg; |
y0 = yorg; |
x1 = xend = x0 + width - 1; |
y1 = yend = y0 + height - 1; |
|
clip.xmin = 0; |
clip.ymin = 0; |
clip.xmax = pixmap->width-1; |
clip.ymax = pixmap->height-1; |
|
if( ! BlockClip( &clip, &x0, &y0, &x1, &y1)) |
{ |
int w, h, bh, bm_y; |
|
__m64 clr_bb, clr_bf, clr_fb, clr_ff; |
char *dst_addr; |
|
clr_bb = _mm_cvtsi32_si64(dst_brush->bkcolor); |
clr_ff = _mm_cvtsi32_si64(dst_brush->fcolor); |
|
clr_bb = _mm_unpacklo_pi32(clr_bb, clr_bb); |
clr_ff = _mm_unpacklo_pi32(clr_ff, clr_ff); |
|
clr_bf = _mm_unpacklo_pi32(clr_ff, clr_bb); |
clr_fb = _mm_unpacklo_pi32(clr_bb, clr_ff); |
|
w = x1 -x0 + 1; |
bh = h = y1 -y0 + 1; |
|
dst_addr = & ((char*)(pixmap->mapped))[pixmap->pitch*y0+x0*4]; |
|
bm_y = y0 & 7; |
|
while(h--) |
{ |
u8_t mask = dst_brush->bits[bm_y]; |
|
char *tmp_dst = dst_addr; |
int width = w; |
dst_addr += pixmap->pitch; |
bm_y = (bm_y+1) & 7; |
|
while(width>=2) |
{ |
__asm__ __volatile__ |
("rolb $2, %0 \n\t" |
:"+g" (mask):"g"(mask) |
:"cc"); |
|
switch( mask & 3 ) |
{ |
case 0: |
__asm__ __volatile__ |
("movq %[clr], (%0)\n\t" :: "r" (tmp_dst), [clr] "y" (clr_bb)); |
break; |
|
case 1: |
__asm__ __volatile__ |
("movq %[clr], (%0)\n\t" :: "r" (tmp_dst), [clr] "y" (clr_fb)); |
break; |
|
case 2: |
__asm__ __volatile__ |
("movq %[clr], (%0)\n\t" :: "r" (tmp_dst), [clr] "y" (clr_bf)); |
break; |
|
case 3: |
__asm__ __volatile__ |
("movq %[clr], (%0)\n\t" :: "r" (tmp_dst), [clr] "y" (clr_ff)); |
break; |
} |
width -=2; |
tmp_dst +=8; |
} |
if( width ) |
if( mask & 1 ) |
__asm__ __volatile__ |
("movd %[clr], (%0)\n\t" :: "r" (tmp_dst), [clr] "y" (clr_ff)); |
else |
__asm__ __volatile__ |
("movd %[clr], (%0)\n\t" :: "r" (tmp_dst), [clr] "y" (clr_bb)); |
}; |
|
if( (border & 0xFF000000) != 0) |
{ |
if( y0 == yorg) |
{ |
dst_addr = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x0*4]; |
HLine(dst_addr, w, border); |
y0++; |
bh--; |
} |
if( y1 == yend ) |
{ |
dst_addr = &((char*)(pixmap->mapped))[pixmap->pitch*y1 + x0*4]; |
HLine(dst_addr, w, border); |
bh--; |
} |
if( (bh > 0) && (x0 == xorg)) |
{ |
int dy = bh; |
|
dst_addr = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x0*4]; |
|
while ( dy-- ) |
{ |
*(color_t*)dst_addr = border; |
dst_addr += pixmap->pitch; |
} |
} |
if( (bh > 0) && (x1 == xend)) |
{ |
int dy = bh; |
|
dst_addr = &((char*)(pixmap->mapped))[pixmap->pitch*y0 + x1*4]; |
|
while ( dy-- ) |
{ |
*(color_t*)dst_addr = border; |
dst_addr += pixmap->pitch; |
} |
} |
}; |
|
_mm_empty(); |
}; |
}; |
return ERR_OK; |
}; |
|
|
int Blit(pixmap_t *dst_pixmap, int dst_x, int dst_y, |
pixmap_t *src_pixmap, int src_x, int src_y, |
int width, int height) |
{ |
|
clip_t src_clip, dst_clip; |
|
if( ( width <= 0 ) || ( height<=0 ) ) |
return ERR_PARAM; |
|
/* if "hardware acceleration present" and |
"destinastion is primary screen or local videomemory" and |
"source is primary screen or local videomemory" |
*/ |
if( (srv_hw2d != 0) && |
( (dst_pixmap == (void*)-1) || |
( (dst_pixmap->flags & PX_MEM_MASK)==PX_MEM_LOCAL) ) && |
( (src_pixmap == (void*)-1) || |
( (src_pixmap->flags & PX_MEM_MASK)==PX_MEM_LOCAL) ) ) |
{ |
ioctl_t io; |
pxblit_t *blit = (pxblit_t*)&dst_pixmap; |
|
if((int)dst_pixmap != -1) |
blit->dst_pixmap = (pixmap_t*)dst_pixmap->handle; |
|
if((int)src_pixmap != -1) |
blit->src_pixmap = (pixmap_t*)src_pixmap->handle; |
|
io.handle = srv_hw2d; |
io.io_code = PX_BLIT; |
io.input = blit; |
io.inp_size = 8; |
io.output = NULL; |
io.out_size = 0; |
|
return call_service(&io); |
} |
|
dst_pixmap = (dst_pixmap == (void*)-1) ? &scrn_pixmap : dst_pixmap ; |
src_pixmap = (src_pixmap == (void*)-1) ? &scrn_pixmap : src_pixmap ; |
|
src_clip.xmin = 0; |
src_clip.ymin = 0; |
src_clip.xmax = src_pixmap->width-1; |
src_clip.ymax = src_pixmap->height-1; |
|
dst_clip.xmin = 0; |
dst_clip.ymin = 0; |
dst_clip.xmax = dst_pixmap->width-1; |
dst_clip.ymax = dst_pixmap->height-1; |
|
if( !blit_clip(&dst_clip, &dst_x, &dst_y, |
&src_clip, &src_x, &src_y, |
&width, &height) ) |
{ |
color_t *src_addr = &((color_t*)(src_pixmap->mapped))[src_pixmap->pitch*src_y/4+src_x]; |
color_t *dst_addr = &((color_t*)(dst_pixmap->mapped))[dst_pixmap->pitch*dst_y/4+dst_x]; |
|
while( height-- ) |
{ |
int w = width; |
color_t *tmp_src = src_addr; |
color_t *tmp_dst = dst_addr; |
|
src_addr += src_pixmap->pitch/4; |
dst_addr += dst_pixmap->pitch/4; |
|
while( w >= 8) |
{ |
__asm__ __volatile__ ( |
"movq (%0), %%mm0\n" |
"movq 8(%0), %%mm1\n" |
"movq 16(%0), %%mm2\n" |
"movq 24(%0), %%mm3\n" |
"movq %%mm0, (%1)\n" |
"movq %%mm1, 8(%1)\n" |
"movq %%mm2, 16(%1)\n" |
"movq %%mm3, 24(%1)\n" |
:: "r" (tmp_src), "r" (tmp_dst) |
: "memory", "%mm0", "%mm1", "%mm2", "%mm3"); |
w -= 8; |
tmp_src += 8; |
tmp_dst += 8; |
}; |
if( w >= 4 ) |
{ |
__asm__ __volatile__ ( |
"movq (%0), %%mm0\n" |
"movq 8(%0), %%mm1\n" |
"movq %%mm0, (%1)\n" |
"movq %%mm1, 8(%1)\n" |
:: "r" (tmp_src), "r" (tmp_dst) |
: "memory", "%mm0", "%mm1"); |
w -= 4; |
tmp_src += 4; |
tmp_dst += 4; |
}; |
if( w >= 2 ) |
{ |
__asm__ __volatile__ ( |
"movq (%0), %%mm0\n" |
"movq %%mm0, (%1)\n" |
:: "r" (tmp_src), "r" (tmp_dst) |
: "memory", "%mm0"); |
w -= 2; |
tmp_src += 2; |
tmp_dst += 2; |
}; |
if( w ) |
*tmp_dst = *tmp_src; |
}; |
}; |
return ERR_OK; |
}; |
|
int TransparentBlit(pixmap_t *dst_pixmap, int dst_x, int dst_y, |
pixmap_t *src_pixmap, int src_x, int src_y, |
int width, int height, color_t key) |
{ |
clip_t src_clip, dst_clip; |
|
/* if "hardware acceleration present" and |
"destinastion is primary screen or local videomemory" and |
"source is primary screen or local videomemory" |
*/ |
|
if( (srv_hw2d != 0) && |
( (dst_pixmap == (void*)-1) || |
( (dst_pixmap->flags & PX_MEM_MASK)==PX_MEM_LOCAL) ) && |
( (src_pixmap == (void*)-1) || |
( (src_pixmap->flags & PX_MEM_MASK)==PX_MEM_LOCAL) ) ) |
{ |
ioctl_t io; |
pxblit_t *blit = (pxblit_t*)&dst_pixmap; |
|
if((int)dst_pixmap != -1) |
blit->dst_pixmap = (pixmap_t*)dst_pixmap->handle; |
|
if((int)src_pixmap != -1) |
blit->src_pixmap = (pixmap_t*)src_pixmap->handle; |
|
io.handle = srv_hw2d; |
io.io_code = PX_BLIT_TRANSPARENT; |
io.input = blit; |
io.inp_size = 9; |
io.output = NULL; |
io.out_size = 0; |
|
return call_service(&io); |
}; |
|
src_clip.xmin = 0; |
src_clip.ymin = 0; |
src_clip.xmax = src_pixmap->width-1; |
src_clip.ymax = src_pixmap->height-1; |
|
dst_clip.xmin = 0; |
dst_clip.ymin = 0; |
dst_clip.xmax = dst_pixmap->width-1; |
dst_clip.ymax = dst_pixmap->height-1; |
|
|
if( !blit_clip(&dst_clip, &dst_x, &dst_y, |
&src_clip, &src_x, &src_y, |
&width, &height) ) |
{ |
__m64 clr_key; |
|
dst_pixmap = (dst_pixmap == (void*)-1) ? &scrn_pixmap : dst_pixmap ; |
src_pixmap = (src_pixmap == (void*)-1) ? &scrn_pixmap : src_pixmap ; |
|
color_t *src_addr = &((color_t*)(src_pixmap->mapped))[src_pixmap->pitch*src_y/4+src_x]; |
color_t *dst_addr = &((color_t*)(dst_pixmap->mapped))[dst_pixmap->pitch*dst_y/4+dst_x]; |
|
clr_key = _mm_cvtsi32_si64(key); |
clr_key = _mm_unpacklo_pi32(clr_key, clr_key); |
|
while( height-- ) |
{ |
int w = width; |
color_t *tmp_src = src_addr; |
color_t *tmp_dst = dst_addr; |
|
src_addr += src_pixmap->pitch/4; |
dst_addr += dst_pixmap->pitch/4; |
|
while( w >= 2) |
{ |
__asm__ __volatile__ ( |
"movq %[clr_key], %%mm0 \n\t" |
"pcmpeqd %[src_clr], %%mm0 \n\t" |
"pand %%mm0, %[dst_clr] \n\t" |
"pandn %[src_clr], %%mm0 \n\t" |
"por %%mm0, %[dst_clr] \n\t" |
"movq %[dst_clr], (%0)" |
:: "r" (tmp_dst), |
[src_clr] "y" (*(__m64*)tmp_src), |
[dst_clr] "y" (*(__m64*)tmp_dst), |
[clr_key] "y" (clr_key) |
:"memory","mm0"); |
|
w -= 2; |
tmp_src += 2; |
tmp_dst += 2; |
}; |
if( w && (*tmp_src != key) ) |
*tmp_dst = *tmp_src; |
}; |
}; |
return ERR_OK; |
} |
|
|