From a341fa016c54948af4fc76cde864f460f962f9db Mon Sep 17 00:00:00 2001 From: =?utf8?q?Kristian=20H=C3=B8gsberg?= Date: Sun, 24 Jan 2010 18:10:15 -0500 Subject: [PATCH] Use FBOs instead of eagle-specific API --- Makefile.in | 7 +-- gears.c | 96 +++++++++++++++++++++----------------- image.c | 12 ++++- terminal.c | 2 +- wayland-system-compositor.c | 111 +++++++++++++++----------------------------- window.c | 32 ++++++++----- 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 egl_clients = gears cairo_clients = flower screenshot terminal image view compositors = wayland-system-compositor +clients = $(egl_clients) $(cairo_clients) -all : $(libs) $(compositors) $(egl_clients) $(cairo_clients) +all : $(libs) $(compositors) $(clients) libwayland-server.so : \ wayland.o \ @@ -36,7 +37,7 @@ wayland-system-compositor : \ wayland-util.o wayland-system-compositor : CFLAGS += @EGL_COMPOSITOR_CFLAGS@ -wayland-system-compositor : LDLIBS += -L. -lwayland-server @EGL_COMPOSITOR_LIBS@ -rdynamic -lrt +wayland-system-compositor : LDLIBS += ./libwayland-server.so @EGL_COMPOSITOR_LIBS@ -rdynamic -lrt flower : flower.o wayland-glib.o gears : gears.o window.o wayland-glib.o cairo-util.o @@ -54,7 +55,7 @@ view : LDLIBS += @POPPLER_LIBS@ $(egl_clients) : CFLAGS += @EGL_CLIENT_CFLAGS@ $(egl_clients) : LDLIBS += -L. -lwayland @EGL_CLIENT_LIBS@ -lrt $(cairo_clients) : CFLAGS += @CAIRO_CLIENT_CFLAGS@ -$(cairo_clients) : LDLIBS += -L. -lwayland @CAIRO_CLIENT_LIBS@ -lrt +$(cairo_clients) : LDLIBS += ./libwayland.so @CAIRO_CLIENT_LIBS@ -lrt install : $(libs) $(compositors) install -d @libdir@ @libdir@/pkgconfig ${udev_rules_dir} diff --git a/gears.c b/gears.c index def1f99..9a8d503 100644 --- a/gears.c +++ b/gears.c @@ -32,6 +32,7 @@ #include #include +#define GL_GLEXT_PROTOTYPES #include #include @@ -52,14 +53,13 @@ struct gears { struct rectangle rectangle; EGLDisplay display; - EGLConfig config; - EGLSurface surface; EGLContext context; int resized; GLfloat angle; cairo_surface_t *cairo_surface; GLint gear_list[3]; + GLuint fbo, color_rbo, depth_rbo; }; struct gear_template { @@ -258,19 +258,20 @@ resize_window(struct gears *gears) window_draw(gears->window); - if (gears->surface != NULL) - eglDestroySurface(gears->display, gears->surface); + glBindRenderbuffer(GL_RENDERBUFFER_EXT, gears->color_rbo); + glRenderbufferStorage(GL_RENDERBUFFER_EXT, + GL_RGBA, + gears->rectangle.width, + gears->rectangle.height); - gears->surface = eglCreateSurface(gears->display, - gears->config, - gears->rectangle.width, - gears->rectangle.height, - 1, NULL); - - eglMakeCurrent(gears->display, - gears->surface, gears->surface, gears->context); + glBindRenderbuffer(GL_RENDERBUFFER_EXT, gears->depth_rbo); + glRenderbufferStorage(GL_RENDERBUFFER_EXT, + GL_DEPTH_COMPONENT, + gears->rectangle.width, + gears->rectangle.height); glViewport(0, 0, gears->rectangle.width, gears->rectangle.height); + gears->resized = 0; } @@ -308,13 +309,12 @@ handle_acknowledge(void *data, { struct gears *gears = data; - if (key != 0) - return; + if (key == 10) { + if (gears->resized) + resize_window(gears); - if (gears->resized) - resize_window(gears); - - draw_gears(gears); + draw_gears(gears); + } } static void @@ -322,14 +322,20 @@ handle_frame(void *data, struct wl_compositor *compositor, uint32_t frame, uint32_t timestamp) { - struct gears *gears = data; - uint32_t name, handle, stride; - - eglGetColorBuffer(gears->surface, 0, &name, &handle, &stride); + struct gears *gears = data; + GLint name, stride; + + glBindRenderbuffer(GL_RENDERBUFFER_EXT, gears->color_rbo); + glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, + GL_RENDERBUFFER_STRIDE_INTEL, + &stride); + glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, + GL_RENDERBUFFER_NAME_INTEL, + &name); window_copy(gears->window, &gears->rectangle, name, stride); - wl_compositor_commit(gears->compositor, 0); + window_commit(gears->window, 10); gears->angle = (GLfloat) (timestamp % 8192) * 360 / 8192.0; } @@ -339,19 +345,11 @@ static const struct wl_compositor_listener compositor_listener = { handle_frame, }; -static const EGLint config_attribs[] = { - EGL_DEPTH_SIZE, 24, - EGL_CONFIG_CAVEAT, EGL_NONE, - EGL_RED_SIZE, 8, - EGL_NONE -}; - static struct gears * gears_create(struct display *display) { const int x = 200, y = 200, width = 450, height = 500; - EGLint major, minor, count; - EGLConfig configs[64]; + EGLint major, minor; struct udev *udev; struct udev_device *device; struct gears *gears; @@ -373,18 +371,29 @@ gears_create(struct display *display) if (!eglInitialize(gears->display, &major, &minor)) die("failed to initialize display\n"); - if (!eglGetConfigs(gears->display, configs, 64, &count)) - die("failed to get configs\n"); - - if (!eglChooseConfig(gears->display, config_attribs, &gears->config, 1, NULL)) - die("failed to pick a config\n"); - - gears->context = eglCreateContext(gears->display, gears->config, NULL, NULL); + gears->context = eglCreateContext(gears->display, NULL, NULL, NULL); if (gears->context == NULL) die("failed to create context\n"); - resize_window(gears); - + 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(1, &gears->color_rbo); + glBindRenderbuffer(GL_RENDERBUFFER_EXT, gears->color_rbo); + glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, + GL_COLOR_ATTACHMENT0_EXT, + GL_RENDERBUFFER_EXT, + 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); @@ -406,10 +415,13 @@ gears_create(struct display *display) glEnable(GL_DEPTH_TEST); glClearColor(0, 0, 0, 0.92); + if (glCheckFramebufferStatus (GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE) + fprintf(stderr, "framebuffer incomplete\n"); + gears->compositor = display_get_compositor(display); + resize_window(gears); draw_gears(gears); - handle_frame(gears, gears->compositor, 0, 0); window_set_resize_handler(gears->window, resize_handler, gears); diff --git a/image.c b/image.c index e38da0f..3f206fc 100644 --- a/image.c +++ b/image.c @@ -184,7 +184,7 @@ image_draw(struct image *image) &rectangle, image->surface); - wl_compositor_commit(image->compositor, image->key); + window_commit(image->window, image->key); } static gboolean @@ -217,6 +217,15 @@ resize_handler(struct window *window, void *data) } static void +keyboard_focus_handler(struct window *window, + struct wl_input_device *device, void *data) +{ + struct image *image = data; + + image_schedule_redraw(image); +} + +static void handle_acknowledge(void *data, struct wl_compositor *compositor, uint32_t key, uint32_t frame) @@ -274,6 +283,7 @@ image_create(struct display *display, uint32_t key, const char *filename) image->compositor = display_get_compositor(display); window_set_resize_handler(image->window, resize_handler, image); + window_set_keyboard_focus_handler(image->window, keyboard_focus_handler, image); wl_compositor_add_listener(image->compositor, &compositor_listener, image); diff --git a/terminal.c b/terminal.c index 05cdaa1..b4800d5 100644 --- a/terminal.c +++ b/terminal.c @@ -227,7 +227,7 @@ terminal_draw(struct terminal *terminal) window_draw(terminal->window); terminal_draw_contents(terminal); - wl_compositor_commit(terminal->compositor, 0); + window_commit(terminal->window, 0); } 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 { struct wl_list link; struct wlsc_compositor *compositor; struct wlsc_surface *background; - EGLSurface surface; int32_t x, y, width, height; drmModeModeInfo mode; uint32_t crtc_id; uint32_t connector_id; + GLuint rbo[2]; uint32_t fb_id[2]; uint32_t current; }; @@ -102,7 +102,7 @@ struct wlsc_compositor { EGLDisplay display; EGLContext context; - EGLConfig config; + GLuint fbo; struct wl_display *wl_display; struct wl_list output_list; @@ -610,16 +610,11 @@ repaint_output(struct wlsc_output *output) double s = 3000; int fd; - if (!eglMakeCurrent(ec->display, output->surface, output->surface, ec->context)) { - fprintf(stderr, "failed to make context current\n"); - return; - } - glViewport(0, 0, output->width, output->height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-output->width / s, output->width / s, - output->height / s, -output->height / s, 1, 2 * s); + -output->height / s, output->height / s, 1, 2 * s); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glClearColor(0, 0, 0, 1); @@ -650,7 +645,11 @@ repaint_output(struct wlsc_output *output) fd = eglGetDisplayFD(ec->display); output->current ^= 1; - eglBindColorBuffer(ec->display, output->surface, output->current); + + glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, + GL_COLOR_ATTACHMENT0_EXT, + GL_RENDERBUFFER_EXT, + output->rbo[output->current]); drmModePageFlip(fd, output->crtc_id, output->fb_id[output->current ^ 1], DRM_MODE_PAGE_FLIP_EVENT, output); @@ -737,8 +736,8 @@ surface_attach(struct wl_client *client, glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTextureExternalMESA(GL_TEXTURE_2D, GL_RGBA, 4, - width, height, stride / 4, name); + glTextureExternalINTEL(GL_TEXTURE_2D, GL_RGBA, 4, + width, height, stride / 4, name); } @@ -762,36 +761,6 @@ surface_copy(struct wl_client *client, uint32_t name, uint32_t stride, int32_t x, int32_t y, int32_t width, int32_t height) { - struct wlsc_surface *es = (struct wlsc_surface *) surface; - GLuint fbo[2], rb; - - glGenFramebuffers(2, fbo); - - glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, fbo[1]); - glGenRenderbuffers(1, &rb); - glBindRenderbuffer(GL_RENDERBUFFER_EXT, rb); - glRenderbufferExternalMESA(GL_RENDERBUFFER_EXT, - GL_RGBA, - es->width, es->height, - stride / 4, name); - glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - GL_RENDERBUFFER_EXT, - rb); - - glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, fbo[0]); - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER_EXT, - GL_COLOR_ATTACHMENT0_EXT, - GL_TEXTURE_2D, es->texture, 0); - - glBlitFramebuffer(x, y, x + width, y + height, - dst_x, dst_y, dst_x+ width, dst_y + height, - GL_COLOR_BUFFER_BIT, GL_NEAREST); - - glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0); - glBindRenderbuffer(GL_RENDERBUFFER_EXT, 0); - glDeleteRenderbuffers(1, &rb); - glDeleteFramebuffers(2, fbo); } static void @@ -1138,14 +1107,6 @@ on_drm_input(int fd, uint32_t mask, void *data) static int init_egl(struct wlsc_compositor *ec, struct udev_device *device) { - static const EGLint config_attribs[] = { - EGL_DEPTH_SIZE, 0, - EGL_STENCIL_SIZE, 0, - EGL_CONFIG_CAVEAT, EGL_NONE, - EGL_RED_SIZE, 8, - EGL_NONE - }; - struct wl_event_loop *loop; EGLint major, minor; int fd; @@ -1161,15 +1122,20 @@ init_egl(struct wlsc_compositor *ec, struct udev_device *device) return -1; } - if (!eglChooseConfig(ec->display, config_attribs, &ec->config, 1, NULL)) - return -1; - - ec->context = eglCreateContext(ec->display, ec->config, NULL, NULL); + ec->context = eglCreateContext(ec->display, NULL, NULL, NULL); if (ec->context == NULL) { fprintf(stderr, "failed to create context\n"); return -1; } + if (!eglMakeCurrent(ec->display, EGL_NO_SURFACE, EGL_NO_SURFACE, ec->context)) { + fprintf(stderr, "failed to make context current\n"); + return -1; + } + + glGenFramebuffers(1, &ec->fbo); + glBindFramebuffer(GL_FRAMEBUFFER_EXT, ec->fbo); + loop = wl_display_get_event_loop(ec->wl_display); fd = eglGetDisplayFD(ec->display); ec->drm_source = @@ -1197,7 +1163,7 @@ create_output_for_connector(struct wlsc_compositor *ec, struct wlsc_output *output; drmModeEncoder *encoder; drmModeModeInfo *mode; - uint32_t name, handle, stride; + GLint handle, stride; int i, ret, fd; fd = eglGetDisplayFD(ec->display); @@ -1243,21 +1209,21 @@ create_output_for_connector(struct wlsc_compositor *ec, drmModeFreeEncoder(encoder); - output->surface = eglCreateSurface(ec->display, - ec->config, - output->width, - output->height, - 2, NULL); - if (output->surface == NULL) { - fprintf(stderr, "failed to create surface\n"); - return -1; - } - + glGenRenderbuffers(2, output->rbo); for (i = 0; i < 2; i++) { - eglGetColorBuffer(output->surface, - i, &name, &handle, &stride); - - ret = drmModeAddFB(fd, mode->hdisplay, mode->vdisplay, + glBindRenderbuffer(GL_RENDERBUFFER_EXT, output->rbo[i]); + glRenderbufferStorage(GL_RENDERBUFFER_EXT, + GL_RGBA, + output->width, + output->height); + glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, + GL_RENDERBUFFER_STRIDE_INTEL, + &stride); + glGetRenderbufferParameteriv(GL_RENDERBUFFER_EXT, + GL_RENDERBUFFER_HANDLE_INTEL, + &handle); + + ret = drmModeAddFB(fd, output->width, output->height, 32, 32, stride, handle, &output->fb_id[i]); if (ret) { fprintf(stderr, "failed to add fb %d: %m\n", i); @@ -1266,6 +1232,10 @@ create_output_for_connector(struct wlsc_compositor *ec, } output->current = 0; + glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, + GL_COLOR_ATTACHMENT0_EXT, + GL_RENDERBUFFER_EXT, + output->rbo[output->current]); ret = drmModeSetCrtc(fd, output->crtc_id, output->fb_id[output->current ^ 1], 0, 0, &output->connector_id, 1, &output->mode); @@ -1279,11 +1249,6 @@ create_output_for_connector(struct wlsc_compositor *ec, wl_display_add_global(ec->wl_display, &output->base, post_output_geometry); wl_list_insert(ec->output_list.prev, &output->link); - if (!eglMakeCurrent(ec->display, output->surface, output->surface, ec->context)) { - fprintf(stderr, "failed to make context current\n"); - return -1; - } - output->background = background_create(output, option_background); return 0; diff --git a/window.c b/window.c index e27ff32..95f3e21 100644 --- a/window.c +++ b/window.c @@ -66,6 +66,7 @@ struct window { uint32_t modifiers; cairo_surface_t *cairo_surface, *pending_surface; + int new_surface; window_resize_handler_t resize_handler; window_key_handler_t key_handler; @@ -113,6 +114,17 @@ window_attach_surface(struct window *window) window->allocation.height); } +void +window_commit(struct window *window, uint32_t key) +{ + if (window->new_surface) { + window_attach_surface(window); + window->new_surface = 0; + } + + wl_compositor_commit(window->display->compositor, key); +} + static void window_draw_decorations(struct window *window) { @@ -210,8 +222,6 @@ window_draw_decorations(struct window *window) cairo_fill(cr); } cairo_destroy(cr); - - window_attach_surface(window); } static void @@ -222,8 +232,6 @@ window_draw_fullscreen(struct window *window) CAIRO_CONTENT_COLOR_ALPHA, window->allocation.width, window->allocation.height); - - window_attach_surface(window); } void @@ -236,6 +244,8 @@ window_draw(struct window *window) window_draw_fullscreen(window); else window_draw_decorations(window); + + window->new_surface = 1; } static void @@ -251,13 +261,11 @@ window_handle_acknowledge(void *data, * safely free the old window buffer if we resized and * render the next frame into our back buffer.. */ - if (key == 0) { - pending = window->pending_surface; - window->pending_surface = NULL; - if (pending != window->cairo_surface) - window_attach_surface(window); - cairo_surface_destroy(pending); - } + pending = window->pending_surface; + window->pending_surface = NULL; + if (pending != window->cairo_surface) + window_attach_surface(window); + cairo_surface_destroy(pending); } static void @@ -585,7 +593,7 @@ window_copy(struct window *window, cairo_t *cr; surface = cairo_drm_surface_create_for_name (window->display->device, - name, CAIRO_CONTENT_COLOR_ALPHA, + name, CAIRO_FORMAT_ARGB32, rectangle->width, rectangle->height, stride); diff --git a/window.h b/window.h index c483400..78e7734 100644 --- a/window.h +++ b/window.h @@ -60,6 +60,8 @@ window_create(struct display *display, const char *title, void window_draw(struct window *window); void +window_commit(struct window *window, uint32_t key); +void window_get_child_rectangle(struct window *window, struct rectangle *rectangle); void -- 2.7.4