#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"
EGLDisplay display;
EGLContext context;
+ EGLImageKHR image;
+ int drm_fd;
int resized;
GLfloat angle;
cairo_surface_t *cairo_surface;
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)
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,
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);
};
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");
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);
#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"
GLuint rbo[2];
uint32_t fb_id[2];
+ EGLImageKHR image[2];
uint32_t current;
};
EGLDisplay display;
EGLContext context;
+ int drm_fd;
GLuint fbo;
struct wl_display *wl_display;
struct wlsc_compositor *compositor;
struct wl_visual *visual;
GLuint texture;
+ EGLImageKHR image;
struct wl_map map;
int width, height;
struct wl_list link;
struct wlsc_surface *es;
struct wlsc_input_device *eid;
double s = 3000;
- int fd;
glViewport(0, 0, output->width, output->height);
glMatrixMode(GL_PROJECTION);
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);
}
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);
}
{
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;
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);
}
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;
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;
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)
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;
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;
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) {
{
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;
{
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;
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)
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;