#include "utils.h" #include "surface.h" #include "testscenarios.h" #include #include #include #include #include #include #include #include #include extern int win_w; extern int win_h; extern Display *disp; extern Window win; extern Bool useARGBWindow; extern double test_time; static const char *const FILLER = "......................................................................"; double get_time(void) { struct timeval timev; gettimeofday(&timev, NULL); return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000); } static int keep_running = 0; void time_test(char *description, void (*func) (int op, XRenderSurf *src, XRenderSurf *mask, XRenderSurf *dst), RenderOp *op, XRenderSurf *src, XRenderSurf *mask, XRenderSurf *dst) { char buf[51]; struct itimerval t; int frame_cnt = 0; double elapsed_time; struct timeval start, end; XImage *img; snprintf(buf, 50, "%s%s", description, FILLER); t.it_interval.tv_sec = 0; t.it_interval.tv_usec = 0; t.it_value.tv_sec = floor(test_time); t.it_value.tv_usec = (test_time - floor(test_time)) * 1000000; printf("\t\t %s", buf); fflush(NULL); keep_running = 1; setitimer(ITIMER_REAL, &t, NULL); gettimeofday(&start, NULL); while (keep_running) { func(op->op, src, mask, dst); ++frame_cnt; // Avoid queuing up way too many X requests in case rendering is really // slow. Otherwise, we could overshoot the target time significantly. if (frame_cnt % 50 == 0) XSync(disp, 0); } // Read back a pixel to flush any queued GPU rendering. img = XGetImage(disp, src->draw, 0, 0, 1, 1, AllPlanes, ZPixmap); gettimeofday(&end, NULL); XDestroyImage(img); elapsed_time = end.tv_sec - start.tv_sec + (end.tv_usec / 1000000.0 - start.tv_usec / 1000000.0); printf ("%d frames in %g seconds = %.3f FPS\n", frame_cnt, elapsed_time, frame_cnt / elapsed_time); } void populate_from_file(Display *disp, XRenderSurf *rs, const char *file) { char *img_data; unsigned int w, h; readPng(file, &img_data, &w, &h); xrender_surf_populate(disp, rs, w, h, img_data); } void setup_window(void) { XSetWindowAttributes att; XClassHint *xch; int scrn = DefaultScreen(disp); int depth = DefaultDepth(disp, scrn); Window parent = RootWindow(disp, scrn); Visual *vis = DefaultVisual(disp, scrn); if (useARGBWindow) { // Override the default visual and find a 32-bit one instead. XVisualInfo vis_info; depth = 32; if (!XMatchVisualInfo(disp, scrn, depth, TrueColor, &vis_info)) { fprintf(stderr, "Failed to find a 32-bit TrueColor visual\n"); exit(1); } vis = vis_info.visual; } att.background_pixmap = None; att.colormap = XCreateColormap(disp, parent, vis, AllocNone); att.border_pixel = 0; att.event_mask = ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | ExposureMask | StructureNotifyMask | KeyPressMask | KeyReleaseMask; win = XCreateWindow(disp, parent, 0, 0, win_w, win_h, 0, depth, InputOutput, vis, CWColormap | CWBorderPixel | CWEventMask | CWBackPixmap, &att); XStoreName(disp, win, "XRender Benchmark"); xch = XAllocClassHint(); xch->res_name = "Main"; xch->res_class = "XRenderBenchmark"; XSetClassHint(disp, win, xch); XFree(xch); XMapWindow(disp, win); XSync(disp, False); } void alarmhandler(int sig) { if (sig == SIGALRM) { keep_running = 0; } }