diff options
Diffstat (limited to 'render')
-rw-r--r-- | render/egl.c | 61 | ||||
-rw-r--r-- | render/glapi.txt | 8 | ||||
-rw-r--r-- | render/gles2/renderer.c | 39 | ||||
-rw-r--r-- | render/meson.build | 20 | ||||
-rw-r--r-- | render/wlr_renderer.c | 5 |
5 files changed, 67 insertions, 66 deletions
diff --git a/render/egl.c b/render/egl.c index 82dea50c..9815b923 100644 --- a/render/egl.c +++ b/render/egl.c @@ -4,6 +4,7 @@ #include <stdlib.h> #include <wlr/util/log.h> #include <wlr/egl.h> +#include "render/glapi.h" // Extension documentation // https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_image_base.txt. @@ -46,27 +47,6 @@ const char *egl_error(void) { } } -static bool egl_exts(struct wlr_egl *egl) { - egl->get_platform_display = (PFNEGLGETPLATFORMDISPLAYEXTPROC) - eglGetProcAddress("eglGetPlatformDisplayEXT"); - - if (!egl->get_platform_display) { - wlr_log(L_ERROR, "Failed to load EGL extension 'eglGetPlatformDisplayEXT'"); - return false; - } - - egl->create_platform_window_surface = (PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) - eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT"); - - if (!egl->create_platform_window_surface) { - wlr_log(L_ERROR, - "Failed to load EGL extension 'eglCreatePlatformWindowSurfaceEXT'"); - return false; - } - - return true; -} - static bool egl_get_config(EGLDisplay disp, EGLConfig *out, EGLint visual_id) { EGLint count = 0, matched = 0, ret; @@ -103,7 +83,7 @@ static bool egl_get_config(EGLDisplay disp, EGLConfig *out, EGLint visual_id) { bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, EGLint visual_id, void *remote_display) { - if (!egl_exts(egl)) { + if (!load_glapi()) { return false; } @@ -112,7 +92,7 @@ bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, EGLint visual_id, goto error; } - egl->display = egl->get_platform_display(platform, remote_display, NULL); + egl->display = eglGetPlatformDisplayEXT(platform, remote_display, NULL); if (egl->display == EGL_NO_DISPLAY) { wlr_log(L_ERROR, "Failed to create EGL display: %s", egl_error()); goto error; @@ -142,22 +122,11 @@ bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, EGLint visual_id, 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) { + strstr(egl->egl_exts, "EGL_KHR_image_base") == NULL) { wlr_log(L_ERROR, "Required egl extensions not supported"); goto error; } - egl->eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC) - eglGetProcAddress("eglCreateImageKHR"); - egl->eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC) - eglGetProcAddress("eglDestroyImageKHR"); - egl->eglQueryWaylandBufferWL = (PFNEGLQUERYWAYLANDBUFFERWL) - (void*) eglGetProcAddress("eglQueryWaylandBufferWL"); - egl->eglBindWaylandDisplayWL = (PFNEGLBINDWAYLANDDISPLAYWL) - (void*) eglGetProcAddress("eglBindWaylandDisplayWL"); - egl->eglUnbindWaylandDisplayWL = (PFNEGLUNBINDWAYLANDDISPLAYWL) - (void*) eglGetProcAddress("eglUnbindWaylandDisplayWL"); - 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", egl->egl_exts); @@ -174,8 +143,8 @@ error: void wlr_egl_free(struct wlr_egl *egl) { eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - if (egl->wl_display && egl->eglUnbindWaylandDisplayWL) { - egl->eglUnbindWaylandDisplayWL(egl->display, egl->wl_display); + if (egl->wl_display && eglUnbindWaylandDisplayWL) { + eglUnbindWaylandDisplayWL(egl->display, egl->wl_display); } eglDestroyContext(egl->display, egl->context); @@ -184,11 +153,11 @@ void wlr_egl_free(struct wlr_egl *egl) { } bool wlr_egl_bind_display(struct wlr_egl *egl, struct wl_display *local_display) { - if (!egl->eglBindWaylandDisplayWL) { + if (!eglBindWaylandDisplayWL) { return false; } - if (egl->eglBindWaylandDisplayWL(egl->display, local_display)) { + if (eglBindWaylandDisplayWL(egl->display, local_display)) { egl->wl_display = local_display; return true; } @@ -198,33 +167,33 @@ bool wlr_egl_bind_display(struct wlr_egl *egl, struct wl_display *local_display) bool wlr_egl_query_buffer(struct wlr_egl *egl, struct wl_resource *buf, int attrib, int *value) { - if (!egl->eglQueryWaylandBufferWL) { + if (!eglQueryWaylandBufferWL) { return false; } - return egl->eglQueryWaylandBufferWL(egl->display, buf, attrib, value); + return eglQueryWaylandBufferWL(egl->display, buf, attrib, value); } EGLImage wlr_egl_create_image(struct wlr_egl *egl, EGLenum target, EGLClientBuffer buffer, const EGLint *attribs) { - if (!egl->eglCreateImageKHR) { + if (!eglCreateImageKHR) { return false; } - return egl->eglCreateImageKHR(egl->display, egl->context, target, + return eglCreateImageKHR(egl->display, egl->context, target, buffer, attribs); } bool wlr_egl_destroy_image(struct wlr_egl *egl, EGLImage image) { - if (!egl->eglDestroyImageKHR) { + if (!eglDestroyImageKHR) { return false; } - egl->eglDestroyImageKHR(egl->display, image); + eglDestroyImageKHR(egl->display, image); return true; } EGLSurface wlr_egl_create_surface(struct wlr_egl *egl, void *window) { - EGLSurface surf = egl->create_platform_window_surface(egl->display, egl->config, + EGLSurface surf = eglCreatePlatformWindowSurfaceEXT(egl->display, egl->config, window, NULL); if (surf == EGL_NO_SURFACE) { wlr_log(L_ERROR, "Failed to create EGL surface: %s", egl_error()); diff --git a/render/glapi.txt b/render/glapi.txt new file mode 100644 index 00000000..81791204 --- /dev/null +++ b/render/glapi.txt @@ -0,0 +1,8 @@ +eglGetPlatformDisplayEXT +eglCreatePlatformWindowSurfaceEXT +-eglCreateImageKHR +-eglDestroyImageKHR +-eglQueryWaylandBufferWL +-eglBindWaylandDisplayWL +-eglUnbindWaylandDisplayWL +-glEGLImageTargetTexture2DOES diff --git a/render/gles2/renderer.c b/render/gles2/renderer.c index d6c22ebe..94c50b9a 100644 --- a/render/gles2/renderer.c +++ b/render/gles2/renderer.c @@ -12,8 +12,8 @@ #include <wlr/render/matrix.h> #include <wlr/util/log.h> #include "render/gles2.h" +#include "render/glapi.h" -PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES = NULL; struct shaders shaders; static bool compile_shader(GLuint type, const GLchar *src, GLuint *shader) { @@ -101,25 +101,7 @@ error: wlr_log(L_ERROR, "Failed to set up default shaders!"); } -static void init_image_ext() { - if (glEGLImageTargetTexture2DOES) { - return; - } - - const char *exts = (const char*) glGetString(GL_EXTENSIONS); - if (strstr(exts, "GL_OES_EGL_image_external")) { - glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) - eglGetProcAddress("glEGLImageTargetTexture2DOES"); - } - - if (!glEGLImageTargetTexture2DOES) { - wlr_log(L_INFO, "Failed to load glEGLImageTargetTexture2DOES " - "Will not be able to attach drm buffers"); - } -} - static void init_globals() { - init_image_ext(); init_default_shaders(); } @@ -226,7 +208,23 @@ static bool wlr_gles2_buffer_is_drm(struct wlr_renderer *_renderer, (struct wlr_gles2_renderer *)_renderer; EGLint format; return wlr_egl_query_buffer(renderer->egl, buffer, - EGL_TEXTURE_FORMAT, &format); + EGL_TEXTURE_FORMAT, &format); +} + +static void rgba_to_argb(uint32_t *data, size_t height, size_t stride) { + size_t n = height*stride/4; + for (size_t i = 0; i < n; ++i) { + uint32_t v = data[i]; + uint32_t rgb = (v & 0xffffff00) >> 8; + uint32_t a = v & 0x000000ff; + data[i] = rgb | (a << 24); + } +} + +static void wlr_gles2_read_pixels(struct wlr_renderer *renderer, int x, int y, + int width, int height, void *out_data) { + glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, out_data); + rgba_to_argb(out_data, height, width*4); } static struct wlr_renderer_impl wlr_renderer_impl = { @@ -238,6 +236,7 @@ static struct wlr_renderer_impl wlr_renderer_impl = { .render_ellipse = wlr_gles2_render_ellipse, .formats = wlr_gles2_formats, .buffer_is_drm = wlr_gles2_buffer_is_drm, + .read_pixels = wlr_gles2_read_pixels, }; struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_backend *backend) { diff --git a/render/meson.build b/render/meson.build index dc0ceeb9..749d1393 100644 --- a/render/meson.build +++ b/render/meson.build @@ -1,3 +1,16 @@ +glgen = find_program('../glgen.sh') + +glapi_c = custom_target('glapi.c', + input: 'glapi.txt', + output: '@BASENAME@.c', + command: [glgen, '@INPUT@', '@OUTPUT@'], +) +glapi_h = custom_target('glapi.h', + input: 'glapi.txt', + output: '@BASENAME@.h', + command: [glgen, '@INPUT@', '@OUTPUT@'], +) + lib_wlr_render = static_library( 'wlr_render', files( @@ -11,6 +24,13 @@ lib_wlr_render = static_library( 'wlr_renderer.c', 'wlr_texture.c', ), + glapi_c, + glapi_h, include_directories: wlr_inc, dependencies: [glesv2, egl], ) + +wlr_render = declare_dependency( + link_with: lib_wlr_render, + sources: glapi_h, +) diff --git a/render/wlr_renderer.c b/render/wlr_renderer.c index fec5e38a..ef0c31be 100644 --- a/render/wlr_renderer.c +++ b/render/wlr_renderer.c @@ -51,3 +51,8 @@ bool wlr_renderer_buffer_is_drm(struct wlr_renderer *r, struct wl_resource *buffer) { return r->impl->buffer_is_drm(r, buffer); } + +void wlr_renderer_read_pixels(struct wlr_renderer *r, int x, int y, + int width, int height, void *out_data) { + r->impl->read_pixels(r, x, y, width, height, out_data); +} |