diff options
author | Kristian Høgsberg <krh@bitplanet.net> | 2010-01-24 18:10:15 -0500 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2010-01-24 18:10:15 -0500 |
commit | a341fa016c54948af4fc76cde864f460f962f9db (patch) | |
tree | e03749a18af66b568b5872298cdc29eded71b877 | |
parent | 450cc8136d5c3c84407b3c621006a1fa6b092085 (diff) |
Use FBOs instead of eagle-specific API
-rw-r--r-- | Makefile.in | 7 | ||||
-rw-r--r-- | gears.c | 96 | ||||
-rw-r--r-- | image.c | 12 | ||||
-rw-r--r-- | terminal.c | 2 | ||||
-rw-r--r-- | wayland-system-compositor.c | 111 | ||||
-rw-r--r-- | window.c | 32 | ||||
-rw-r--r-- | window.h | 2 |
7 files changed, 130 insertions, 132 deletions
diff --git a/Makefile.in b/Makefile.in index cc66c61..3f666e2 100644 --- a/Makefile.in +++ b/Makefile.in | |||
@@ -8,8 +8,9 @@ libs = libwayland-server.so libwayland.so | |||
8 | egl_clients = gears | 8 | egl_clients = gears |
9 | cairo_clients = flower screenshot terminal image view | 9 | cairo_clients = flower screenshot terminal image view |
10 | compositors = wayland-system-compositor | 10 | compositors = wayland-system-compositor |
11 | clients = $(egl_clients) $(cairo_clients) | ||
11 | 12 | ||
12 | all : $(libs) $(compositors) $(egl_clients) $(cairo_clients) | 13 | all : $(libs) $(compositors) $(clients) |
13 | 14 | ||
14 | libwayland-server.so : \ | 15 | libwayland-server.so : \ |
15 | wayland.o \ | 16 | wayland.o \ |
@@ -36,7 +37,7 @@ wayland-system-compositor : \ | |||
36 | wayland-util.o | 37 | wayland-util.o |
37 | 38 | ||
38 | wayland-system-compositor : CFLAGS += @EGL_COMPOSITOR_CFLAGS@ | 39 | wayland-system-compositor : CFLAGS += @EGL_COMPOSITOR_CFLAGS@ |
39 | wayland-system-compositor : LDLIBS += -L. -lwayland-server @EGL_COMPOSITOR_LIBS@ -rdynamic -lrt | 40 | wayland-system-compositor : LDLIBS += ./libwayland-server.so @EGL_COMPOSITOR_LIBS@ -rdynamic -lrt |
40 | 41 | ||
41 | flower : flower.o wayland-glib.o | 42 | flower : flower.o wayland-glib.o |
42 | gears : gears.o window.o wayland-glib.o cairo-util.o | 43 | gears : gears.o window.o wayland-glib.o cairo-util.o |
@@ -54,7 +55,7 @@ view : LDLIBS += @POPPLER_LIBS@ | |||
54 | $(egl_clients) : CFLAGS += @EGL_CLIENT_CFLAGS@ | 55 | $(egl_clients) : CFLAGS += @EGL_CLIENT_CFLAGS@ |
55 | $(egl_clients) : LDLIBS += -L. -lwayland @EGL_CLIENT_LIBS@ -lrt | 56 | $(egl_clients) : LDLIBS += -L. -lwayland @EGL_CLIENT_LIBS@ -lrt |
56 | $(cairo_clients) : CFLAGS += @CAIRO_CLIENT_CFLAGS@ | 57 | $(cairo_clients) : CFLAGS += @CAIRO_CLIENT_CFLAGS@ |
57 | $(cairo_clients) : LDLIBS += -L. -lwayland @CAIRO_CLIENT_LIBS@ -lrt | 58 | $(cairo_clients) : LDLIBS += ./libwayland.so @CAIRO_CLIENT_LIBS@ -lrt |
58 | 59 | ||
59 | install : $(libs) $(compositors) | 60 | install : $(libs) $(compositors) |
60 | install -d @libdir@ @libdir@/pkgconfig ${udev_rules_dir} | 61 | install -d @libdir@ @libdir@/pkgconfig ${udev_rules_dir} |
@@ -32,6 +32,7 @@ | |||
32 | #include <glib.h> | 32 | #include <glib.h> |
33 | #include <cairo-drm.h> | 33 | #include <cairo-drm.h> |
34 | 34 | ||
35 | #define GL_GLEXT_PROTOTYPES | ||
35 | #include <GL/gl.h> | 36 | #include <GL/gl.h> |
36 | #include <eagle.h> | 37 | #include <eagle.h> |
37 | 38 | ||
@@ -52,14 +53,13 @@ struct gears { | |||
52 | struct rectangle rectangle; | 53 | struct rectangle rectangle; |
53 | 54 | ||
54 | EGLDisplay display; | 55 | EGLDisplay display; |
55 | EGLConfig config; | ||
56 | EGLSurface surface; | ||
57 | EGLContext context; | 56 | EGLContext context; |
58 | int resized; | 57 | int resized; |
59 | GLfloat angle; | 58 | GLfloat angle; |
60 | cairo_surface_t *cairo_surface; | 59 | cairo_surface_t *cairo_surface; |
61 | 60 | ||
62 | GLint gear_list[3]; | 61 | GLint gear_list[3]; |
62 | GLuint fbo, color_rbo, depth_rbo; | ||
63 | }; | 63 | }; |
64 | 64 | ||
65 | struct gear_template { | 65 | struct gear_template { |
@@ -258,19 +258,20 @@ resize_window(struct gears *gears) | |||
258 | 258 | ||
259 | window_draw(gears->window); | 259 | window_draw(gears->window); |
260 | 260 | ||
261 | if (gears->surface != NULL) | 261 | glBindRenderbuffer(GL_RENDERBUFFER_EXT, gears->color_rbo); |
262 | eglDestroySurface(gears->display, gears->surface); | 262 | glRenderbufferStorage(GL_RENDERBUFFER_EXT, |
263 | GL_RGBA, | ||
264 | gears->rectangle.width, | ||
265 | gears->rectangle.height); | ||
263 | 266 | ||
264 | gears->surface = eglCreateSurface(gears->display, | 267 | glBindRenderbuffer(GL_RENDERBUFFER_EXT, gears->depth_rbo); |
265 | gears->config, | 268 | glRenderbufferStorage(GL_RENDERBUFFER_EXT, |
266 | gears->rectangle.width, | 269 | GL_DEPTH_COMPONENT, |
267 | gears->rectangle.height, | 270 | gears->rectangle.width, |
268 | 1, NULL); | 271 | gears->rectangle.height); |
269 | |||
270 | eglMakeCurrent(gears->display, | ||
271 | gears->surface, gears->surface, gears->context); | ||
272 | 272 | ||
273 | glViewport(0, 0, gears->rectangle.width, gears->rectangle.height); | 273 | glViewport(0, 0, gears->rectangle.width, gears->rectangle.height); |
274 | |||
274 | gears->resized = 0; | 275 | gears->resized = 0; |
275 | } | 276 | } |
276 | 277 | ||
@@ -308,13 +309,12 @@ handle_acknowledge(void *data, | |||
308 | { | 309 | { |
309 | struct gears *gears = data; | 310 | struct gears *gears = data; |
310 | 311 | ||
311 | if (key != 0) | 312 | if (key == 10) { |
312 | return; | 313 | if (gears->resized) |
314 | resize_window(gears); | ||
313 | 315 | ||
314 | if (gears->resized) | 316 | draw_gears(gears); |
315 | resize_window(gears); | 317 | } |
316 | |||
317 | draw_gears(gears); | ||
318 | } | 318 | } |
319 | 319 | ||
320 | static void | 320 | static void |
@@ -322,14 +322,20 @@ handle_frame(void *data, | |||
322 | struct wl_compositor *compositor, | 322 | struct wl_compositor *compositor, |
323 | uint32_t frame, uint32_t timestamp) | 323 | uint32_t frame, uint32_t timestamp) |
324 | { | 324 | { |
325 | struct gears *gears = data; | 325 | struct gears *gears = data; |
326 | uint32_t name, handle, stride; | 326 | GLint name, stride; |
327 | 327 | ||
328 | eglGetColorBuffer(gears->surface, 0, &name, &handle, &stride); | 328 | glBindRenderbuffer(GL_RENDERBUFFER_EXT, gears->color_rbo); |
329 | glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, | ||
330 | GL_RENDERBUFFER_STRIDE_INTEL, | ||
331 | &stride); | ||
332 | glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, | ||
333 | GL_RENDERBUFFER_NAME_INTEL, | ||
334 | &name); | ||
329 | 335 | ||
330 | window_copy(gears->window, &gears->rectangle, name, stride); | 336 | window_copy(gears->window, &gears->rectangle, name, stride); |
331 | 337 | ||
332 | wl_compositor_commit(gears->compositor, 0); | 338 | window_commit(gears->window, 10); |
333 | 339 | ||
334 | gears->angle = (GLfloat) (timestamp % 8192) * 360 / 8192.0; | 340 | gears->angle = (GLfloat) (timestamp % 8192) * 360 / 8192.0; |
335 | } | 341 | } |
@@ -339,19 +345,11 @@ static const struct wl_compositor_listener compositor_listener = { | |||
339 | handle_frame, | 345 | handle_frame, |
340 | }; | 346 | }; |
341 | 347 | ||
342 | static const EGLint config_attribs[] = { | ||
343 | EGL_DEPTH_SIZE, 24, | ||
344 | EGL_CONFIG_CAVEAT, EGL_NONE, | ||
345 | EGL_RED_SIZE, 8, | ||
346 | EGL_NONE | ||
347 | }; | ||
348 | |||
349 | static struct gears * | 348 | static struct gears * |
350 | gears_create(struct display *display) | 349 | gears_create(struct display *display) |
351 | { | 350 | { |
352 | const int x = 200, y = 200, width = 450, height = 500; | 351 | const int x = 200, y = 200, width = 450, height = 500; |
353 | EGLint major, minor, count; | 352 | EGLint major, minor; |
354 | EGLConfig configs[64]; | ||
355 | struct udev *udev; | 353 | struct udev *udev; |
356 | struct udev_device *device; | 354 | struct udev_device *device; |
357 | struct gears *gears; | 355 | struct gears *gears; |
@@ -373,18 +371,29 @@ gears_create(struct display *display) | |||
373 | if (!eglInitialize(gears->display, &major, &minor)) | 371 | if (!eglInitialize(gears->display, &major, &minor)) |
374 | die("failed to initialize display\n"); | 372 | die("failed to initialize display\n"); |
375 | 373 | ||
376 | if (!eglGetConfigs(gears->display, configs, 64, &count)) | 374 | gears->context = eglCreateContext(gears->display, NULL, NULL, NULL); |
377 | die("failed to get configs\n"); | ||
378 | |||
379 | if (!eglChooseConfig(gears->display, config_attribs, &gears->config, 1, NULL)) | ||
380 | die("failed to pick a config\n"); | ||
381 | |||
382 | gears->context = eglCreateContext(gears->display, gears->config, NULL, NULL); | ||
383 | if (gears->context == NULL) | 375 | if (gears->context == NULL) |
384 | die("failed to create context\n"); | 376 | die("failed to create context\n"); |
385 | 377 | ||
386 | resize_window(gears); | 378 | if (!eglMakeCurrent(gears->display, NULL, NULL, gears->context)) |
387 | 379 | die("faile to make context current\n"); | |
380 | |||
381 | glGenFramebuffers(1, &gears->fbo); | ||
382 | glBindFramebuffer(GL_FRAMEBUFFER_EXT, gears->fbo); | ||
383 | |||
384 | glGenRenderbuffers(1, &gears->color_rbo); | ||
385 | glBindRenderbuffer(GL_RENDERBUFFER_EXT, gears->color_rbo); | ||
386 | glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, | ||
387 | GL_COLOR_ATTACHMENT0_EXT, | ||
388 | GL_RENDERBUFFER_EXT, | ||
389 | gears->color_rbo); | ||
390 | |||
391 | glGenRenderbuffers(1, &gears->depth_rbo); | ||
392 | glBindRenderbuffer(GL_RENDERBUFFER_EXT, gears->depth_rbo); | ||
393 | glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, | ||
394 | GL_DEPTH_ATTACHMENT_EXT, | ||
395 | GL_RENDERBUFFER_EXT, | ||
396 | gears->depth_rbo); | ||
388 | for (i = 0; i < 3; i++) { | 397 | for (i = 0; i < 3; i++) { |
389 | gears->gear_list[i] = glGenLists(1); | 398 | gears->gear_list[i] = glGenLists(1); |
390 | glNewList(gears->gear_list[i], GL_COMPILE); | 399 | glNewList(gears->gear_list[i], GL_COMPILE); |
@@ -406,10 +415,13 @@ gears_create(struct display *display) | |||
406 | glEnable(GL_DEPTH_TEST); | 415 | glEnable(GL_DEPTH_TEST); |
407 | glClearColor(0, 0, 0, 0.92); | 416 | glClearColor(0, 0, 0, 0.92); |
408 | 417 | ||
418 | if (glCheckFramebufferStatus (GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE) | ||
419 | fprintf(stderr, "framebuffer incomplete\n"); | ||
420 | |||
409 | gears->compositor = display_get_compositor(display); | 421 | gears->compositor = display_get_compositor(display); |
410 | 422 | ||
423 | resize_window(gears); | ||
411 | draw_gears(gears); | 424 | draw_gears(gears); |
412 | |||
413 | handle_frame(gears, gears->compositor, 0, 0); | 425 | handle_frame(gears, gears->compositor, 0, 0); |
414 | 426 | ||
415 | window_set_resize_handler(gears->window, resize_handler, gears); | 427 | window_set_resize_handler(gears->window, resize_handler, gears); |
@@ -184,7 +184,7 @@ image_draw(struct image *image) | |||
184 | &rectangle, | 184 | &rectangle, |
185 | image->surface); | 185 | image->surface); |
186 | 186 | ||
187 | wl_compositor_commit(image->compositor, image->key); | 187 | window_commit(image->window, image->key); |
188 | } | 188 | } |
189 | 189 | ||
190 | static gboolean | 190 | static gboolean |
@@ -217,6 +217,15 @@ resize_handler(struct window *window, void *data) | |||
217 | } | 217 | } |
218 | 218 | ||
219 | static void | 219 | static void |
220 | keyboard_focus_handler(struct window *window, | ||
221 | struct wl_input_device *device, void *data) | ||
222 | { | ||
223 | struct image *image = data; | ||
224 | |||
225 | image_schedule_redraw(image); | ||
226 | } | ||
227 | |||
228 | static void | ||
220 | handle_acknowledge(void *data, | 229 | handle_acknowledge(void *data, |
221 | struct wl_compositor *compositor, | 230 | struct wl_compositor *compositor, |
222 | uint32_t key, uint32_t frame) | 231 | uint32_t key, uint32_t frame) |
@@ -274,6 +283,7 @@ image_create(struct display *display, uint32_t key, const char *filename) | |||
274 | 283 | ||
275 | image->compositor = display_get_compositor(display); | 284 | image->compositor = display_get_compositor(display); |
276 | window_set_resize_handler(image->window, resize_handler, image); | 285 | window_set_resize_handler(image->window, resize_handler, image); |
286 | window_set_keyboard_focus_handler(image->window, keyboard_focus_handler, image); | ||
277 | 287 | ||
278 | wl_compositor_add_listener(image->compositor, &compositor_listener, image); | 288 | wl_compositor_add_listener(image->compositor, &compositor_listener, image); |
279 | 289 | ||
@@ -227,7 +227,7 @@ terminal_draw(struct terminal *terminal) | |||
227 | 227 | ||
228 | window_draw(terminal->window); | 228 | window_draw(terminal->window); |
229 | terminal_draw_contents(terminal); | 229 | terminal_draw_contents(terminal); |
230 | wl_compositor_commit(terminal->compositor, 0); | 230 | window_commit(terminal->window, 0); |
231 | } | 231 | } |
232 | 232 | ||
233 | static gboolean | 233 | static gboolean |
diff --git a/wayland-system-compositor.c b/wayland-system-compositor.c index 74b7f0a..851398c 100644 --- a/wayland-system-compositor.c +++ b/wayland-system-compositor.c | |||
@@ -69,13 +69,13 @@ struct wlsc_output { | |||
69 | struct wl_list link; | 69 | struct wl_list link; |
70 | struct wlsc_compositor *compositor; | 70 | struct wlsc_compositor *compositor; |
71 | struct wlsc_surface *background; | 71 | struct wlsc_surface *background; |
72 | EGLSurface surface; | ||
73 | int32_t x, y, width, height; | 72 | int32_t x, y, width, height; |
74 | 73 | ||
75 | drmModeModeInfo mode; | 74 | drmModeModeInfo mode; |
76 | uint32_t crtc_id; | 75 | uint32_t crtc_id; |
77 | uint32_t connector_id; | 76 | uint32_t connector_id; |
78 | 77 | ||
78 | GLuint rbo[2]; | ||
79 | uint32_t fb_id[2]; | 79 | uint32_t fb_id[2]; |
80 | uint32_t current; | 80 | uint32_t current; |
81 | }; | 81 | }; |
@@ -102,7 +102,7 @@ struct wlsc_compositor { | |||
102 | 102 | ||
103 | EGLDisplay display; | 103 | EGLDisplay display; |
104 | EGLContext context; | 104 | EGLContext context; |
105 | EGLConfig config; | 105 | GLuint fbo; |
106 | struct wl_display *wl_display; | 106 | struct wl_display *wl_display; |
107 | 107 | ||
108 | struct wl_list output_list; | 108 | struct wl_list output_list; |
@@ -610,16 +610,11 @@ repaint_output(struct wlsc_output *output) | |||
610 | double s = 3000; | 610 | double s = 3000; |
611 | int fd; | 611 | int fd; |
612 | 612 | ||
613 | if (!eglMakeCurrent(ec->display, output->surface, output->surface, ec->context)) { | ||
614 | fprintf(stderr, "failed to make context current\n"); | ||
615 | return; | ||
616 | } | ||
617 | |||
618 | glViewport(0, 0, output->width, output->height); | 613 | glViewport(0, 0, output->width, output->height); |
619 | glMatrixMode(GL_PROJECTION); | 614 | glMatrixMode(GL_PROJECTION); |
620 | glLoadIdentity(); | 615 | glLoadIdentity(); |
621 | glFrustum(-output->width / s, output->width / s, | 616 | glFrustum(-output->width / s, output->width / s, |
622 | output->height / s, -output->height / s, 1, 2 * s); | 617 | -output->height / s, output->height / s, 1, 2 * s); |
623 | glMatrixMode(GL_MODELVIEW); | 618 | glMatrixMode(GL_MODELVIEW); |
624 | glLoadIdentity(); | 619 | glLoadIdentity(); |
625 | glClearColor(0, 0, 0, 1); | 620 | glClearColor(0, 0, 0, 1); |
@@ -650,7 +645,11 @@ repaint_output(struct wlsc_output *output) | |||
650 | 645 | ||
651 | fd = eglGetDisplayFD(ec->display); | 646 | fd = eglGetDisplayFD(ec->display); |
652 | output->current ^= 1; | 647 | output->current ^= 1; |
653 | eglBindColorBuffer(ec->display, output->surface, output->current); | 648 | |
649 | glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, | ||
650 | GL_COLOR_ATTACHMENT0_EXT, | ||
651 | GL_RENDERBUFFER_EXT, | ||
652 | output->rbo[output->current]); | ||
654 | drmModePageFlip(fd, output->crtc_id, | 653 | drmModePageFlip(fd, output->crtc_id, |
655 | output->fb_id[output->current ^ 1], | 654 | output->fb_id[output->current ^ 1], |
656 | DRM_MODE_PAGE_FLIP_EVENT, output); | 655 | DRM_MODE_PAGE_FLIP_EVENT, output); |
@@ -737,8 +736,8 @@ surface_attach(struct wl_client *client, | |||
737 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_REPEAT); | 736 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_REPEAT); |
738 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 737 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
739 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 738 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
740 | glTextureExternalMESA(GL_TEXTURE_2D, GL_RGBA, 4, | 739 | glTextureExternalINTEL(GL_TEXTURE_2D, GL_RGBA, 4, |
741 | width, height, stride / 4, name); | 740 | width, height, stride / 4, name); |
742 | 741 | ||
743 | } | 742 | } |
744 | 743 | ||
@@ -762,36 +761,6 @@ surface_copy(struct wl_client *client, | |||
762 | uint32_t name, uint32_t stride, | 761 | uint32_t name, uint32_t stride, |
763 | int32_t x, int32_t y, int32_t width, int32_t height) | 762 | int32_t x, int32_t y, int32_t width, int32_t height) |
764 | { | 763 | { |
765 | struct wlsc_surface *es = (struct wlsc_surface *) surface; | ||
766 | GLuint fbo[2], rb; | ||
767 | |||
768 | glGenFramebuffers(2, fbo); | ||
769 | |||
770 | glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, fbo[1]); | ||
771 | glGenRenderbuffers(1, &rb); | ||
772 | glBindRenderbuffer(GL_RENDERBUFFER_EXT, rb); | ||
773 | glRenderbufferExternalMESA(GL_RENDERBUFFER_EXT, | ||
774 | GL_RGBA, | ||
775 | es->width, es->height, | ||
776 | stride / 4, name); | ||
777 | glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER_EXT, | ||
778 | GL_COLOR_ATTACHMENT0_EXT, | ||
779 | GL_RENDERBUFFER_EXT, | ||
780 | rb); | ||
781 | |||
782 | glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, fbo[0]); | ||
783 | glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER_EXT, | ||
784 | GL_COLOR_ATTACHMENT0_EXT, | ||
785 | GL_TEXTURE_2D, es->texture, 0); | ||
786 | |||
787 | glBlitFramebuffer(x, y, x + width, y + height, | ||
788 | dst_x, dst_y, dst_x+ width, dst_y + height, | ||
789 | GL_COLOR_BUFFER_BIT, GL_NEAREST); | ||
790 | |||
791 | glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0); | ||
792 | glBindRenderbuffer(GL_RENDERBUFFER_EXT, 0); | ||
793 | glDeleteRenderbuffers(1, &rb); | ||
794 | glDeleteFramebuffers(2, fbo); | ||
795 | } | 764 | } |
796 | 765 | ||
797 | static void | 766 | static void |
@@ -1138,14 +1107,6 @@ on_drm_input(int fd, uint32_t mask, void *data) | |||
1138 | static int | 1107 | static int |
1139 | init_egl(struct wlsc_compositor *ec, struct udev_device *device) | 1108 | init_egl(struct wlsc_compositor *ec, struct udev_device *device) |
1140 | { | 1109 | { |
1141 | static const EGLint config_attribs[] = { | ||
1142 | EGL_DEPTH_SIZE, 0, | ||
1143 | EGL_STENCIL_SIZE, 0, | ||
1144 | EGL_CONFIG_CAVEAT, EGL_NONE, | ||
1145 | EGL_RED_SIZE, 8, | ||
1146 | EGL_NONE | ||
1147 | }; | ||
1148 | |||
1149 | struct wl_event_loop *loop; | 1110 | struct wl_event_loop *loop; |
1150 | EGLint major, minor; | 1111 | EGLint major, minor; |
1151 | int fd; | 1112 | int fd; |
@@ -1161,15 +1122,20 @@ init_egl(struct wlsc_compositor *ec, struct udev_device *device) | |||
1161 | return -1; | 1122 | return -1; |
1162 | } | 1123 | } |
1163 | 1124 | ||
1164 | if (!eglChooseConfig(ec->display, config_attribs, &ec->config, 1, NULL)) | 1125 | ec->context = eglCreateContext(ec->display, NULL, NULL, NULL); |
1165 | return -1; | ||
1166 | |||
1167 | ec->context = eglCreateContext(ec->display, ec->config, NULL, NULL); | ||
1168 | if (ec->context == NULL) { | 1126 | if (ec->context == NULL) { |
1169 | fprintf(stderr, "failed to create context\n"); | 1127 | fprintf(stderr, "failed to create context\n"); |
1170 | return -1; | 1128 | return -1; |
1171 | } | 1129 | } |
1172 | 1130 | ||
1131 | if (!eglMakeCurrent(ec->display, EGL_NO_SURFACE, EGL_NO_SURFACE, ec->context)) { | ||
1132 | fprintf(stderr, "failed to make context current\n"); | ||
1133 | return -1; | ||
1134 | } | ||
1135 | |||
1136 | glGenFramebuffers(1, &ec->fbo); | ||
1137 | glBindFramebuffer(GL_FRAMEBUFFER_EXT, ec->fbo); | ||
1138 | |||
1173 | loop = wl_display_get_event_loop(ec->wl_display); | 1139 | loop = wl_display_get_event_loop(ec->wl_display); |
1174 | fd = eglGetDisplayFD(ec->display); | 1140 | fd = eglGetDisplayFD(ec->display); |
1175 | ec->drm_source = | 1141 | ec->drm_source = |
@@ -1197,7 +1163,7 @@ create_output_for_connector(struct wlsc_compositor *ec, | |||
1197 | struct wlsc_output *output; | 1163 | struct wlsc_output *output; |
1198 | drmModeEncoder *encoder; | 1164 | drmModeEncoder *encoder; |
1199 | drmModeModeInfo *mode; | 1165 | drmModeModeInfo *mode; |
1200 | uint32_t name, handle, stride; | 1166 | GLint handle, stride; |
1201 | int i, ret, fd; | 1167 | int i, ret, fd; |
1202 | 1168 | ||
1203 | fd = eglGetDisplayFD(ec->display); | 1169 | fd = eglGetDisplayFD(ec->display); |
@@ -1243,21 +1209,21 @@ create_output_for_connector(struct wlsc_compositor *ec, | |||
1243 | 1209 | ||
1244 | drmModeFreeEncoder(encoder); | 1210 | drmModeFreeEncoder(encoder); |
1245 | 1211 | ||
1246 | output->surface = eglCreateSurface(ec->display, | 1212 | glGenRenderbuffers(2, output->rbo); |
1247 | ec->config, | ||
1248 | output->width, | ||
1249 | output->height, | ||
1250 | 2, NULL); | ||
1251 | if (output->surface == NULL) { | ||
1252 | fprintf(stderr, "failed to create surface\n"); | ||
1253 | return -1; | ||
1254 | } | ||
1255 | |||
1256 | for (i = 0; i < 2; i++) { | 1213 | for (i = 0; i < 2; i++) { |
1257 | eglGetColorBuffer(output->surface, | 1214 | glBindRenderbuffer(GL_RENDERBUFFER_EXT, output->rbo[i]); |
1258 | i, &name, &handle, &stride); | 1215 | glRenderbufferStorage(GL_RENDERBUFFER_EXT, |
1259 | 1216 | GL_RGBA, | |
1260 | ret = drmModeAddFB(fd, mode->hdisplay, mode->vdisplay, | 1217 | output->width, |
1218 | output->height); | ||
1219 | glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, | ||
1220 | GL_RENDERBUFFER_STRIDE_INTEL, | ||
1221 | &stride); | ||
1222 | glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, | ||
1223 | GL_RENDERBUFFER_HANDLE_INTEL, | ||
1224 | &handle); | ||
1225 | |||
1226 | ret = drmModeAddFB(fd, output->width, output->height, | ||
1261 | 32, 32, stride, handle, &output->fb_id[i]); | 1227 | 32, 32, stride, handle, &output->fb_id[i]); |
1262 | if (ret) { | 1228 | if (ret) { |
1263 | fprintf(stderr, "failed to add fb %d: %m\n", i); | 1229 | fprintf(stderr, "failed to add fb %d: %m\n", i); |
@@ -1266,6 +1232,10 @@ create_output_for_connector(struct wlsc_compositor *ec, | |||
1266 | } | 1232 | } |
1267 | 1233 | ||
1268 | output->current = 0; | 1234 | output->current = 0; |
1235 | glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, | ||
1236 | GL_COLOR_ATTACHMENT0_EXT, | ||
1237 | GL_RENDERBUFFER_EXT, | ||
1238 | output->rbo[output->current]); | ||
1269 | ret = drmModeSetCrtc(fd, output->crtc_id, | 1239 | ret = drmModeSetCrtc(fd, output->crtc_id, |
1270 | output->fb_id[output->current ^ 1], 0, 0, | 1240 | output->fb_id[output->current ^ 1], 0, 0, |
1271 | &output->connector_id, 1, &output->mode); | 1241 | &output->connector_id, 1, &output->mode); |
@@ -1279,11 +1249,6 @@ create_output_for_connector(struct wlsc_compositor *ec, | |||
1279 | wl_display_add_global(ec->wl_display, &output->base, post_output_geometry); | 1249 | wl_display_add_global(ec->wl_display, &output->base, post_output_geometry); |
1280 | wl_list_insert(ec->output_list.prev, &output->link); | 1250 | wl_list_insert(ec->output_list.prev, &output->link); |
1281 | 1251 | ||
1282 | if (!eglMakeCurrent(ec->display, output->surface, output->surface, ec->context)) { | ||
1283 | fprintf(stderr, "failed to make context current\n"); | ||
1284 | return -1; | ||
1285 | } | ||
1286 | |||
1287 | output->background = background_create(output, option_background); | 1252 | output->background = background_create(output, option_background); |
1288 | 1253 | ||
1289 | return 0; | 1254 | return 0; |
@@ -66,6 +66,7 @@ struct window { | |||
66 | uint32_t modifiers; | 66 | uint32_t modifiers; |
67 | 67 | ||
68 | cairo_surface_t *cairo_surface, *pending_surface; | 68 | cairo_surface_t *cairo_surface, *pending_surface; |
69 | int new_surface; | ||
69 | 70 | ||
70 | window_resize_handler_t resize_handler; | 71 | window_resize_handler_t resize_handler; |
71 | window_key_handler_t key_handler; | 72 | window_key_handler_t key_handler; |
@@ -113,6 +114,17 @@ window_attach_surface(struct window *window) | |||
113 | window->allocation.height); | 114 | window->allocation.height); |
114 | } | 115 | } |
115 | 116 | ||
117 | void | ||
118 | window_commit(struct window *window, uint32_t key) | ||
119 | { | ||
120 | if (window->new_surface) { | ||
121 | window_attach_surface(window); | ||
122 | window->new_surface = 0; | ||
123 | } | ||
124 | |||
125 | wl_compositor_commit(window->display->compositor, key); | ||
126 | } | ||
127 | |||
116 | static void | 128 | static void |
117 | window_draw_decorations(struct window *window) | 129 | window_draw_decorations(struct window *window) |
118 | { | 130 | { |
@@ -210,8 +222,6 @@ window_draw_decorations(struct window *window) | |||
210 | cairo_fill(cr); | 222 | cairo_fill(cr); |
211 | } | 223 | } |
212 | cairo_destroy(cr); | 224 | cairo_destroy(cr); |
213 | |||
214 | window_attach_surface(window); | ||
215 | } | 225 | } |
216 | 226 | ||
217 | static void | 227 | static void |
@@ -222,8 +232,6 @@ window_draw_fullscreen(struct window *window) | |||
222 | CAIRO_CONTENT_COLOR_ALPHA, | 232 | CAIRO_CONTENT_COLOR_ALPHA, |
223 | window->allocation.width, | 233 | window->allocation.width, |
224 | window->allocation.height); | 234 | window->allocation.height); |
225 | |||
226 | window_attach_surface(window); | ||
227 | } | 235 | } |
228 | 236 | ||
229 | void | 237 | void |
@@ -236,6 +244,8 @@ window_draw(struct window *window) | |||
236 | window_draw_fullscreen(window); | 244 | window_draw_fullscreen(window); |
237 | else | 245 | else |
238 | window_draw_decorations(window); | 246 | window_draw_decorations(window); |
247 | |||
248 | window->new_surface = 1; | ||
239 | } | 249 | } |
240 | 250 | ||
241 | static void | 251 | static void |
@@ -251,13 +261,11 @@ window_handle_acknowledge(void *data, | |||
251 | * safely free the old window buffer if we resized and | 261 | * safely free the old window buffer if we resized and |
252 | * render the next frame into our back buffer.. */ | 262 | * render the next frame into our back buffer.. */ |
253 | 263 | ||
254 | if (key == 0) { | 264 | pending = window->pending_surface; |
255 | pending = window->pending_surface; | 265 | window->pending_surface = NULL; |
256 | window->pending_surface = NULL; | 266 | if (pending != window->cairo_surface) |
257 | if (pending != window->cairo_surface) | 267 | window_attach_surface(window); |
258 | window_attach_surface(window); | 268 | cairo_surface_destroy(pending); |
259 | cairo_surface_destroy(pending); | ||
260 | } | ||
261 | } | 269 | } |
262 | 270 | ||
263 | static void | 271 | static void |
@@ -585,7 +593,7 @@ window_copy(struct window *window, | |||
585 | cairo_t *cr; | 593 | cairo_t *cr; |
586 | 594 | ||
587 | surface = cairo_drm_surface_create_for_name (window->display->device, | 595 | surface = cairo_drm_surface_create_for_name (window->display->device, |
588 | name, CAIRO_CONTENT_COLOR_ALPHA, | 596 | name, CAIRO_FORMAT_ARGB32, |
589 | rectangle->width, rectangle->height, | 597 | rectangle->width, rectangle->height, |
590 | stride); | 598 | stride); |
591 | 599 | ||
@@ -60,6 +60,8 @@ window_create(struct display *display, const char *title, | |||
60 | void | 60 | void |
61 | window_draw(struct window *window); | 61 | window_draw(struct window *window); |
62 | void | 62 | void |
63 | window_commit(struct window *window, uint32_t key); | ||
64 | void | ||
63 | window_get_child_rectangle(struct window *window, | 65 | window_get_child_rectangle(struct window *window, |
64 | struct rectangle *rectangle); | 66 | struct rectangle *rectangle); |
65 | void | 67 | void |