aboutsummaryrefslogtreecommitdiff
path: root/backend
diff options
context:
space:
mode:
Diffstat (limited to 'backend')
-rw-r--r--backend/drm/backend.c4
-rw-r--r--backend/drm/drm.c2
-rw-r--r--backend/egl.c94
-rw-r--r--backend/wayland/backend.c2
4 files changed, 94 insertions, 8 deletions
diff --git a/backend/drm/backend.c b/backend/drm/backend.c
index e361358e..bcc81624 100644
--- a/backend/drm/backend.c
+++ b/backend/drm/backend.c
@@ -149,6 +149,10 @@ struct wlr_backend *wlr_drm_backend_create(struct wl_display *display,
goto error_event;
}
+ if (!wlr_egl_bind_display(&drm->renderer.egl, display)) {
+ wlr_log(L_INFO, "Failed to bind egl/wl display: %s", egl_error());
+ }
+
return backend;
error_event:
diff --git a/backend/drm/drm.c b/backend/drm/drm.c
index 1c83af3e..e11751e2 100644
--- a/backend/drm/drm.c
+++ b/backend/drm/drm.c
@@ -579,7 +579,7 @@ static bool wlr_drm_output_set_cursor(struct wlr_output_state *output,
wlr_matrix_texture(plane->matrix, plane->width, plane->height,
output->base->transform ^ WL_OUTPUT_TRANSFORM_FLIPPED_180);
- plane->wlr_rend = wlr_gles2_renderer_init();
+ plane->wlr_rend = wlr_gles2_renderer_init(&output->renderer->egl);
if (!plane->wlr_rend) {
return false;
}
diff --git a/backend/egl.c b/backend/egl.c
index a547523c..15a2c58e 100644
--- a/backend/egl.c
+++ b/backend/egl.c
@@ -1,10 +1,17 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
-#include <GLES3/gl3.h>
+#include <GLES2/gl2.h>
#include <gbm.h> // GBM_FORMAT_XRGB8888
+#include <stdlib.h>
#include <wlr/util/log.h>
#include "backend/egl.h"
+// Extension documentation
+// https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_image_base.txt.
+// https://cgit.freedesktop.org/mesa/mesa/tree/docs/specs/WL_bind_wayland_display.spec
+
+struct wlr_egl *egl_global;
+
const char *egl_error(void) {
switch (eglGetError()) {
case EGL_SUCCESS:
@@ -46,6 +53,12 @@ const char *egl_error(void) {
PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display;
PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC create_platform_window_surface;
+PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR;
+PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR;
+PFNEGLQUERYWAYLANDBUFFERWL eglQueryWaylandBufferWL;
+PFNEGLBINDWAYLANDDISPLAYWL eglBindWaylandDisplayWL;
+PFNEGLUNBINDWAYLANDDISPLAYWL eglUnbindWaylandDisplayWL;
+
static bool egl_exts() {
get_platform_display = (PFNEGLGETPLATFORMDISPLAYEXTPROC)
eglGetProcAddress("eglGetPlatformDisplayEXT");
@@ -109,7 +122,8 @@ static bool egl_get_config(EGLDisplay disp, EGLConfig *out, EGLenum platform) {
return false;
}
-bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *display) {
+bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform,
+ void *remote_display) {
if (!egl_exts()) {
return false;
}
@@ -119,7 +133,7 @@ bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *display) {
goto error;
}
- egl->display = get_platform_display(platform, display, NULL);
+ egl->display = get_platform_display(platform, remote_display, NULL);
if (egl->display == EGL_NO_DISPLAY) {
wlr_log(L_ERROR, "Failed to create EGL display: %s", egl_error());
goto error;
@@ -147,11 +161,31 @@ bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *display) {
}
eglMakeCurrent(egl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, egl->context);
+ egl->egl_exts = eglQueryString(egl->display, EGL_EXTENSIONS);
+ if (strstr(egl->egl_exts, "EGL_WL_bind_wayland_display") == NULL ||
+ strstr(egl->egl_exts, "EGL_KHR_image_base") == NULL) {
+ wlr_log(L_ERROR, "Required egl extensions not supported");
+ goto error;
+ }
+
+ eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC)
+ eglGetProcAddress("eglCreateImageKHR");
+ eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC)
+ eglGetProcAddress("eglDestroyImageKHR");
+ eglQueryWaylandBufferWL = (PFNEGLQUERYWAYLANDBUFFERWL)
+ (void*) eglGetProcAddress("eglQueryWaylandBufferWL");
+ eglBindWaylandDisplayWL = (PFNEGLBINDWAYLANDDISPLAYWL)
+ (void*) eglGetProcAddress("eglBindWaylandDisplayWL");
+ eglUnbindWaylandDisplayWL = (PFNEGLUNBINDWAYLANDDISPLAYWL)
+ (void*) eglGetProcAddress("eglUnbindWaylandDisplayWL");
+
+ egl_global = egl;
+
+ egl->gl_exts = (const char*) glGetString(GL_EXTENSIONS);
wlr_log(L_INFO, "Using EGL %d.%d", (int)major, (int)minor);
- wlr_log(L_INFO, "Supported EGL extensions: %s", eglQueryString(egl->display,
- EGL_EXTENSIONS));
+ wlr_log(L_INFO, "Supported EGL extensions: %s", egl->egl_exts);
wlr_log(L_INFO, "Using %s", glGetString(GL_VERSION));
- wlr_log(L_INFO, "Supported OpenGL ES extensions: %s", glGetString(GL_EXTENSIONS));
+ wlr_log(L_INFO, "Supported OpenGL ES extensions: %s", egl->gl_exts);
return true;
error:
@@ -162,11 +196,57 @@ error:
}
void wlr_egl_free(struct wlr_egl *egl) {
- eglMakeCurrent(egl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ if (egl->wl_display && eglUnbindWaylandDisplayWL) {
+ eglUnbindWaylandDisplayWL(egl->display, egl->wl_display);
+ }
+
eglDestroyContext(egl->display, egl->context);
eglTerminate(egl->display);
eglReleaseThread();
eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+
+ if (egl_global == egl)
+ egl_global = NULL;
+}
+
+bool wlr_egl_bind_display(struct wlr_egl *egl, struct wl_display *local_display) {
+ if (!eglBindWaylandDisplayWL) {
+ return false;
+ }
+
+ if (eglBindWaylandDisplayWL(egl->display, local_display)) {
+ egl->wl_display = local_display;
+ return true;
+ }
+
+ return false;
+}
+
+bool wlr_egl_query_buffer(struct wl_resource *buf, int attrib, int *value) {
+ if (!egl_global || !eglQueryWaylandBufferWL) {
+ return false;
+ }
+
+ return eglQueryWaylandBufferWL(egl_global->display, buf, attrib, value);
+}
+
+EGLImage wlr_egl_create_image(EGLenum target,
+ EGLClientBuffer buffer, const EGLint *attribs) {
+ if (!egl_global || !eglCreateImageKHR) {
+ return false;
+ }
+
+ return eglCreateImageKHR(egl_global->display, egl_global->context, target,
+ buffer, attribs);
+}
+
+bool wlr_egl_destroy_image(EGLImage image) {
+ if (!egl_global || !eglDestroyImageKHR) {
+ return false;
+ }
+
+ eglDestroyImageKHR(egl_global->display, image);
+ return true;
}
EGLSurface wlr_egl_create_surface(struct wlr_egl *egl, void *window) {
diff --git a/backend/wayland/backend.c b/backend/wayland/backend.c
index ef480c18..a0fb0be6 100644
--- a/backend/wayland/backend.c
+++ b/backend/wayland/backend.c
@@ -52,6 +52,8 @@ static bool wlr_wl_backend_init(struct wlr_backend_state* state) {
}
wlr_egl_init(&state->egl, EGL_PLATFORM_WAYLAND_EXT, state->remote_display);
+ wlr_egl_bind_display(&state->egl, state->local_display);
+
for (size_t i = 0; i < state->requested_outputs; ++i) {
wlr_wl_output_create(state->backend);
}