summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Franzke <benjaminfranzke@googlemail.com>2011-02-18 23:00:55 +0100
committerBenjamin Franzke <benjaminfranzke@googlemail.com>2011-03-17 15:55:25 +0100
commitcff904e69d28f05a97105502bfcb027adac247b5 (patch)
tree7f7bae9a0db81464fdff1877ee5309446f8e4222
parent6693ac21088618d1a33391550fdd4d4521171018 (diff)
gears: Use wayland egl surface instead of images
-rw-r--r--clients/gears.c88
-rw-r--r--clients/window.c45
-rw-r--r--clients/window.h16
3 files changed, 80 insertions, 69 deletions
diff --git a/clients/gears.c b/clients/gears.c
index 2df79c3..e64ff3e 100644
--- a/clients/gears.c
+++ b/clients/gears.c
@@ -30,11 +30,8 @@
#include <unistd.h>
#include <math.h>
#include <time.h>
-#include <cairo.h>
#include <glib.h>
-#define GL_GLEXT_PROTOTYPES
-#define EGL_EGLEXT_PROTOTYPES
#include <GL/gl.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
@@ -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)
-{
- EGLImageKHR image;
- 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);
-}
-
-static void
draw_gears(struct gears *gears)
{
GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
+ struct rectangle window_allocation;
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_draw(gears->window);
window_get_child_allocation(gears->window, &allocation);
- glViewport(allocation.x, allocation.y,
- allocation.width, allocation.height);
- glScissor(allocation.x, allocation.y,
+ window_get_allocation(gears->window, &window_allocation);
+
+ 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 4792710..6e7ef9b 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
@@ -1261,6 +1264,13 @@ static const struct wl_shell_listener shell_listener = {
};
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,6 +1860,12 @@ 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)
{
@@ -1857,6 +1873,35 @@ display_get_shell(struct display *display)
}
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)
{
g_main_loop_run(d->loop);
diff --git a/clients/window.h b/clients/window.h
index c1c5212..538ff07 100644
--- a/clients/window.h
+++ b/clients/window.h
@@ -26,6 +26,7 @@
#include <X11/extensions/XKBcommon.h>
#include <glib.h>
#include <wayland-client.h>
+#include <cairo.h>
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);