added gles3 impl

This commit is contained in:
William McKinnon 2025-10-27 00:58:07 -04:00
parent 00c96e3ac0
commit 78bffc2df5
21 changed files with 190 additions and 25 deletions

View file

@ -10,6 +10,7 @@
#include <wlr/util/region.h>
#include <xf86drm.h>
#include "render/egl.h"
#include "render/gles.h"
#include "util/env.h"
static enum wlr_log_importance egl_log_importance_to_wlr(EGLint type) {
@ -191,7 +192,7 @@ static void init_dmabuf_formats(struct wlr_egl *egl) {
}
}
static struct wlr_egl *egl_create(void) {
static struct wlr_egl *egl_create(enum egl_version version) {
const char *client_exts_str = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
if (client_exts_str == NULL) {
if (eglGetError() == EGL_BAD_DISPLAY) {
@ -257,6 +258,8 @@ static struct wlr_egl *egl_create(void) {
return NULL;
}
egl->version = version;
return egl;
}
@ -411,7 +414,7 @@ static bool egl_init(struct wlr_egl *egl, EGLenum platform,
size_t atti = 0;
EGLint attribs[7];
attribs[atti++] = EGL_CONTEXT_CLIENT_VERSION;
attribs[atti++] = 2;
attribs[atti++] = egl->version;
// Request a high priority context if possible
// TODO: only do this if we're running as the DRM master
@ -555,10 +558,10 @@ static int open_render_node(int drm_fd) {
return render_fd;
}
struct wlr_egl *wlr_egl_create_with_drm_fd(int drm_fd) {
struct wlr_egl *wlr_egl_create_with_drm_fd(int drm_fd, enum egl_version version) {
bool allow_software = drm_fd < 0;
struct wlr_egl *egl = egl_create();
struct wlr_egl *egl = egl_create(version);
if (egl == NULL) {
wlr_log(WLR_ERROR, "Failed to create EGL context");
return NULL;
@ -615,7 +618,7 @@ error:
}
struct wlr_egl *wlr_egl_create_with_context(EGLDisplay display,
EGLContext context) {
EGLContext context, enum egl_version version) {
EGLint client_type;
if (!eglQueryContext(display, context, EGL_CONTEXT_CLIENT_TYPE, &client_type) ||
client_type != EGL_OPENGL_ES_API) {
@ -630,7 +633,7 @@ struct wlr_egl *wlr_egl_create_with_context(EGLDisplay display,
return NULL;
}
struct wlr_egl *egl = egl_create();
struct wlr_egl *egl = egl_create(version);
if (egl == NULL) {
return NULL;
}

View file

@ -1,4 +1,5 @@
glesv2 = dependency('glesv2', required: 'gles2' in renderers)
glesv3 = dependency('glesv2', required: 'gles3' in renderers)
if not ((glesv2.found() or glesv3.found()) and internal_features['egl'])
subdir_done()
@ -6,8 +7,14 @@ endif
glslang = find_program('glslang', 'glslangValidator', native: true, required: false, disabler: true)
features += { 'gles2-renderer': true }
wlr_deps += glesv2
if glesv2.found()
features += { 'gles2-renderer': true }
wlr_deps += glesv2
endif
if glesv3.found()
features += { 'gles3-renderer': true }
wlr_deps += glesv3
endif
wlr_files += files(
'pass.c',

View file

@ -1,6 +1,14 @@
#include <drm_fourcc.h>
#include <wlr/config.h>
#if WLR_HAS_GLES2_RENDERER
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#else
#include <GLES3/gl3.h>
#include <GLES3/gl3ext.h>
#endif
#include "render/gles.h"
#include "render/pixel_format.h"

View file

@ -9,6 +9,7 @@
#include <unistd.h>
#include <wayland-server-protocol.h>
#include <wayland-util.h>
#include <wlr/config.h>
#include <wlr/render/egl.h>
#include <wlr/render/interface.h>
#include <wlr/render/wlr_renderer.h>
@ -20,11 +21,21 @@
#include "render/pixel_format.h"
#include "util/time.h"
#if WLR_HAS_GLES2_RENDERER
#include "gles2_common_vert_src.h"
#include "gles2_quad_frag_src.h"
#include "gles2_tex_rgba_frag_src.h"
#include "gles2_tex_rgbx_frag_src.h"
#include "gles2_tex_external_frag_src.h"
#endif
#if WLR_HAS_GLES3_RENDERER
#include "gles3_common_vert_src.h"
#include "gles3_quad_frag_src.h"
#include "gles3_tex_rgba_frag_src.h"
#include "gles3_tex_rgbx_frag_src.h"
#include "gles3_tex_external_frag_src.h"
#endif
static const struct wlr_renderer_impl renderer_impl;
static const struct wlr_render_timer_impl render_timer_impl;
@ -633,9 +644,33 @@ struct wlr_renderer *wlr_gles_renderer_create(struct wlr_egl *egl) {
push_gles_debug(renderer);
const char* common_vert_src;
const char* quad_frag_src;
const char* tex_rgba_frag_src;
const char* tex_rgbx_frag_src;
const char* tex_external_frag_src;
if (egl->version == GLES2) {
#if WLR_HAS_GLES2_RENDERER
common_vert_src = gles2_common_vert_src;
quad_frag_src = gles2_quad_frag_src;
tex_rgba_frag_src = gles2_tex_rgba_frag_src;
tex_rgbx_frag_src = gles2_tex_rgbx_frag_src;
tex_external_frag_src = gles2_tex_external_frag_src;
#endif
} else {
#if WLR_HAS_GLES3_RENDERER
common_vert_src = gles3_common_vert_src;
quad_frag_src = gles3_quad_frag_src;
tex_rgba_frag_src = gles3_tex_rgba_frag_src;
tex_rgbx_frag_src = gles3_tex_rgbx_frag_src;
tex_external_frag_src = gles3_tex_external_frag_src;
#endif
}
GLuint prog;
renderer->shaders.quad.program = prog =
link_program(renderer, gles2_common_vert_src, gles2_quad_frag_src);
link_program(renderer, common_vert_src, quad_frag_src);
if (!renderer->shaders.quad.program) {
goto error;
}
@ -644,7 +679,7 @@ struct wlr_renderer *wlr_gles_renderer_create(struct wlr_egl *egl) {
renderer->shaders.quad.pos_attrib = glGetAttribLocation(prog, "pos");
renderer->shaders.tex_rgba.program = prog =
link_program(renderer, gles2_common_vert_src, gles2_tex_rgba_frag_src);
link_program(renderer, common_vert_src, tex_rgba_frag_src);
if (!renderer->shaders.tex_rgba.program) {
goto error;
}
@ -655,7 +690,7 @@ struct wlr_renderer *wlr_gles_renderer_create(struct wlr_egl *egl) {
renderer->shaders.tex_rgba.pos_attrib = glGetAttribLocation(prog, "pos");
renderer->shaders.tex_rgbx.program = prog =
link_program(renderer, gles2_common_vert_src, gles2_tex_rgbx_frag_src);
link_program(renderer, common_vert_src, tex_rgbx_frag_src);
if (!renderer->shaders.tex_rgbx.program) {
goto error;
}
@ -667,7 +702,7 @@ struct wlr_renderer *wlr_gles_renderer_create(struct wlr_egl *egl) {
if (renderer->exts.OES_egl_image_external) {
renderer->shaders.tex_ext.program = prog =
link_program(renderer, gles2_common_vert_src, gles2_tex_external_frag_src);
link_program(renderer, common_vert_src, tex_external_frag_src);
if (!renderer->shaders.tex_ext.program) {
goto error;
}

View file

@ -0,0 +1,12 @@
#version 300 es
uniform mat3 proj;
uniform mat3 tex_proj;
in vec2 pos;
out vec2 v_texcoord;
void main() {
vec3 pos3 = vec3(pos, 1.0);
gl_Position = vec4(pos3 * proj, 1.0);
v_texcoord = (pos3 * tex_proj).xy;
}

View file

@ -0,0 +1,13 @@
#version 300 es
precision highp float;
in vec4 v_color;
in vec2 v_texcoord;
uniform vec4 color;
out vec4 frag_color;
void main() {
frag_color = color;
}

View file

@ -0,0 +1,15 @@
#version 300 es
#extension GL_OES_EGL_image_external_essl3 : require
precision highp float;
in vec2 v_texcoord;
uniform samplerExternalOES texture0;
uniform float alpha;
out vec4 frag_color;
void main() {
frag_color = texture(texture0, v_texcoord) * alpha;
}

View file

@ -0,0 +1,13 @@
#version 300 es
precision highp float;
in vec2 v_texcoord;
uniform sampler2D tex;
uniform float alpha;
out vec4 frag_color;
void main() {
frag_color = texture(tex, v_texcoord) * alpha;
}

View file

@ -0,0 +1,13 @@
#version 300 es
precision highp float;
in vec2 v_texcoord;
uniform sampler2D tex;
uniform float alpha;
out vec4 frag_color;
void main() {
frag_color = vec4(texture(tex, v_texcoord).rgb, 1.0) * alpha;
}

View file

@ -6,6 +6,11 @@ shaders = [
'gles2_tex_rgba.frag',
'gles2_tex_rgbx.frag',
'gles2_tex_external.frag',
'gles3_common.vert',
'gles3_quad.frag',
'gles3_tex_rgba.frag',
'gles3_tex_rgbx.frag',
'gles3_tex_external.frag',
]
foreach name : shaders

View file

@ -1,7 +1,16 @@
#include <assert.h>
#include <drm_fourcc.h>
#include <wlr/config.h>
#if WLR_HAS_GLES2_RENDERER
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#else
#include <GLES3/gl3.h>
#include <GLES3/gl3ext.h>
#endif
#include <stdint.h>
#include <stdlib.h>
#include <wayland-server-protocol.h>

View file

@ -1,6 +1,6 @@
renderers = get_option('renderers')
if 'auto' in renderers and get_option('auto_features').enabled()
renderers = ['gles2', 'vulkan']
renderers = ['gles2', 'gles3', 'vulkan']
elif 'auto' in renderers and get_option('auto_features').disabled()
renderers = []
endif
@ -25,8 +25,8 @@ endif
internal_config.set10('HAVE_EVENTFD', cc.has_header('sys/eventfd.h'))
if 'gles2' in renderers or 'auto' in renderers
egl = dependency('egl', required: 'gles2' in renderers)
if 'gles2' in renderers or 'gles3' in renderers or 'auto' in renderers
egl = dependency('egl', required: 'gles2' in renderers or 'gles3' in renderers)
if egl.found()
eglext_version = cc.get_define(
'EGL_EGLEXT_VERSION',
@ -36,12 +36,12 @@ if 'gles2' in renderers or 'auto' in renderers
if eglext_version < 20210604
egl = dependency(
'',
required: 'gles2' in renderers,
required: 'gles2' in renderers or 'gles3' in renderers,
not_found_message: 'EGL headers too old',
)
endif
endif
gbm = dependency('gbm', required: 'gles2' in renderers)
gbm = dependency('gbm', required: 'gles2' in renderers or 'gles3' in renderers)
if egl.found() and gbm.found()
wlr_deps += [egl, gbm]
wlr_files += files('egl.c')

View file

@ -16,7 +16,7 @@
#include <wlr/config.h>
#if WLR_HAS_GLES2_RENDERER
#if WLR_HAS_GLES2_RENDERER || WLR_HAS_GLES3_RENDERER
#include <wlr/render/egl.h>
#include <wlr/render/gles.h>
#endif
@ -220,6 +220,7 @@ static struct wlr_renderer *renderer_autocreate(struct wlr_backend *backend, int
const char *renderer_options[] = {
"auto",
"gles2",
"gles3",
"vulkan",
"pixman",
NULL
@ -236,7 +237,7 @@ static struct wlr_renderer *renderer_autocreate(struct wlr_backend *backend, int
log_creation_failure(is_auto, "Cannot create GLES2 renderer: no DRM FD available");
} else {
#if WLR_HAS_GLES2_RENDERER
renderer = wlr_gles_renderer_create_with_drm_fd(drm_fd);
renderer = wlr_gles_renderer_create_with_drm_fd(drm_fd, GLES2);
#else
wlr_log(WLR_ERROR, "Cannot create GLES2 renderer: disabled at compile-time");
#endif
@ -248,6 +249,23 @@ static struct wlr_renderer *renderer_autocreate(struct wlr_backend *backend, int
}
}
if ((is_auto && WLR_HAS_GLES3_RENDERER) || strcmp(renderer_name, "gles3") == 0) {
if (!open_preferred_drm_fd(backend, &drm_fd, &own_drm_fd)) {
log_creation_failure(is_auto, "Cannot create GLES3 renderer: no DRM FD available");
} else {
#if WLR_HAS_GLES3_RENDERER
renderer = wlr_gles_renderer_create_with_drm_fd(drm_fd, GLES3);
#else
wlr_log(WLR_ERROR, "Cannot create GLES3 renderer: disabled at compile-time");
#endif
if (renderer) {
goto out;
} else {
log_creation_failure(is_auto, "Failed to create a GLES3 renderer");
}
}
}
if ((is_auto && WLR_HAS_VULKAN_RENDERER) || strcmp(renderer_name, "vulkan") == 0) {
if (!open_preferred_drm_fd(backend, &drm_fd, &own_drm_fd)) {
log_creation_failure(is_auto, "Cannot create Vulkan renderer: no DRM FD available");