Switch to using mesa EGL
authorKristian Høgsberg <krh@bitplanet.net>
Wed, 3 Mar 2010 14:54:29 +0000 (09:54 -0500)
committerKristian Høgsberg <krh@bitplanet.net>
Wed, 3 Mar 2010 15:34:35 +0000 (10:34 -0500)
Makefile.in
configure.ac
gears.c
wayland-system-compositor.c

index 04538ab..72b5e6a 100644 (file)
@@ -39,7 +39,7 @@ wayland-system-compositor :                   \
        wayland-util.o
 
 wayland-system-compositor : CFLAGS += @EGL_COMPOSITOR_CFLAGS@
-wayland-system-compositor : LDLIBS += ./libwayland-server.so @EGL_COMPOSITOR_LIBS@ -rdynamic -lrt
+wayland-system-compositor : LDLIBS += ./libwayland-server.so @EGL_COMPOSITOR_LIBS@ -rdynamic -lrt -lEGL
 
 flower : flower.o wayland-glib.o
 gears : gears.o window.o wayland-glib.o cairo-util.o
@@ -55,7 +55,7 @@ view : CFLAGS += @POPPLER_CFLAGS@
 view : LDLIBS += @POPPLER_LIBS@
 
 $(egl_clients) : CFLAGS += @EGL_CLIENT_CFLAGS@
-$(egl_clients) : LDLIBS += -L. -lwayland @EGL_CLIENT_LIBS@ -lrt
+$(egl_clients) : LDLIBS += -L. -lwayland @EGL_CLIENT_LIBS@ -lrt -lEGL
 $(cairo_clients) : CFLAGS += @CAIRO_CLIENT_CFLAGS@
 $(cairo_clients) : LDLIBS += ./libwayland.so @CAIRO_CLIENT_LIBS@ -lrt
 
index f3a1aa6..f7e4663 100644 (file)
@@ -5,8 +5,8 @@ PKG_PROG_PKG_CONFIG()
 PKG_CHECK_MODULES(FFI, [libffi])
 
 PKG_CHECK_MODULES(EGL_COMPOSITOR,
-                 [eagle libpng cairo gdk-pixbuf-2.0 libudev >= 136 libdrm >= 2.4.17])
-PKG_CHECK_MODULES(EGL_CLIENT, [eagle cairo glib-2.0 libudev])
+                 [gl libpng cairo gdk-pixbuf-2.0 libudev >= 136 libdrm >= 2.4.17])
+PKG_CHECK_MODULES(EGL_CLIENT, [gl cairo glib-2.0 libudev])
 PKG_CHECK_MODULES(CAIRO_CLIENT, [cairo-drm glib-2.0])
 PKG_CHECK_MODULES(GDK_PIXBUF, [gdk-pixbuf-2.0])
 PKG_CHECK_MODULES(POPPLER, [poppler-glib gdk-2.0])
diff --git a/gears.c b/gears.c
index 9a8d503..ff385a2 100644 (file)
--- a/gears.c
+++ b/gears.c
 #include <cairo-drm.h>
 
 #define GL_GLEXT_PROTOTYPES
+#define EGL_EGLEXT_PROTOTYPES
 #include <GL/gl.h>
-#include <eagle.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
 
 #include "wayland-util.h"
 #include "wayland-client.h"
