From 00f7bf91d85198d5c42ece1e2a5dd63e47aa4645 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Molinari?= Date: Thu, 10 Oct 2024 11:30:42 +0200 Subject: [PATCH] gl-renderer: Add extension flag parser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This new utility parses extension strings and fills a bitfield of matched flags. This will be used to store EGL and GL extension flags. Signed-off-by: Loïc Molinari --- libweston/renderer-gl/gl-renderer-internal.h | 13 +++++ libweston/renderer-gl/gl-renderer.c | 56 ++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/libweston/renderer-gl/gl-renderer-internal.h b/libweston/renderer-gl/gl-renderer-internal.h index 9c7103ed3..99ad1bbab 100644 --- a/libweston/renderer-gl/gl-renderer-internal.h +++ b/libweston/renderer-gl/gl-renderer-internal.h @@ -54,6 +54,8 @@ /* Max number of images per buffer. */ #define SHADER_INPUT_TEX_MAX 3 +#define EXT(string, flag) { string, ARRAY_LENGTH(string) - 1, (uint64_t) flag } + /* Keep the following in sync with vertex.glsl. */ enum gl_shader_texcoord_input { SHADER_TEXCOORD_INPUT_ATTRIB = 0, @@ -107,6 +109,12 @@ static_assert(TEX_UNIT_LAST < 8, "OpenGL ES 2.0 requires at least 8 texture " "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS check at display creation " "to require more."); +struct gl_extension_table { + const char *str; + size_t len; + uint64_t flag; +}; + /** GL shader requirements key * * This structure is used as a binary blob key for building and searching @@ -325,6 +333,11 @@ gl_version_minor(uint32_t ver) return ver & 0xffff; } +void +gl_extensions_add(const struct gl_extension_table *table, + const char *extensions, + uint64_t *flags_out); + static inline struct gl_renderer * get_renderer(struct weston_compositor *ec) { diff --git a/libweston/renderer-gl/gl-renderer.c b/libweston/renderer-gl/gl-renderer.c index 1ecfceded..08665bd16 100644 --- a/libweston/renderer-gl/gl-renderer.c +++ b/libweston/renderer-gl/gl-renderer.c @@ -424,6 +424,62 @@ struct yuv_format_descriptor yuv_formats[] = { } }; +/* Add extension flags to the bitfield that 'flags_out' points to. 'table' + * stores extension names and flags to check for and 'extensions' is the list + * usually returned by the EGL or GL implementation. New flags are stored using + * a binary OR in order to keep flags set from a previous call. Caller must + * ensure the bitfield is set to 0 at first call. + */ +void +gl_extensions_add(const struct gl_extension_table *table, + const char *extensions, + uint64_t *flags_out) +{ + struct { const char *str; size_t len; } *map; + size_t i = 0, n = 0; + uint64_t flags = 0; + char prev_char = ' '; + + /* Get number of extensions. */ + while (extensions[i]) { + if (prev_char == ' ' && extensions[i] != ' ') + n++; + prev_char = extensions[i++]; + } + + if (n == 0) + return; + + /* Allocate data structure mapping each extension with their length. */ + map = xmalloc(n * sizeof *map); + prev_char = ' '; + i = n = 0; + while (prev_char) { + if (extensions[i] != ' ' && extensions[i] != '\0') { + if (prev_char == ' ') + map[n].str = &extensions[i]; + } else if (prev_char != ' ') { + map[n].len = &extensions[i] - map[n].str; + n++; + } + prev_char = extensions[i++]; + } + + /* Match extensions with table. */ + for (; table->str; table++) { + for (i = 0; i < n; i++) { + if (table->len == map[i].len && + !strncmp(table->str, map[i].str, table->len)) { + flags |= table->flag; + break; + } + } + } + + *flags_out |= flags; + free(map); +} + static void timeline_begin_render_query(struct gl_renderer *gr, GLuint query) {