#define _GNU_SOURCE #include #include #include #include #include #define GL_GLEXT_PROTOTYPES #include static double get_timestamp() { struct timespec tp; clock_gettime(CLOCK_MONOTONIC, &tp); return tp.tv_sec + 1e-9 * tp.tv_nsec; } int main(int argc, char *argv[]) { int width = 0, height = 0; if (argc != 3 || !(width = atoi(argv[1])) || !(height = atoi(argv[2]))) { fprintf(stderr, "usage: %s WIDTH HEIGHT\n", argv[0]); return 1; } Display *dpy = XOpenDisplay(NULL); int ncfg, attrs[] = {GLX_DOUBLEBUFFER, GL_TRUE, None}; GLXFBConfig *dconfigs = glXChooseFBConfig(dpy, 0, attrs, &ncfg); fprintf(stderr, "FBConfig %p\n", dconfigs[0]); int pbattrs[] = {GLX_PBUFFER_WIDTH, width, GLX_PBUFFER_HEIGHT, height, GLX_PRESERVED_CONTENTS, True, None}; GLXPbuffer pbuffer = glXCreatePbuffer(dpy, dconfigs[0], pbattrs); GLXContext ctx = glXCreateNewContext(dpy, dconfigs[0], GLX_RGBA_TYPE, NULL, True); glXMakeCurrent(dpy, pbuffer, ctx); GLuint pbo; glGenBuffers(1, &pbo); glBindBuffer(GL_PIXEL_UNPACK_BUFFER_EXT, pbo); int size = width*height*4; glBufferData(GL_PIXEL_UNPACK_BUFFER_EXT, size, NULL, GL_STREAM_DRAW); void *pixeldata = malloc(size); memset(pixeldata, 0x80, size); double end = 0.2 + get_timestamp(); int iters = 0; do { glBufferSubData(GL_PIXEL_UNPACK_BUFFER_EXT, 0, size, pixeldata); glDrawPixels(width, height, GL_BGRA, GL_UNSIGNED_BYTE, NULL); glXSwapBuffers(dpy, pbuffer); iters++; } while (end > get_timestamp()); free(pixeldata); glDeleteBuffers(1, &pbo); glXDestroyPbuffer(dpy, pbuffer); fprintf(stderr, "%d iters\n", iters); return 0; }