void bench_line(int n) { epx_pixmap_t* a; epx_gc_t* gc; int x0 = 0, x1 = 639; int y0, y1; int i; double tfsum = 0.0; gc = epx_gc_create(); a = epx_pixmap_create(640, 480, EPX_FORMAT_ARGB); epx_gc_set_line_style(gc, EPX_FILL_STYLE_BLEND); epx_gc_set_foreground_color(gc, epx_pixel_argb(127,100,200,150)); for (i = 0; i < n; i++) { struct timeval t, t0, t1; double tf; gettimeofday(&t0, NULL); for (y0 = 0; y0 < 480; y0++) { y1 = 439-y0; epx_pixmap_draw_line(a, gc, x0, y0, x1, y1); } gettimeofday(&t1, NULL); timersub(&t1, &t0, &t); tf = 480.0/(t.tv_sec+(t.tv_usec/1000000.0)); tfsum += tf; } printf("LINE Avg: %f/s\n", tfsum/n); }
/* Time the blend fill area function */ void bench_blend_fill(int n) { epx_pixmap_t* a; epx_gc_t* gc; int i, j; double tfsum = 0.0; /* Bench mark blending function */ gc = epx_gc_create(); a = epx_pixmap_create(640, 480, EPX_FORMAT_ARGB); epx_gc_set_fill_style(gc, EPX_FILL_STYLE_BLEND); epx_gc_set_border_width(gc, 0); epx_gc_set_fill_color(gc, epx_pixel_argb(127,100,200,150)); for (j = 0; j < n; j++) { struct timeval t, t0, t1; double tf; gettimeofday(&t0, NULL); for (i = 0; i < 100; i++) { epx_pixmap_draw_rectangle(a, gc, 0, 0, 640, 480); } gettimeofday(&t1, NULL); timersub(&t1, &t0, &t); tf = 100.0/(t.tv_sec+(t.tv_usec/1000000.0)); tfsum += tf; } printf("BFILL: Avg: %f/s\n", tfsum/n); }
/* Draw & Blend animation frame with background */ void epx_anim_draw_frame(epx_pixmap_t* pic, epx_gc_t* gc, int x, int y, int width, int height, epx_format_t src_pt, epx_anim_pixels_t* base, epx_anim_pixels_t* current) { u_int8_t fader = gc->fader_value; u_int8_t *src = (u_int8_t*) current; u_int8_t* src_save = NULL; int n_blocks = 0; unsigned char *dst0 = EPX_PIXEL_ADDR(pic, x, y); int dst_wb = pic->bytes_per_row; epx_format_t src_format = src_pt; int srcPixelSize = EPX_PIXEL_BYTE_SIZE(src_pt); epx_format_t dst_format = pic->pixel_format; int dstPixelSize = pic->bytes_per_pixel; epx_rect_t r = {{x,y}, {width,height}}; int x0, yi; int clip_y0, clip_y1; int clip_x0, clip_x1, clip_len; int need_x_clip; if (epx_rect_is_subrect(&r, &pic->clip)) { if (src_format == dst_format) { if (dst_format == EPX_FORMAT_BGRA) goto bgra_noclip; else if (dst_format == EPX_FORMAT_RGBA) goto rgba_noclip; goto no_clip; } } goto clip; /* if we must clip the image we do the general stuff */ clip: clip_y0 = epx_rect_top(&pic->clip); clip_y1 = epx_rect_bottom(&pic->clip); clip_x0 = epx_rect_left(&pic->clip); clip_x1 = epx_rect_right(&pic->clip); clip_len = epx_rect_width(&pic->clip); yi = y; x0 = x; need_x_clip = !( (x0 >= clip_x0) && ((x0+width-1) <= clip_x1) ); while(height--) { int xi = x0; int w = width; if (!epx_in_range(yi, clip_y0, clip_y1)) { // The line is clipped but we must skip the source data while(w) { epx_anim_pixels_t* hdr = (epx_anim_pixels_t*) src; u_int32_t pcount; if (hdr->type == EPX_ANIM_INDIRECT) { u_int8_t *isrc = ((u_int8_t*)base) + hdr->count; n_blocks = hdr->nblocks; // number of blocks to run src_save = src + sizeof(epx_anim_pixels_t); // continue point src = isrc; hdr = (epx_anim_pixels_t*) src; // switch to indirect header } src += sizeof(epx_anim_pixels_t); pcount = hdr->count; w -= pcount; switch(hdr->type) { case EPX_ANIM_SKIP: break; case EPX_ANIM_SHADOW: src += pcount; break; case EPX_ANIM_BGRA: case EPX_ANIM_RGBA: src += pcount*4; break; case EPX_ANIM_COPY: src += pcount*srcPixelSize; break; case EPX_ANIM_FILL: src += 4; break; default: break; } if (n_blocks) { // are we running indirect blocks? if (n_blocks == 1) src = src_save; // restore & continue n_blocks--; } } } else if (!need_x_clip) { // No horizontal clipping needed unsigned char *dst = EPX_PIXEL_ADDR(pic, xi, yi); while(w) { epx_anim_pixels_t* hdr = (epx_anim_pixels_t*) src; u_int32_t pcount; u_int8_t a; if (hdr->type == EPX_ANIM_INDIRECT) { u_int8_t *isrc = ((u_int8_t*)base) + hdr->count; n_blocks = hdr->nblocks; // number of blocks to run src_save = src + sizeof(epx_anim_pixels_t); // continue point src = isrc; hdr = (epx_anim_pixels_t*) src; // switch to indirect header } src += sizeof(epx_anim_pixels_t); pcount = hdr->count; w -= pcount; switch(hdr->type) { case EPX_ANIM_SKIP: break; case EPX_ANIM_SHADOW: epx_add_color_row(src, EPX_FORMAT_A8, dst, dst_format, fader, epx_pixel_transparent, pcount, EPX_FLAG_BLEND); src += pcount; break; case EPX_ANIM_BGRA: epx_fade_row(src,EPX_FORMAT_BGRA, dst, dst_format, fader, pcount); src += pcount*4; break; case EPX_ANIM_RGBA: epx_fade_row(src,EPX_FORMAT_RGBA, dst, dst_format, fader, pcount); src += pcount*4; break; case EPX_ANIM_COPY: if (fader == ALPHA_FACTOR_1) epx_copy_row(src, src_format, dst, dst_format, pcount); else if (fader != ALPHA_FACTOR_0) epx_alpha_row(src, src_format, dst, dst_format, fader, pcount); src += pcount*srcPixelSize; break; case EPX_ANIM_FILL: a= (fader==ALPHA_FACTOR_1) ? src[0] : ((src[0]*fader) >> 8); if (a == EPX_ALPHA_TRANSPARENT) ; else if (a == EPX_ALPHA_OPAQUE) epx_fill_row(dst, dst_format, epx_pixel_argb(a,src[1],src[2],src[3]), pcount); else epx_fill_row_blend(dst, dst_format, epx_pixel_argb(a,src[1], src[2],src[3]), pcount); src += 4; break; default: break; } dst += pcount*dstPixelSize; if (n_blocks) { // are we running indirect blocks? if (n_blocks == 1) src = src_save; // restore & continue n_blocks--; } } } else { // we need to clip dds
/* Copy animation frame to background */ void epx_anim_copy_frame(epx_pixmap_t* pic, epx_gc_t* gc, int x, int y, int width, int height, epx_format_t src_pt, epx_anim_pixels_t* base, epx_anim_pixels_t* current) { (void) gc; u_int8_t *src = (u_int8_t*) current; u_int8_t* src_save = NULL; int n_blocks = 0; unsigned char *dst0 = EPX_PIXEL_ADDR(pic, x, y); int dst_wb = pic->bytes_per_row; epx_format_t src_format = src_pt; int srcPixelSize = EPX_PIXEL_BYTE_SIZE(src_pt); epx_format_t dst_format = pic->pixel_format; int dstPixelSize = pic->bytes_per_pixel; while(height--) { unsigned char* dst = dst0; int w = width; dst0 += dst_wb; while(w) { epx_anim_pixels_t* hdr = (epx_anim_pixels_t*) src; u_int32_t pcount; if (hdr->type == EPX_ANIM_INDIRECT) { u_int8_t *isrc = ((u_int8_t*)base) + hdr->count; n_blocks = hdr->nblocks; // number of blocks to run src_save = src + sizeof(epx_anim_pixels_t); // continue point src = isrc; hdr = (epx_anim_pixels_t*) src; // switch to indirect header } src += sizeof(epx_anim_pixels_t); pcount = hdr->count; w -= pcount; switch(hdr->type) { case EPX_ANIM_SKIP: break; case EPX_ANIM_SHADOW: epx_copy_row(src, EPX_FORMAT_A8, dst, dst_format, pcount); src += pcount; break; case EPX_ANIM_RGBA: epx_copy_row(src,EPX_FORMAT_RGBA, dst, dst_format, pcount); src += pcount*4; break; case EPX_ANIM_BGRA: epx_copy_row(src,EPX_FORMAT_BGRA, dst, dst_format, pcount); src += pcount*4; break; case EPX_ANIM_COPY: // BGRA values!!! epx_copy_row(src, src_format, dst, dst_format, pcount); src += pcount*srcPixelSize; break; case EPX_ANIM_FILL: epx_fill_row(dst, dst_format, epx_pixel_argb(src[0],src[1],src[2],src[3]), pcount); src += 4; break; default: break; } dst += pcount*dstPixelSize; if (n_blocks) { // are we running indirect blocks? if (n_blocks == 1) src = src_save; // restore & continue n_blocks--; } } } }