diff options
author | Drew DeVault <sir@cmpwn.com> | 2017-08-10 22:20:21 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-10 22:20:21 -0400 |
commit | 6569c2b62614384b268eb20feb7818f3c0cf606c (patch) | |
tree | 4be63a8f4e2edfcecd228f23e9846403ddf39281 /backend | |
parent | fe2fbd0fad96624ab64a86b0b8eb8ead769908f2 (diff) | |
parent | c24351681f672a2ce561b9cb6d73172dfc36c45c (diff) |
Merge pull request #53 from nyorain/drm_buffer
Implement drm (egl) buffer attaching
Diffstat (limited to 'backend')
-rw-r--r-- | backend/backend.c | 7 | ||||
-rw-r--r-- | backend/drm/backend.c | 12 | ||||
-rw-r--r-- | backend/drm/drm.c | 2 | ||||
-rw-r--r-- | backend/egl.c | 180 | ||||
-rw-r--r-- | backend/meson.build | 1 | ||||
-rw-r--r-- | backend/multi/backend.c | 14 | ||||
-rw-r--r-- | backend/wayland/backend.c | 10 | ||||
-rw-r--r-- | backend/wayland/output.c | 1 |
8 files changed, 42 insertions, 185 deletions
diff --git a/backend/backend.c b/backend/backend.c index 4da3fe7a..dc34c80b 100644 --- a/backend/backend.c +++ b/backend/backend.c @@ -39,6 +39,13 @@ void wlr_backend_destroy(struct wlr_backend *backend) { free(backend); } +struct wlr_egl *wlr_backend_get_egl(struct wlr_backend *backend) { + if (!backend->impl->get_egl) { + return NULL; + } + return backend->impl->get_egl(backend->state); +} + static struct wlr_backend *attempt_wl_backend(struct wl_display *display) { struct wlr_backend *backend = wlr_wl_backend_create(display); if (backend) { diff --git a/backend/drm/backend.c b/backend/drm/backend.c index e361358e..a7e6824c 100644 --- a/backend/drm/backend.c +++ b/backend/drm/backend.c @@ -12,6 +12,7 @@ #include <wlr/interfaces/wlr_output.h> #include <wlr/util/list.h> #include <wlr/util/log.h> +#include <wlr/egl.h> #include "backend/udev.h" #include "backend/drm.h" @@ -38,9 +39,14 @@ static void wlr_drm_backend_destroy(struct wlr_backend_state *drm) { free(drm); } +static struct wlr_egl *wlr_drm_backend_get_egl(struct wlr_backend_state *drm) { + return &drm->renderer.egl; +} + static struct wlr_backend_impl backend_impl = { .init = wlr_drm_backend_init, - .destroy = wlr_drm_backend_destroy + .destroy = wlr_drm_backend_destroy, + .get_egl = wlr_drm_backend_get_egl }; static void session_signal(struct wl_listener *listener, void *data) { @@ -149,6 +155,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 b5742eca..8062a478 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(drm->base); if (!plane->wlr_rend) { return false; } diff --git a/backend/egl.c b/backend/egl.c deleted file mode 100644 index a547523c..00000000 --- a/backend/egl.c +++ /dev/null @@ -1,180 +0,0 @@ -#include <EGL/egl.h> -#include <EGL/eglext.h> -#include <GLES3/gl3.h> -#include <gbm.h> // GBM_FORMAT_XRGB8888 -#include <wlr/util/log.h> -#include "backend/egl.h" - -const char *egl_error(void) { - switch (eglGetError()) { - case EGL_SUCCESS: - return "Success"; - case EGL_NOT_INITIALIZED: - return "Not initialized"; - case EGL_BAD_ACCESS: - return "Bad access"; - case EGL_BAD_ALLOC: - return "Bad alloc"; - case EGL_BAD_ATTRIBUTE: - return "Bad attribute"; - case EGL_BAD_CONTEXT: - return "Bad Context"; - case EGL_BAD_CONFIG: - return "Bad Config"; - case EGL_BAD_CURRENT_SURFACE: - return "Bad current surface"; - case EGL_BAD_DISPLAY: - return "Bad display"; - case EGL_BAD_SURFACE: - return "Bad surface"; - case EGL_BAD_MATCH: - return "Bad match"; - case EGL_BAD_PARAMETER: - return "Bad parameter"; - case EGL_BAD_NATIVE_PIXMAP: - return "Bad native pixmap"; - case EGL_BAD_NATIVE_WINDOW: - return "Bad native window"; - case EGL_CONTEXT_LOST: - return "Context lost"; - default: - return "Unknown"; - } -} - -// EGL extensions -PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display; -PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC create_platform_window_surface; - -static bool egl_exts() { - get_platform_display = (PFNEGLGETPLATFORMDISPLAYEXTPROC) - eglGetProcAddress("eglGetPlatformDisplayEXT"); - - if (!get_platform_display) { - wlr_log(L_ERROR, "Failed to load EGL extension 'eglGetPlatformDisplayEXT'"); - return false; - } - - create_platform_window_surface = (PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) - eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT"); - - if (!get_platform_display) { - wlr_log(L_ERROR, - "Failed to load EGL extension 'eglCreatePlatformWindowSurfaceEXT'"); - return false; - } - - return true; -} - -static bool egl_get_config(EGLDisplay disp, EGLConfig *out, EGLenum platform) { - EGLint count = 0, matched = 0, ret; - - ret = eglGetConfigs(disp, NULL, 0, &count); - if (ret == EGL_FALSE || count == 0) { - wlr_log(L_ERROR, "eglGetConfigs returned no configs"); - return false; - } - - EGLConfig configs[count]; - - ret = eglChooseConfig(disp, NULL, configs, count, &matched); - if (ret == EGL_FALSE) { - wlr_log(L_ERROR, "eglChooseConfig failed"); - return false; - } - - for (int i = 0; i < matched; ++i) { - EGLint gbm_format; - - if (platform == EGL_PLATFORM_WAYLAND_EXT) { - *out = configs[i]; - return true; - } - - if (!eglGetConfigAttrib(disp, - configs[i], - EGL_NATIVE_VISUAL_ID, - &gbm_format)) { - continue; - } - - if (gbm_format == GBM_FORMAT_ARGB8888) { - *out = configs[i]; - return true; - } - } - - wlr_log(L_ERROR, "no valid egl config found"); - return false; -} - -bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *display) { - if (!egl_exts()) { - return false; - } - - if (eglBindAPI(EGL_OPENGL_ES_API) == EGL_FALSE) { - wlr_log(L_ERROR, "Failed to bind to the OpenGL ES API: %s", egl_error()); - goto error; - } - - egl->display = get_platform_display(platform, display, NULL); - if (egl->display == EGL_NO_DISPLAY) { - wlr_log(L_ERROR, "Failed to create EGL display: %s", egl_error()); - goto error; - } - - EGLint major, minor; - if (eglInitialize(egl->display, &major, &minor) == EGL_FALSE) { - wlr_log(L_ERROR, "Failed to initialize EGL: %s", egl_error()); - goto error; - } - - if (!egl_get_config(egl->display, &egl->config, platform)) { - wlr_log(L_ERROR, "Failed to get EGL config"); - goto error; - } - - static const EGLint attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; - - egl->context = eglCreateContext(egl->display, egl->config, - EGL_NO_CONTEXT, attribs); - - if (egl->context == EGL_NO_CONTEXT) { - wlr_log(L_ERROR, "Failed to create EGL context: %s", egl_error()); - goto error; - } - - eglMakeCurrent(egl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, egl->context); - 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, "Using %s", glGetString(GL_VERSION)); - wlr_log(L_INFO, "Supported OpenGL ES extensions: %s", glGetString(GL_EXTENSIONS)); - return true; - -error: - eglTerminate(egl->display); - eglReleaseThread(); - eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - return false; -} - -void wlr_egl_free(struct wlr_egl *egl) { - eglMakeCurrent(egl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - eglDestroyContext(egl->display, egl->context); - eglTerminate(egl->display); - eglReleaseThread(); - eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); -} - -EGLSurface wlr_egl_create_surface(struct wlr_egl *egl, void *window) { - EGLSurface surf = create_platform_window_surface(egl->display, egl->config, - window, NULL); - if (surf == EGL_NO_SURFACE) { - wlr_log(L_ERROR, "Failed to create EGL surface: %s", egl_error()); - return EGL_NO_SURFACE; - } - return surf; -} diff --git a/backend/meson.build b/backend/meson.build index bb1b84c8..9c6b70df 100644 --- a/backend/meson.build +++ b/backend/meson.build @@ -1,6 +1,5 @@ wlr_files += files( 'backend.c', - 'egl.c', 'udev.c', 'session/direct-ipc.c', 'session/direct.c', diff --git a/backend/multi/backend.c b/backend/multi/backend.c index 19839629..9563356d 100644 --- a/backend/multi/backend.c +++ b/backend/multi/backend.c @@ -38,9 +38,21 @@ static void multi_backend_destroy(struct wlr_backend_state *state) { free(state); } +static struct wlr_egl *multi_backend_get_egl(struct wlr_backend_state *state) { + for (size_t i = 0; i < state->backends->length; ++i) { + struct subbackend_state *sub = state->backends->items[i]; + struct wlr_egl *egl = wlr_backend_get_egl(sub->backend); + if (egl) { + return egl; + } + } + return NULL; +} + struct wlr_backend_impl backend_impl = { .init = multi_backend_init, - .destroy = multi_backend_destroy + .destroy = multi_backend_destroy, + .get_egl = multi_backend_get_egl }; struct wlr_backend *wlr_multi_backend_create(struct wlr_session *session, diff --git a/backend/wayland/backend.c b/backend/wayland/backend.c index ef480c18..1a156802 100644 --- a/backend/wayland/backend.c +++ b/backend/wayland/backend.c @@ -4,6 +4,7 @@ #include <EGL/egl.h> #include <EGL/eglext.h> #include <wayland-server.h> +#include <wlr/egl.h> #include <wlr/backend/interface.h> #include <wlr/interfaces/wlr_output.h> #include <wlr/interfaces/wlr_input_device.h> @@ -52,6 +53,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); } @@ -93,9 +96,14 @@ static void wlr_wl_backend_destroy(struct wlr_backend_state *state) { free(state); } +static struct wlr_egl *wlr_wl_backend_get_egl(struct wlr_backend_state *state) { + return &state->egl; +} + static struct wlr_backend_impl backend_impl = { .init = wlr_wl_backend_init, - .destroy = wlr_wl_backend_destroy + .destroy = wlr_wl_backend_destroy, + .get_egl = wlr_wl_backend_get_egl }; bool wlr_backend_is_wl(struct wlr_backend *b) { diff --git a/backend/wayland/output.c b/backend/wayland/output.c index 96f71efa..2c7086e2 100644 --- a/backend/wayland/output.c +++ b/backend/wayland/output.c @@ -117,6 +117,7 @@ struct wlr_output *wlr_wl_output_create(struct wlr_backend *_backend) { strncpy(wlr_output->model, "wayland", sizeof(wlr_output->model)); snprintf(wlr_output->name, sizeof(wlr_output->name), "WL-%zd", backend->outputs->length + 1); + wlr_output_update_matrix(wlr_output); ostate->backend = backend; ostate->wlr_output = wlr_output; |