simple-client: Port to wayland-egl and use eglSwapBuffers()

simple-client is simpler.
dev
Kristian Høgsberg 14 years ago
parent f57a96f98d
commit a495a5ed8b
  1. 6
      clients/Makefile.am
  2. 171
      clients/simple-client.c

@ -58,8 +58,10 @@ resizor_SOURCES = resizor.c
resizor_LDADD = $(toolkit_libs) resizor_LDADD = $(toolkit_libs)
simple_client_SOURCES = simple-client.c simple_client_SOURCES = simple-client.c
simple_client_LDADD = \ simple_client_LDADD = \
$(top_builddir)/wayland/libwayland-client.la -lm $(GLES2_LIBS) $(top_builddir)/wayland/libwayland-client.la -lm \
$(GLES2_LIBS) \
-lwayland-egl
eventdemo_SOURCES = eventdemo.c eventdemo_SOURCES = eventdemo.c
eventdemo_LDADD = $(toolkit_libs) eventdemo_LDADD = $(toolkit_libs)

@ -23,39 +23,25 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <math.h> #include <math.h>
#include <assert.h> #include <assert.h>
#include <fcntl.h>
#include <wayland-client.h> #include <wayland-client.h>
#include <xf86drm.h> #include <wayland-egl.h>
#define GL_GLEXT_PROTOTYPES
#define EGL_EGLEXT_PROTOTYPES
#include <GLES2/gl2.h> #include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <EGL/egl.h> #include <EGL/egl.h>
#include <EGL/eglext.h>
struct display { struct display {
struct wl_display *display; struct wl_display *display;
struct { struct wl_egl_display *native;
struct wl_compositor *compositor; struct wl_compositor *compositor;
struct wl_drm *drm;
} interface;
struct { struct {
EGLDisplay dpy; EGLDisplay dpy;
EGLContext ctx; EGLContext ctx;
EGLConfig conf;
} egl; } egl;
struct {
int fd;
const char *device_name;
bool authenticated;
} drm;
uint32_t mask; uint32_t mask;
}; };
@ -74,11 +60,10 @@ struct window {
GLuint pos; GLuint pos;
GLuint col; GLuint col;
} gl; } gl;
struct {
struct wl_buffer *buffer; struct wl_egl_window *native;
struct wl_surface *surface; struct wl_surface *surface;
EGLImageKHR image; EGLSurface egl_surface;
} drm_surface;
}; };
static const char *vert_shader_text = static const char *vert_shader_text =
@ -106,10 +91,21 @@ init_egl(struct display *display)
EGL_NONE EGL_NONE
}; };
EGLint major, minor; static const EGLint config_attribs[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RED_SIZE, 1,
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
EGL_DEPTH_SIZE, 1,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NONE
};
EGLint major, minor, n;
EGLBoolean ret; EGLBoolean ret;
display->egl.dpy = eglGetDRMDisplayMESA(display->drm.fd); display->egl.dpy =
eglGetDisplay((EGLNativeDisplayType) display->native);
assert(display->egl.dpy); assert(display->egl.dpy);
ret = eglInitialize(display->egl.dpy, &major, &minor); ret = eglInitialize(display->egl.dpy, &major, &minor);
@ -117,11 +113,14 @@ init_egl(struct display *display)
ret = eglBindAPI(EGL_OPENGL_ES_API); ret = eglBindAPI(EGL_OPENGL_ES_API);
assert(ret == EGL_TRUE); assert(ret == EGL_TRUE);
display->egl.ctx = eglCreateContext(display->egl.dpy, NULL, assert(eglChooseConfig(display->egl.dpy, config_attribs,
&display->egl.conf, 1, &n) && n == 1);
display->egl.ctx = eglCreateContext(display->egl.dpy,
display->egl.conf,
EGL_NO_CONTEXT, context_attribs); EGL_NO_CONTEXT, context_attribs);
assert(display->egl.ctx); assert(display->egl.ctx);
ret = eglMakeCurrent(display->egl.dpy, NULL, NULL, display->egl.ctx);
assert(ret == EGL_TRUE);
} }
static GLuint static GLuint
@ -156,11 +155,6 @@ init_gl(struct window *window)
GLuint frag, vert; GLuint frag, vert;
GLint status; GLint status;
glGenFramebuffers(1, &window->gl.fbo);
glBindFramebuffer(GL_FRAMEBUFFER, window->gl.fbo);
glGenRenderbuffers(1, &window->gl.color_rbo);
glViewport(0, 0, window->geometry.width, window->geometry.height); glViewport(0, 0, window->geometry.width, window->geometry.height);
frag = create_shader(window, frag_shader_text, GL_FRAGMENT_SHADER); frag = create_shader(window, frag_shader_text, GL_FRAGMENT_SHADER);
@ -198,48 +192,26 @@ create_surface(struct window *window)
{ {
struct display *display = window->display; struct display *display = window->display;
struct wl_visual *visual; struct wl_visual *visual;
EGLint name, stride; EGLBoolean ret;
EGLint image_attribs[] = {
EGL_WIDTH, 0,
EGL_HEIGHT, 0,
EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
EGL_DRM_BUFFER_USE_MESA, EGL_DRM_BUFFER_USE_SCANOUT_MESA,
EGL_NONE
};
window->drm_surface.surface =
wl_compositor_create_surface(display->interface.compositor);
image_attribs[1] = window->geometry.width;
image_attribs[3] = window->geometry.height;
window->drm_surface.image = eglCreateDRMImageMESA(display->egl.dpy, window->surface = wl_compositor_create_surface(display->compositor);
image_attribs);
eglExportDRMImageMESA(display->egl.dpy, window->drm_surface.image,
&name, NULL, &stride);
visual = wl_display_get_premultiplied_argb_visual(display->display); visual = wl_display_get_premultiplied_argb_visual(display->display);
window->native =
window->drm_surface.buffer = wl_egl_native_window_create(window->surface,
wl_drm_create_buffer(display->interface.drm, name, window->geometry.width,
window->geometry.width, window->geometry.height,
window->geometry.height, visual);
stride, visual); window->egl_surface =
eglCreateWindowSurface(display->egl.dpy,
wl_surface_attach(window->drm_surface.surface, display->egl.conf,
window->drm_surface.buffer, 0, 0); (EGLNativeWindowType) window->native,
wl_surface_map_toplevel(window->drm_surface.surface); NULL);
glBindRenderbuffer(GL_RENDERBUFFER, window->gl.color_rbo); wl_surface_map_toplevel(window->surface);
glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER,
window->drm_surface.image); ret = eglMakeCurrent(window->display->egl.dpy, window->egl_surface,
window->egl_surface, window->display->egl.ctx);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, assert(ret == EGL_TRUE);
GL_COLOR_ATTACHMENT0,
GL_RENDERBUFFER,
window->gl.color_rbo);
assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) ==
GL_FRAMEBUFFER_COMPLETE);
} }
static void static void
@ -293,45 +265,18 @@ redraw(void *data, uint32_t time)
glFlush(); glFlush();
wl_surface_damage(window->drm_surface.surface, 0, 0, eglSwapBuffers(window->display->egl.dpy, window->egl_surface);
window->geometry.width, window->geometry.height);
wl_display_frame_callback(window->display->display, redraw, window); wl_display_frame_callback(window->display->display, redraw, window);
} }
static void
drm_handle_device(void *data, struct wl_drm *drm, const char *device)
{
struct display *d = data;
d->drm.device_name = strdup(device);
}
static void
drm_handle_authenticated(void *data, struct wl_drm *drm)
{
struct display *d = data;
d->drm.authenticated = true;
}
static const struct wl_drm_listener drm_listener = {
drm_handle_device,
drm_handle_authenticated
};
static void static void
display_handle_global(struct wl_display *display, uint32_t id, display_handle_global(struct wl_display *display, uint32_t id,
const char *interface, uint32_t version, void *data) const char *interface, uint32_t version, void *data)
{ {
struct display *d = data; struct display *d = data;
if (strcmp(interface, "compositor") == 0) { if (strcmp(interface, "compositor") == 0)
d->interface.compositor = wl_compositor_create(display, id); d->compositor = wl_compositor_create(display, id);
} else if (strcmp(interface, "drm") == 0) {
d->interface.drm = wl_drm_create(display, id);
wl_drm_add_listener(d->interface.drm, &drm_listener, d);
}
} }
static int static int
@ -349,8 +294,6 @@ main(int argc, char **argv)
{ {
struct display display = { 0 }; struct display display = { 0 };
struct window window = { 0 }; struct window window = { 0 };
drm_magic_t magic;
int ret;
memset(&display, 0, sizeof display); memset(&display, 0, sizeof display);
memset(&window, 0, sizeof window); memset(&window, 0, sizeof window);
@ -363,29 +306,19 @@ main(int argc, char **argv)
assert(display.display); assert(display.display);
wl_display_add_global_listener(display.display, wl_display_add_global_listener(display.display,
display_handle_global, &display); display_handle_global, &display);
/* process connection events */
wl_display_iterate(display.display, WL_DISPLAY_READABLE);
display.drm.fd = open(display.drm.device_name, O_RDWR); display.native = wl_egl_native_display_create(display.display);
assert(display.drm.fd >= 0);
ret = drmGetMagic(display.drm.fd, &magic);
assert(ret == 0);
wl_drm_authenticate(display.interface.drm, magic);
wl_display_iterate(display.display, WL_DISPLAY_WRITABLE);
while (!display.drm.authenticated)
wl_display_iterate(display.display, WL_DISPLAY_READABLE);
init_egl(&display); init_egl(&display);
init_gl(&window);
create_surface(&window); create_surface(&window);
init_gl(&window);
wl_display_frame_callback(display.display, redraw, &window); wl_display_frame_callback(display.display, redraw, &window);
wl_display_get_fd(display.display, event_mask_update, &display); wl_display_get_fd(display.display, event_mask_update, &display);
while (true) while (true)
wl_display_iterate(display.display, display.mask); wl_display_iterate(display.display, display.mask);
return 0; return 0;
} }

Loading…
Cancel
Save