@@ -54,6 +56,8 @@ struct gears {
 
        EGLDisplay display;
        EGLContext context;
+       EGLImageKHR image;
+       int drm_fd;
        int resized;
        GLfloat angle;
        cairo_surface_t *cairo_surface;
@@ -244,6 +248,15 @@ draw_gears(struct gears *gears)
 static void
 resize_window(struct gears *gears)
 {
+       EGLint attribs[] = {
+               EGL_IMAGE_WIDTH_INTEL,  0,
+               EGL_IMAGE_HEIGHT_INTEL, 0,
+               EGL_IMAGE_FORMAT_INTEL, EGL_FORMAT_RGBA_8888_KHR,
+               EGL_IMAGE_USE_INTEL,    EGL_IMAGE_USE_SHARE_INTEL |
+                                       EGL_IMAGE_USE_SCANOUT_INTEL,
+               EGL_NONE
+       };
+
        /* Constrain child size to be square and at least 300x300 */
        window_get_child_rectangle(gears->window, &gears->rectangle);
        if (gears->rectangle.width > gears->rectangle.height)
@@ -258,11 +271,16 @@ resize_window(struct gears *gears)
 
        window_draw(gears->window);
 
+       if (gears->image)
+               eglDestroyImageKHR(gears->display, gears->image);
+       attribs[1] = gears->rectangle.width;
+       attribs[1] = gears->rectangle.height;
+       gears->image = eglCreateImageKHR(gears->display, gears->context,
+                                        EGL_SYSTEM_IMAGE_INTEL,
+                                        NULL, attribs);
+
        glBindRenderbuffer(GL_RENDERBUFFER_EXT, gears->color_rbo);
-       glRenderbufferStorage(GL_RENDERBUFFER_EXT,
-                             GL_RGBA,
-                             gears->rectangle.width,
-                             gears->rectangle.height);
+       glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, gears->image);
 
        glBindRenderbuffer(GL_RENDERBUFFER_EXT, gears->depth_rbo);
        glRenderbufferStorage(GL_RENDERBUFFER_EXT,
@@ -323,15 +341,10 @@ handle_frame(void *data,
             uint32_t frame, uint32_t timestamp)
 {
        struct gears *gears = data;
-       GLint name, stride;
+       EGLint name, handle, 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);
+       eglShareImageINTEL(gears->display, gears->context,
+                          gears->image, 0, &name, &handle, &stride);
        
        window_copy(gears->window, &gears->rectangle, name, stride);
 
@@ -346,25 +359,24 @@ static const struct wl_compositor_listener compositor_listener = {
 };
 
 static struct gears *
-gears_create(struct display *display)
+gears_create(struct display *display, int drm_fd)
 {
        const int x = 200, y = 200, width = 450, height = 500;
        EGLint major, minor;
-       struct udev *udev;
-       struct udev_device *device;
+       EGLDisplayTypeDRMMESA drm_display;
        struct gears *gears;
        int i;
 
-       udev = udev_new();
-       device = udev_device_new_from_syspath(udev, "/sys/class/drm/card0");
-
        gears = malloc(sizeof *gears);
        memset(gears, 0, sizeof *gears);
        gears->d = display;
        gears->window = window_create(display, "Wayland Gears",
                                      x, y, width, height);
 
-       gears->display = eglCreateDisplayNative(device);
+       drm_display.type = EGL_DISPLAY_TYPE_DRM_MESA;
+       drm_display.device = NULL;
+       drm_display.fd = drm_fd;
+       gears->display = eglGetDisplay((EGLNativeDisplayType) &drm_display);
        if (gears->display == NULL)
                die("failed to create egl display\n");
 
@@ -460,7 +472,7 @@ int main(int argc, char *argv[])
        source = wl_glib_source_new(display);
        g_source_attach(source, NULL);
 
-       gears = gears_create(d);
+       gears = gears_create(d, fd);
 
        g_main_loop_run(loop);
 
index 13eca24..5da2e7e 100644 (file)
 #include <libudev.h>
 
 #define GL_GLEXT_PROTOTYPES
+#define EGL_EGLEXT_PROTOTYPES
 #include <GL/gl.h>
-#include <eagle.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
 
 #include "wayland.h"
 #include "wayland-protocol.h"
@@ -77,6 +79,7 @@ struct wlsc_output {
 
        GLuint rbo[2];
        uint32_t fb_id[2];
+       EGLImageKHR image[2];
        uint32_t current;       
 };
 
@@ -102,6 +105,7 @@ struct wlsc_compositor {
 
        EGLDisplay display;
        EGLContext context;
+       int drm_fd;
        GLuint fbo;
        struct wl_display *wl_display;
 
@@ -147,6 +151,7 @@ struct wlsc_surface {
        struct wlsc_compositor *compositor;
        struct wl_visual *visual;
        GLuint texture;
+       EGLImageKHR image;
        struct wl_map map;
        int width, height;
        struct wl_list link;
@@ -582,7 +587,6 @@ repaint_output(struct wlsc_output *output)
        struct wlsc_surface *es;
        struct wlsc_input_device *eid;
        double s = 3000;
-       int fd;
 
        glViewport(0, 0, output->width, output->height);
        glMatrixMode(GL_PROJECTION);
@@ -606,14 +610,13 @@ repaint_output(struct wlsc_output *output)
        wl_list_for_each(eid, &ec->input_device_list, link)
                wlsc_surface_draw(eid->sprite);
 
-       fd = eglGetDisplayFD(ec->display);
        output->current ^= 1;
 
        glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT,
                                  GL_COLOR_ATTACHMENT0_EXT,
                                  GL_RENDERBUFFER_EXT,
                                  output->rbo[output->current]);
-       drmModePageFlip(fd, output->crtc_id,
+       drmModePageFlip(ec->drm_fd, output->crtc_id,
                        output->fb_id[output->current ^ 1],
                        DRM_MODE_PAGE_FLIP_EVENT, output);
 }
@@ -639,15 +642,13 @@ static void
 wlsc_compositor_schedule_repaint(struct wlsc_compositor *compositor)
 {
        struct wlsc_output *output;
-       int fd;
 
        compositor->repaint_needed = 1;
        if (compositor->repaint_on_timeout)
                return;
 
-       fd = eglGetDisplayFD(compositor->display);
        wl_list_for_each(output, &compositor->output_list, link)
-               drmModePageFlip(fd, output->crtc_id,
+               drmModePageFlip(compositor->drm_fd, output->crtc_id,
                                output->fb_id[output->current ^ 1],
                                DRM_MODE_PAGE_FLIP_EVENT, output);
 }
@@ -672,6 +673,14 @@ surface_attach(struct wl_client *client,
 {
        struct wlsc_surface *es = (struct wlsc_surface *) surface;
        struct wlsc_compositor *ec = es->compositor;
+       EGLint attribs[] = {
+               EGL_IMAGE_WIDTH_INTEL,  0,
+               EGL_IMAGE_HEIGHT_INTEL, 0,
+               EGL_IMAGE_NAME_INTEL,   0,
+               EGL_IMAGE_STRIDE_INTEL, 0,
+               EGL_IMAGE_FORMAT_INTEL, EGL_FORMAT_RGBA_8888_KHR,
+               EGL_NONE
+       };
 
        es->width = width;
        es->height = height;
@@ -690,8 +699,19 @@ 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);
-       glTextureExternalINTEL(GL_TEXTURE_2D, GL_RGBA, 4,
-                              width, height, stride / 4, name);
+
+       if (es->image)
+               eglDestroyImageKHR(ec->display, es->image);
+
+       attribs[1] = width;
+       attribs[3] = height;
+       attribs[5] = name;
+       attribs[7] = stride / 4;
+
+       es->image = eglCreateImageKHR(ec->display, ec->context,
+                                      EGL_SYSTEM_IMAGE_INTEL,
+                                      NULL, attribs);
+       glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, es->image);
        
 }
 
@@ -1055,10 +1075,12 @@ static int
 init_egl(struct wlsc_compositor *ec, struct udev_device *device)
 {
        struct wl_event_loop *loop;
+       EGLDisplayTypeDRMMESA display;
        EGLint major, minor;
-       int fd;
 
-       ec->display = eglCreateDisplayNative(device);
+       display.type = EGL_DISPLAY_TYPE_DRM_MESA;
+       display.device = udev_device_get_devnode(device);
+       ec->display = eglGetDisplay((EGLNativeDisplayType) &display);
        if (ec->display == NULL) {
                fprintf(stderr, "failed to create display\n");
                return -1;
@@ -1084,9 +1106,9 @@ init_egl(struct wlsc_compositor *ec, struct udev_device *device)
        glBindFramebuffer(GL_FRAMEBUFFER_EXT, ec->fbo);
 
        loop = wl_display_get_event_loop(ec->wl_display);
-       fd = eglGetDisplayFD(ec->display);
+       ec->drm_fd = display.fd;
        ec->drm_source =
-               wl_event_loop_add_fd(loop, fd,
+               wl_event_loop_add_fd(loop, ec->drm_fd,
                                     WL_EVENT_READABLE, on_drm_input, ec);
 
        return 0;
@@ -1110,10 +1132,15 @@ create_output_for_connector(struct wlsc_compositor *ec,
        struct wlsc_output *output;
        drmModeEncoder *encoder;
        drmModeModeInfo *mode;
-       GLint handle, stride;
-       int i, ret, fd;
-
-       fd = eglGetDisplayFD(ec->display);
+       int i, ret;
+       EGLint name, handle, stride, attribs[] = {
+               EGL_IMAGE_WIDTH_INTEL,  0,
+               EGL_IMAGE_HEIGHT_INTEL, 0,
+               EGL_IMAGE_FORMAT_INTEL, EGL_FORMAT_RGBA_8888_KHR,
+               EGL_IMAGE_USE_INTEL,    EGL_IMAGE_USE_SHARE_INTEL |
+                                       EGL_IMAGE_USE_SCANOUT_INTEL,
+               EGL_NONE
+       };
 
        output = malloc(sizeof *output);
        if (output == NULL)
@@ -1124,7 +1151,7 @@ create_output_for_connector(struct wlsc_compositor *ec,
        else
                mode = &builtin_1024x768;
 
-       encoder = drmModeGetEncoder(fd, connector->encoders[0]);
+       encoder = drmModeGetEncoder(ec->drm_fd, connector->encoders[0]);
        if (encoder == NULL) {
                fprintf(stderr, "No encoder for connector.\n");
                return -1;
@@ -1159,19 +1186,18 @@ create_output_for_connector(struct wlsc_compositor *ec,
        glGenRenderbuffers(2, output->rbo);
        for (i = 0; i < 2; i++) {
                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]);
+
+               attribs[1] = output->width;
+               attribs[3] = output->height;
+               output->image[i] = eglCreateImageKHR(ec->display, ec->context,
+                                                    EGL_SYSTEM_IMAGE_INTEL,
+                                                    NULL, attribs);
+               glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, output->image[i]);
+               eglShareImageINTEL(ec->display, ec->context,
+                                  output->image[i], 0, &name, &handle, &stride);
+
+               ret = drmModeAddFB(ec->drm_fd, output->width, output->height,
+                                  32, 32, stride * 4, handle, &output->fb_id[i]);
                if (ret) {
                        fprintf(stderr, "failed to add fb %d: %m\n", i);
                        return -1;
@@ -1183,7 +1209,7 @@ create_output_for_connector(struct wlsc_compositor *ec,
                                  GL_COLOR_ATTACHMENT0_EXT,
                                  GL_RENDERBUFFER_EXT,
                                  output->rbo[output->current]);
-       ret = drmModeSetCrtc(fd, output->crtc_id,
+       ret = drmModeSetCrtc(ec->drm_fd, output->crtc_id,
                             output->fb_id[output->current ^ 1], 0, 0,
                             &output->connector_id, 1, &output->mode);
        if (ret) {
@@ -1206,17 +1232,16 @@ create_outputs(struct wlsc_compositor *ec)
 {
        drmModeConnector *connector;
        drmModeRes *resources;
-       int fd, i;
+       int i;
 
-       fd = eglGetDisplayFD(ec->display);
-       resources = drmModeGetResources(fd);
+       resources = drmModeGetResources(ec->drm_fd);
        if (!resources) {
                fprintf(stderr, "drmModeGetResources failed\n");
                return -1;
        }
 
        for (i = 0; i < resources->count_connectors; i++) {
-               connector = drmModeGetConnector(fd, resources->connectors[i]);
+               connector = drmModeGetConnector(ec->drm_fd, resources->connectors[i]);
                if (connector == NULL)
                        continue;
 
@@ -1268,10 +1293,9 @@ static void on_enter_vt(int signal_number, void *data)
 {
        struct wlsc_compositor *ec = data;
        struct wlsc_output *output;
-       int ret, fd;
+       int ret;
 
-       fd = eglGetDisplayFD(ec->display);
-       ret = drmSetMaster(fd);
+       ret = drmSetMaster(ec->drm_fd);
        if (ret) {
                fprintf(stderr, "failed to set drm master\n");
                return;
@@ -1281,7 +1305,7 @@ static void on_enter_vt(int signal_number, void *data)
        ec->vt_active = TRUE;
 
        wl_list_for_each(output, &ec->output_list, link) {
-               ret = drmModeSetCrtc(fd, output->crtc_id,
+               ret = drmModeSetCrtc(ec->drm_fd, output->crtc_id,
                                     output->fb_id[output->current ^ 1], 0, 0,
                                     &output->connector_id, 1, &output->mode);
                if (ret)
@@ -1293,10 +1317,9 @@ static void on_enter_vt(int signal_number, void *data)
 static void on_leave_vt(int signal_number, void *data)
 {
        struct wlsc_compositor *ec = data;
-       int ret, fd;
+       int ret;
 
-       fd = eglGetDisplayFD(ec->display);
-       ret = drmDropMaster(fd);
+       ret = drmDropMaster(ec->drm_fd);
        if (ret) {
                fprintf(stderr, "failed to drop drm master\n");
                return;