diff options
Diffstat (limited to 'progs/egl/xeglgears.c')
-rw-r--r-- | progs/egl/xeglgears.c | 226 |
1 files changed, 171 insertions, 55 deletions
diff --git a/progs/egl/xeglgears.c b/progs/egl/xeglgears.c index efb63ef3c9..a6a977d9ff 100644 --- a/progs/egl/xeglgears.c +++ b/progs/egl/xeglgears.c @@ -32,6 +32,9 @@ */ +#define GL_GLEXT_PROTOTYPES +#define EGL_EGLEXT_PROTOTYPES + #include <math.h> #include <stdlib.h> #include <stdio.h> @@ -42,6 +45,8 @@ #include <GL/gl.h> #include <EGL/egl.h> +#include <EGL/eglext.h> + #define BENCHMARK @@ -335,9 +340,13 @@ struct egl_manager { EGLSurface win; EGLSurface pix; EGLSurface pbuf; + EGLImageKHR image; EGLBoolean verbose; EGLint major, minor; + + GC gc; + GLuint fbo; }; static struct egl_manager * @@ -469,6 +478,8 @@ egl_manager_create_window(struct egl_manager *eman, const char *name, } } + eman->gc = XCreateGC(eman->xdpy, eman->xwin, 0, NULL); + XMapWindow(eman->xdpy, eman->xwin); return EGL_TRUE; @@ -525,20 +536,28 @@ egl_manager_destroy(struct egl_manager *eman) if (eman->xpix != None) XFreePixmap(eman->xdpy, eman->xpix); + XFreeGC(eman->xdpy, eman->gc); + free(eman); } -enum { GEARS_WINDOW, GEARS_PIXMAP, GEARS_PBUFFER_COPY, GEARS_PBUFFER_TEXTURE }; +enum { + GEARS_WINDOW, + GEARS_PIXMAP, + GEARS_PIXMAP_TEXTURE, + GEARS_PBUFFER, + GEARS_PBUFFER_TEXTURE, + GEARS_RENDERBUFFER +}; static void -texture_gears(struct egl_manager *eman) +texture_gears(struct egl_manager *eman, int surface_type) { static const GLint verts[12] = { -5, -6, -10, 5, -6, -10, -5, 4, 10, 5, 4, 10 }; static const GLint tex_coords[8] = { 0, 0, 1, 0, 0, 1, 1, 1 }; - static const GLuint indices[4] = { 0, 1, 2, 3 }; - eglMakeCurrent(eman->dpy, eman->pix, eman->pix, eman->ctx); + eglMakeCurrent(eman->dpy, eman->win, eman->win, eman->ctx); glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -554,22 +573,42 @@ texture_gears(struct egl_manager *eman) glVertexPointer(3, GL_INT, 0, verts); glTexCoordPointer(2, GL_INT, 0, tex_coords); - eglBindTexImage(eman->dpy, eman->pbuf, EGL_BACK_BUFFER); + if (surface_type == GEARS_PBUFFER_TEXTURE) + eglBindTexImage(eman->dpy, eman->pbuf, EGL_BACK_BUFFER); - glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, indices); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glDisable(GL_TEXTURE_2D); - eglReleaseTexImage(eman->dpy, eman->pbuf, EGL_BACK_BUFFER); + if (surface_type == GEARS_PBUFFER_TEXTURE) + eglReleaseTexImage(eman->dpy, eman->pbuf, EGL_BACK_BUFFER); + + eglSwapBuffers(eman->dpy, eman->win); +} + +static void +copy_gears(struct egl_manager *eman, + EGLint tile_w, EGLint tile_h, EGLint w, EGLint h) +{ + int x, y; + + eglWaitClient(); + + for (x = 0; x < w; x += tile_w) { + for (y = 0; y < h; y += tile_h) { + + XCopyArea(eman->xdpy, eman->xpix, eman->xwin, eman->gc, + 0, 0, tile_w, tile_h, x, y); + } + } } static void event_loop(struct egl_manager *eman, EGLint surface_type, EGLint w, EGLint h) { - GC gc = XCreateGC(eman->xdpy, eman->xwin, 0, NULL); - EGLint orig_w = w, orig_h = h; + int window_w = w, window_h = h; if (surface_type == EGL_PBUFFER_BIT) printf("there will be no screen update if " @@ -584,10 +623,10 @@ event_loop(struct egl_manager *eman, EGLint surface_type, EGLint w, EGLint h) /* we'll redraw below */ break; case ConfigureNotify: - w = event.xconfigure.width; - h = event.xconfigure.height; + window_w = event.xconfigure.width; + window_h = event.xconfigure.height; if (surface_type == EGL_WINDOW_BIT) - reshape(w, h); + reshape(window_w, window_h); break; case KeyPress: { @@ -622,7 +661,6 @@ event_loop(struct egl_manager *eman, EGLint surface_type, EGLint w, EGLint h) static int frames = 0; static double tRot0 = -1.0, tRate0 = -1.0; double dt, t = current_time(); - int x, y; if (tRot0 < 0.0) tRot0 = t; dt = t - tRot0; @@ -633,34 +671,43 @@ event_loop(struct egl_manager *eman, EGLint surface_type, EGLint w, EGLint h) if (angle > 3600.0) angle -= 3600.0; - if (surface_type == GEARS_PBUFFER_TEXTURE) - eglMakeCurrent(eman->dpy, eman->pbuf, eman->pbuf, eman->ctx); - - draw(); switch (surface_type) { case GEARS_WINDOW: + draw(); eglSwapBuffers(eman->dpy, eman->win); break; - case GEARS_PBUFFER_TEXTURE: - case GEARS_PBUFFER_COPY: - if (surface_type == GEARS_PBUFFER_TEXTURE) { - texture_gears(eman); - } else { - if (!eglCopyBuffers(eman->dpy, eman->pbuf, eman->xpix)) - break; - } - eglWaitClient(); - /* fall through */ - case GEARS_PIXMAP: - eglWaitClient(); - for (x = 0; x < w; x += orig_w) { - for (y = 0; y < h; y += orig_h) { - XCopyArea(eman->xdpy, eman->xpix, eman->xwin, gc, - 0, 0, orig_w, orig_h, x, y); - } - } - break; - } + + case GEARS_PBUFFER: + draw(); + if (!eglCopyBuffers(eman->dpy, eman->pbuf, eman->xpix)) + break; + copy_gears(eman, w, h, window_w, window_h); + break; + + case GEARS_PBUFFER_TEXTURE: + eglMakeCurrent(eman->dpy, eman->pbuf, eman->pbuf, eman->ctx); + draw(); + texture_gears(eman, surface_type); + break; + + case GEARS_PIXMAP: + draw(); + copy_gears(eman, w, h, window_w, window_h); + break; + + case GEARS_PIXMAP_TEXTURE: + eglMakeCurrent(eman->dpy, eman->pix, eman->pix, eman->ctx); + draw(); + texture_gears(eman, surface_type); + break; + + case GEARS_RENDERBUFFER: + glBindFramebuffer(GL_FRAMEBUFFER_EXT, eman->fbo); + draw(); + glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0); + texture_gears(eman, surface_type); + break; + } frames++; @@ -676,8 +723,6 @@ event_loop(struct egl_manager *eman, EGLint surface_type, EGLint w, EGLint h) } } } - - XFreeGC(eman->xdpy, gc); } @@ -689,10 +734,20 @@ usage(void) printf(" -fullscreen run in fullscreen mode\n"); printf(" -info display OpenGL renderer info\n"); printf(" -pixmap use pixmap surface\n"); - printf(" -pbuffer-copy use pbuffer surface and eglCopyBuffers\n"); + printf(" -pixmap-texture use pixmap surface and texture using EGLImage\n"); + printf(" -pbuffer use pbuffer surface and eglCopyBuffers\n"); printf(" -pbuffer-texture use pbuffer surface and eglBindTexImage\n"); + printf(" -renderbuffer renderbuffer as EGLImage and bind as texture from\n"); } +static const char *names[] = { + "window", + "pixmap", + "pixmap_texture", + "pbuffer", + "pbuffer_texture", + "renderbuffer" +}; int main(int argc, char *argv[]) @@ -715,6 +770,7 @@ main(int argc, char *argv[]) GLboolean printInfo = GL_FALSE; GLboolean fullscreen = GL_FALSE; EGLBoolean ret; + GLuint texture, color_rb, depth_rb; int i; for (i = 1; i < argc; i++) { @@ -732,14 +788,21 @@ main(int argc, char *argv[]) surface_type = GEARS_PIXMAP; attribs[1] = EGL_PIXMAP_BIT; } - else if (strcmp(argv[i], "-pbuffer-copy") == 0) { - surface_type = GEARS_PBUFFER_COPY; + else if (strcmp(argv[i], "-pixmap-texture") == 0) { + surface_type = GEARS_PIXMAP_TEXTURE; + attribs[1] = EGL_PIXMAP_BIT; + } + else if (strcmp(argv[i], "-pbuffer") == 0) { + surface_type = GEARS_PBUFFER; attribs[1] = EGL_PBUFFER_BIT; } else if (strcmp(argv[i], "-pbuffer-texture") == 0) { surface_type = GEARS_PBUFFER_TEXTURE; attribs[1] = EGL_PBUFFER_BIT; } + else if (strcmp(argv[i], "-renderbuffer") == 0) { + surface_type = GEARS_RENDERBUFFER; + } else { usage(); return -1; @@ -761,28 +824,32 @@ main(int argc, char *argv[]) return -1; } - snprintf(win_title, sizeof(win_title), "xeglgears (%s)", - (surface_type == GEARS_WINDOW) ? "window" : - (surface_type == GEARS_PIXMAP) ? "pixmap" : "pbuffer"); + snprintf(win_title, sizeof(win_title), + "xeglgears (%s)", names[surface_type]); + + ret = egl_manager_create_window(eman, win_title, winWidth, winHeight, + EGL_TRUE, fullscreen, NULL); + if (!ret) + return -1; /* create surface(s) */ switch (surface_type) { case GEARS_WINDOW: - ret = egl_manager_create_window(eman, win_title, winWidth, winHeight, - EGL_TRUE, fullscreen, NULL); if (ret) ret = eglMakeCurrent(eman->dpy, eman->win, eman->win, eman->ctx); break; case GEARS_PIXMAP: - ret = (egl_manager_create_window(eman, win_title, winWidth, winHeight, - EGL_FALSE, fullscreen, NULL) && - egl_manager_create_pixmap(eman, eman->xwin, - EGL_TRUE, NULL)); + case GEARS_PIXMAP_TEXTURE: + ret = egl_manager_create_pixmap(eman, eman->xwin, EGL_TRUE, NULL); + if (surface_type == GEARS_PIXMAP_TEXTURE) + eman->image = eglCreateImageKHR (eman->dpy, eman->ctx, + EGL_NATIVE_PIXMAP_KHR, + (EGLClientBuffer) eman->xpix, NULL); if (ret) ret = eglMakeCurrent(eman->dpy, eman->pix, eman->pix, eman->ctx); break; + case GEARS_PBUFFER: case GEARS_PBUFFER_TEXTURE: - case GEARS_PBUFFER_COPY: { EGLint pbuf_attribs[] = { EGL_WIDTH, winWidth, @@ -791,20 +858,69 @@ main(int argc, char *argv[]) EGL_TEXTURE_TARGET, EGL_TEXTURE_2D, EGL_NONE }; - ret = (egl_manager_create_window(eman, win_title, winWidth, winHeight, - EGL_FALSE, fullscreen, NULL) && - egl_manager_create_pixmap(eman, eman->xwin, + ret = (egl_manager_create_pixmap(eman, eman->xwin, EGL_TRUE, NULL) && egl_manager_create_pbuffer(eman, pbuf_attribs)); if (ret) ret = eglMakeCurrent(eman->dpy, eman->pbuf, eman->pbuf, eman->ctx); } break; + + + case GEARS_RENDERBUFFER: + ret = eglMakeCurrent(eman->dpy, eman->win, eman->win, eman->ctx); + if (ret == EGL_FALSE) + printf("failed to make context current\n"); + + glGenFramebuffers(1, &eman->fbo); + glBindFramebuffer(GL_FRAMEBUFFER_EXT, eman->fbo); + + glGenRenderbuffers(1, &color_rb); + glBindRenderbuffer(GL_RENDERBUFFER_EXT, color_rb); + glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_RGBA, winWidth, winHeight); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, + GL_COLOR_ATTACHMENT0_EXT, + GL_RENDERBUFFER_EXT, + color_rb); + + eman->image = eglCreateImageKHR(eman->dpy, eman->ctx, + EGL_GL_RENDERBUFFER_KHR, + (EGLClientBuffer) color_rb, NULL); + + glGenRenderbuffers(1, &depth_rb); + glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_rb); + glRenderbufferStorage(GL_RENDERBUFFER_EXT, + GL_DEPTH_COMPONENT, winWidth, winHeight); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, + GL_DEPTH_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, + depth_rb); + + if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE) { + printf("framebuffer not complete\n"); + exit(1); + } + + break; + default: ret = EGL_FALSE; break; } + switch (surface_type) { + case GEARS_PIXMAP_TEXTURE: + case GEARS_RENDERBUFFER: + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eman->image); + break; + case GEARS_PBUFFER_TEXTURE: + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + break; + } + if (!ret) { egl_manager_destroy(eman); XCloseDisplay(x_dpy); |