#include #include #include #include #include #include #include #include #include #include /* Variables globales */ static int width = 800; static int height = 400; static inline double get_time_ms(void) { struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0; } static int TestImageUpdateCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { double start, end; int iterations = 100; int i, x, y; double total_time = 0.0; unsigned char *data; if (objc > 2) { Tcl_WrongNumArgs(interp, 1, objv, "?iterations?"); return TCL_ERROR; } if (Tcl_GetIntFromObj(interp, objv[1], &iterations) != TCL_OK) { return TCL_ERROR; } Tk_Window tkwin = Tk_MainWindow(interp); if (tkwin == NULL) { Tcl_SetResult(interp, "No main window", TCL_STATIC); return TCL_ERROR; } Tk_Window targetWindow = Tk_NameToWindow(interp, ".f", tkwin); if (targetWindow == NULL) { Tcl_SetResult(interp, "No '.f' frame", TCL_STATIC); return TCL_ERROR; } Tk_MakeWindowExist(targetWindow); Window window = Tk_WindowId(targetWindow); Display *display = Tk_Display(targetWindow); if (window == None) { Tcl_SetResult(interp, "Window not yet created", TCL_STATIC); return TCL_ERROR; } XGCValues gcValues; gcValues.graphics_exposures = False; GC gc = Tk_GetGC(targetWindow, GCGraphicsExposures, &gcValues); data = (unsigned char *)malloc(width * height * 4); if (data == NULL) { Tcl_SetResult(interp, "Memory allocation failed", TCL_STATIC); return TCL_ERROR; } for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { int offset = (y * width + x) * 4; data[offset+0] = (x & 0xFF); data[offset+1] = (y & 0xFF); data[offset+2] = ((x + y) & 0xFF); data[offset+3] = 255; } } XImage *ximage = XCreateImage( display, Tk_Visual(targetWindow), Tk_Depth(targetWindow), ZPixmap, 0, (char*)data, width, height, 32, width * 4 ); for (i = 0; i < iterations; i++) { int status = 0; start = get_time_ms(); status = XPutImage(display, window, gc, ximage, 0, 0, 0, 0, width, height); end = get_time_ms(); if (status) { fprintf(stderr, "status: %d\n", status); } //XFlush(display); double elapsed = end - start; total_time += elapsed; if (i < 10 || i % 10 == 0) { printf("Iteration %d: %.3f ms\n", i, elapsed); } } double avg_time = total_time / iterations; printf("\nAverage time: %.3f ms\n", avg_time); char result[256]; sprintf(result, "%.3f", avg_time); Tcl_SetResult(interp, result, TCL_VOLATILE); return TCL_OK; } #ifdef __cplusplus extern "C" { #endif DLLEXPORT int Imagetest_Init(Tcl_Interp *interp) { if (Tcl_InitStubs(interp, "8.6-", 0) == NULL) { return TCL_ERROR; } if (Tk_InitStubs(interp, "8.6-", 0) == NULL) { return TCL_ERROR; } Tcl_CreateObjCommand(interp, "test_image_update", TestImageUpdateCmd, NULL, NULL); if (Tcl_PkgProvide(interp, "imagetest", "1.0") != TCL_OK) { return TCL_ERROR; } return TCL_OK; } #ifdef __cplusplus } #endif