diff --git a/clients/gears.c b/clients/gears.c index 2df79c33..e64ff3e2 100644 --- a/clients/gears.c +++ b/clients/gears.c @@ -30,11 +30,8 @@ #include #include #include -#include #include -#define GL_GLEXT_PROTOTYPES -#define EGL_EGLEXT_PROTOTYPES #include #include #include @@ -51,14 +48,11 @@ struct gears { struct display *d; EGLDisplay display; + EGLDisplay config; EGLContext context; GLfloat angle; - cairo_surface_t *cairo_surface; GLint gear_list[3]; - GLuint fbo, color_rbo[2], depth_rbo; - cairo_surface_t *surface[2]; - int current; }; struct gear_template { @@ -203,55 +197,27 @@ make_gear(const struct gear_template *t) } static void -allocate_buffer(struct gears *gears) +draw_gears(struct gears *gears) { - EGLImageKHR image; + GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0; + struct rectangle window_allocation; struct rectangle allocation; window_draw(gears->window); - gears->surface[gears->current] = window_get_surface(gears->window); -#ifdef HAVE_CAIRO_EGL - image = display_get_image_for_egl_image_surface(gears->display, - gears->surface[gears->current]); -#else /* XXX: hack to make Wayland compile, even if this example doesn't run */ - die("gears cannot allocate buffer: it was compiled without cairo-gl\n"); - return; -#endif - if (!eglMakeCurrent(gears->display, NULL, NULL, gears->context)) - die("faile to make context current\n"); - - glBindRenderbuffer(GL_RENDERBUFFER_EXT, - gears->color_rbo[gears->current]); - glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, image); - - glBindRenderbuffer(GL_RENDERBUFFER_EXT, gears->depth_rbo); window_get_child_allocation(gears->window, &allocation); - glRenderbufferStorage(GL_RENDERBUFFER_EXT, - GL_DEPTH_COMPONENT, - allocation.width + 20 + 32, - allocation.height + 60 + 32); -} + window_get_allocation(gears->window, &window_allocation); -static void -draw_gears(struct gears *gears) -{ - GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0; - struct rectangle allocation; - - if (gears->surface[gears->current] == NULL) - allocate_buffer(gears); - - glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - GL_RENDERBUFFER_EXT, - gears->color_rbo[gears->current]); - - window_get_child_allocation(gears->window, &allocation); - glViewport(allocation.x, allocation.y, - allocation.width, allocation.height); - glScissor(allocation.x, allocation.y, + display_acquire_window_surface(gears->d, + gears->window, + gears->context); + + glViewport(allocation.x, + window_allocation.height - allocation.height - allocation.x, allocation.width, allocation.height); + glScissor(allocation.x, + window_allocation.height - allocation.height - allocation.y, + allocation.width, allocation.height); glEnable(GL_SCISSOR_TEST); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -286,7 +252,7 @@ draw_gears(struct gears *gears) glFlush(); - window_set_surface(gears->window, gears->surface[gears->current]); + display_release(gears->d); window_flush(gears->window); } @@ -296,11 +262,6 @@ resize_handler(struct window *window, { struct gears *gears = data; - cairo_surface_destroy(gears->surface[0]); - gears->surface[0] = NULL; - cairo_surface_destroy(gears->surface[1]); - gears->surface[1] = NULL; - /* Constrain child size to be square and at least 300x300 */ if (width > height) height = width; @@ -338,8 +299,6 @@ frame_callback(void *data, uint32_t time) { struct gears *gears = data; - gears->current = 1 - gears->current; - gears->angle = (GLfloat) (time % 8192) * 360 / 8192.0; window_schedule_redraw(gears->window); @@ -359,7 +318,6 @@ gears_create(struct display *display) gears->d = display; gears->window = window_create(display, width, height); window_set_title(gears->window, "Wayland Gears"); - window_set_buffer_type(gears->window, WINDOW_BUFFER_TYPE_EGL_IMAGE); gears->display = display_get_egl_display(gears->d); if (gears->display == NULL) @@ -367,24 +325,16 @@ gears_create(struct display *display) eglBindAPI(EGL_OPENGL_API); - gears->context = eglCreateContext(gears->display, - NULL, EGL_NO_CONTEXT, NULL); + gears->config = display_get_egl_config(gears->d); + + gears->context = eglCreateContext(gears->display, gears->config, + EGL_NO_CONTEXT, NULL); if (gears->context == NULL) die("failed to create context\n"); if (!eglMakeCurrent(gears->display, NULL, NULL, gears->context)) die("faile to make context current\n"); - glGenFramebuffers(1, &gears->fbo); - glBindFramebuffer(GL_FRAMEBUFFER_EXT, gears->fbo); - - glGenRenderbuffers(2, gears->color_rbo); - glGenRenderbuffers(1, &gears->depth_rbo); - glBindRenderbuffer(GL_RENDERBUFFER_EXT, gears->depth_rbo); - glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, - GL_DEPTH_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, - gears->depth_rbo); for (i = 0; i < 3; i++) { gears->gear_list[i] = glGenLists(1); glNewList(gears->gear_list[i], GL_COMPILE); diff --git a/clients/window.c b/clients/window.c index 4792710c..6e7ef9b2 100644 --- a/clients/window.c +++ b/clients/window.c @@ -870,7 +870,10 @@ window_draw_decorations(struct window *window) cairo_destroy(cr); + /* FIXME: this breakes gears, fix cairo? */ +#if 0 cairo_device_flush (window->display->device); +#endif } void @@ -1260,6 +1263,13 @@ static const struct wl_shell_listener shell_listener = { handle_configure, }; +void +window_get_allocation(struct window *window, + struct rectangle *allocation) +{ + *allocation = window->allocation; +} + void window_get_child_allocation(struct window *window, struct rectangle *allocation) @@ -1850,12 +1860,47 @@ display_get_egl_display(struct display *d) return d->dpy; } +EGLConfig +display_get_egl_config(struct display *d) +{ + return d->conf; +} + struct wl_shell * display_get_shell(struct display *display) { return display->shell; } +void +display_acquire_window_surface(struct display *display, + struct window *window, + EGLContext ctx) +{ + struct egl_window_surface_data *data; + + if (!window->cairo_surface) + return; + + if (!ctx) + ctx = display->ctx; + + data = cairo_surface_get_user_data(window->cairo_surface, + &surface_data_key); + + cairo_device_acquire(display->device); + if (!eglMakeCurrent(display->dpy, data->surf, data->surf, ctx)) + fprintf(stderr, "failed to make surface current\n"); +} + +void +display_release(struct display *display) +{ + if (!eglMakeCurrent(display->dpy, NULL, NULL, display->ctx)) + fprintf(stderr, "failed to make context current\n"); + cairo_device_release(display->device); +} + void display_run(struct display *d) { diff --git a/clients/window.h b/clients/window.h index c1c5212e..538ff07e 100644 --- a/clients/window.h +++ b/clients/window.h @@ -26,6 +26,7 @@ #include #include #include +#include struct window; @@ -55,6 +56,16 @@ display_get_shell(struct display *display); EGLDisplay display_get_egl_display(struct display *d); +EGLConfig +display_get_egl_config(struct display *d); + +void +display_acquire_window_surface(struct display *display, + struct window *window, + EGLContext ctx); +void +display_release(struct display *display); + #ifdef HAVE_CAIRO_EGL EGLImageKHR display_get_image_for_egl_image_surface(struct display *display, @@ -142,6 +153,11 @@ window_move(struct window *window, struct input *input, uint32_t time); void window_draw(struct window *window); + +void +window_get_allocation(struct window *window, + struct rectangle *allocation); + void window_get_child_allocation(struct window *window, struct rectangle *allocation);