Skip to content

Commit

Permalink
egl: implement multi-context support
Browse files Browse the repository at this point in the history
Signed-off-by: Steven Noonan <[email protected]>
  • Loading branch information
tycho committed Nov 2, 2022
1 parent ba3c786 commit d6d562c
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 47 deletions.
4 changes: 2 additions & 2 deletions glad/generator/c/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
jinja2_contextfilter
)
from glad.parse import Type, EnumType
from glad.specification import VK, GL, WGL
from glad.specification import VK, EGL, GL, WGL
import glad.util

_ARRAY_RE = re.compile(r'\[[\d\w]*\]')
Expand Down Expand Up @@ -324,7 +324,7 @@ def get_template_arguments(self, spec, feature_set, config):
args = JinjaGenerator.get_template_arguments(self, spec, feature_set, config)

# TODO allow MX for every specification/api
if spec.name not in (VK.NAME, GL.NAME):
if spec.name not in (EGL.NAME, VK.NAME, GL.NAME):
args['options']['mx'] = False
args['options']['mx_global'] = False

Expand Down
72 changes: 49 additions & 23 deletions glad/generator/c/templates/egl.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{% extends 'base_template.c' %}

{% block loader %}
static int glad_egl_get_extensions(EGLDisplay display, const char **extensions) {
*extensions = eglQueryString(display, EGL_EXTENSIONS);
static int glad_egl_get_extensions({{ template_utils.context_arg(', ') }}EGLDisplay display, const char **extensions) {
*extensions = {{ 'eglQueryString'|ctx }}(display, EGL_EXTENSIONS);

return extensions != NULL;
}
Expand Down Expand Up @@ -32,29 +32,29 @@ static GLADapiproc glad_egl_get_proc_from_userptr(void *userptr, const char *nam
}

{% for api in feature_set.info.apis %}
static int glad_egl_find_extensions_{{ api|lower }}(EGLDisplay display) {
static int glad_egl_find_extensions_{{ api|lower }}({{ template_utils.context_arg(', ') }}EGLDisplay display) {
const char *extensions;
if (!glad_egl_get_extensions(display, &extensions)) return 0;
if (!glad_egl_get_extensions({{'context, ' if options.mx }}display, &extensions)) return 0;

{% for extension in feature_set.extensions %}
GLAD_{{ extension.name }} = glad_egl_has_extension(extensions, "{{ extension.name }}");
{{ ('GLAD_' + extension.name)|ctx(name_only=True) }} = glad_egl_has_extension(extensions, "{{ extension.name }}");
{% else %}
GLAD_UNUSED(glad_egl_has_extension);
{% endfor %}

return 1;
}

static int glad_egl_find_core_{{ api|lower }}(EGLDisplay display) {
static int glad_egl_find_core_{{ api|lower }}({{ template_utils.context_arg(', ') }}EGLDisplay display) {
int major, minor;
const char *version;

if (display == NULL) {
display = EGL_NO_DISPLAY; /* this is usually NULL, better safe than sorry */
}

version = eglQueryString(display, EGL_VERSION);
(void) eglGetError();
version = {{ 'eglQueryString'|ctx }}(display, EGL_VERSION);
(void) {{ 'eglGetError'|ctx }}();

if (version == NULL) {
major = 1;
Expand All @@ -64,41 +64,67 @@ static int glad_egl_find_core_{{ api|lower }}(EGLDisplay display) {
}

{% for feature in feature_set.features %}
GLAD_{{ feature.name }} = (major == {{ feature.version.major }} && minor >= {{ feature.version.minor }}) || major > {{ feature.version.major }};
{{ ('GLAD_' + feature.name)|ctx(name_only=True) }} = (major == {{ feature.version.major }} && minor >= {{ feature.version.minor }}) || major > {{ feature.version.major }};
{% endfor %}

return GLAD_MAKE_VERSION(major, minor);
}

int gladLoad{{ api|api }}UserPtr(EGLDisplay display, GLADuserptrloadfunc load, void* userptr) {
int gladLoad{{ api|api }}{{ 'Context' if options.mx }}UserPtr({{ template_utils.context_arg(', ') }}EGLDisplay display, GLADuserptrloadfunc load, void *userptr) {
int version;
eglGetDisplay = (PFNEGLGETDISPLAYPROC) load(userptr, "eglGetDisplay");
eglGetCurrentDisplay = (PFNEGLGETCURRENTDISPLAYPROC) load(userptr, "eglGetCurrentDisplay");
eglQueryString = (PFNEGLQUERYSTRINGPROC) load(userptr, "eglQueryString");
eglGetError = (PFNEGLGETERRORPROC) load(userptr, "eglGetError");
if (eglGetDisplay == NULL || eglGetCurrentDisplay == NULL || eglQueryString == NULL || eglGetError == NULL) return 0;
{{ 'eglGetDisplay'|ctx }} = (PFNEGLGETDISPLAYPROC) load(userptr, "eglGetDisplay");
{{ 'eglGetCurrentDisplay'|ctx }} = (PFNEGLGETCURRENTDISPLAYPROC) load(userptr, "eglGetCurrentDisplay");
{{ 'eglQueryString'|ctx }} = (PFNEGLQUERYSTRINGPROC) load(userptr, "eglQueryString");
{{ 'eglGetError'|ctx }} = (PFNEGLGETERRORPROC) load(userptr, "eglGetError");
if ({{ 'eglGetDisplay'|ctx }} == NULL || {{ 'eglGetCurrentDisplay'|ctx }} == NULL || {{ 'eglQueryString'|ctx }} == NULL || {{ 'eglGetError'|ctx }} == NULL) return 0;

version = glad_egl_find_core_{{ api|lower }}(display);
version = glad_egl_find_core_{{ api|lower }}({{'context, ' if options.mx }}display);
if (!version) return 0;
{% for feature, _ in loadable(feature_set.features) %}
glad_egl_load_{{ feature.name }}(load, userptr);
{% for feature, _ in loadable(feature_set.features, api=api) %}
glad_egl_load_{{ feature.name }}({{'context, ' if options.mx }}load, userptr);
{% endfor %}

if (!glad_egl_find_extensions_{{ api|lower }}(display)) return 0;
{% for extension, _ in loadable(feature_set.extensions) %}
glad_egl_load_{{ extension.name }}(load, userptr);
if (!glad_egl_find_extensions_{{ api|lower }}({{'context, ' if options.mx }}display)) return 0;
{% for extension, _ in loadable(feature_set.extensions, api=api) %}
glad_egl_load_{{ extension.name }}({{'context, ' if options.mx }}load, userptr);
{% endfor %}

{% if options.mx_global %}
gladSet{{ feature_set.name|api }}Context(context);
{% endif %}

{% if options.alias %}
glad_egl_resolve_aliases();
glad_egl_resolve_aliases({{ 'context' if options.mx }});
{% endif %}

return version;
}

{% if options.mx_global %}
int gladLoad{{ api|api }}UserPtr(EGLDisplay display, GLADuserptrloadfunc load, void *userptr) {
return gladLoad{{ api|api }}ContextUserPtr(gladGet{{ feature_set.name|api }}Context(), display, load, userptr);
}
{% endif %}

int gladLoad{{ api|api }}{{ 'Context' if options.mx }}({{ template_utils.context_arg(', ') }}EGLDisplay display, GLADloadfunc load) {
return gladLoad{{ api|api }}{{ 'Context' if options.mx }}UserPtr({{'context,' if options.mx }} display, glad_egl_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load);
}

{% if options.mx_global %}
int gladLoad{{ api|api }}(EGLDisplay display, GLADloadfunc load) {
return gladLoad{{ api|api }}UserPtr(display, glad_egl_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load);
return gladLoad{{ api|api }}Context(gladGet{{ feature_set.name|api }}Context(), display, load);
}
{% endif %}
{% endfor %}

{% if options.mx_global %}
Glad{{ feature_set.name|api }}Context* gladGet{{ feature_set.name|api }}Context() {
return {{ global_context }};
}

void gladSet{{ feature_set.name|api }}Context(Glad{{ feature_set.name|api }}Context *context) {
{{ global_context }} = context;
}
{% endif %}

{% endblock %}
5 changes: 5 additions & 0 deletions glad/generator/c/templates/egl.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@

{% block custom_declarations %}
{% for api in feature_set.info.apis %}
GLAD_API_CALL int gladLoad{{ api|api }}{{ 'Context' if options.mx }}UserPtr({{ template_utils.context_arg(',') }} EGLDisplay display, GLADuserptrloadfunc load, void *userptr);
GLAD_API_CALL int gladLoad{{ api|api }}{{ 'Context' if options.mx }}({{ template_utils.context_arg(',') }} EGLDisplay display, GLADloadfunc load);

{% if options.mx_global %}
GLAD_API_CALL int gladLoad{{ api|api }}UserPtr(EGLDisplay display, GLADuserptrloadfunc load, void *userptr);
GLAD_API_CALL int gladLoad{{ api|api }}(EGLDisplay display, GLADloadfunc load);
{% endif %}
{% endfor %}
{% endblock %}
66 changes: 46 additions & 20 deletions glad/generator/c/templates/loader/egl.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ static GLADapiproc glad_egl_get_proc(void *vuserptr, const char* name) {
return result;
}

static void* _egl_handle = NULL;
{% if not options.mx %}
static void* {{ template_utils.handle() }} = NULL;
{% endif %}

static void* glad_egl_dlopen_handle(void) {
static void* glad_egl_dlopen_handle({{ template_utils.context_arg(def='void') }}) {
#if GLAD_PLATFORM_APPLE
static const char *NAMES[] = {"libEGL.dylib"};
#elif GLAD_PLATFORM_WIN32
Expand All @@ -31,11 +33,11 @@ static void* glad_egl_dlopen_handle(void) {
static const char *NAMES[] = {"libEGL.so.1", "libEGL.so"};
#endif

if (_egl_handle == NULL) {
_egl_handle = glad_get_dlopen_handle(NAMES, sizeof(NAMES) / sizeof(NAMES[0]));
if ({{ template_utils.handle() }} == NULL) {
{{ template_utils.handle() }} = glad_get_dlopen_handle(NAMES, sizeof(NAMES) / sizeof(NAMES[0]));
}

return _egl_handle;
return {{ template_utils.handle() }};
}

static struct _glad_egl_userptr glad_egl_build_userptr(void *handle) {
Expand All @@ -46,30 +48,34 @@ static struct _glad_egl_userptr glad_egl_build_userptr(void *handle) {
}

{% if not options.on_demand %}
int gladLoaderLoadEGL(EGLDisplay display) {
int gladLoaderLoadEGL{{ 'Context' if options.mx }}({{ template_utils.context_arg(',') }} EGLDisplay display) {
int version = 0;
void *handle = NULL;
void *handle;
int did_load = 0;
struct _glad_egl_userptr userptr;

did_load = _egl_handle == NULL;
handle = glad_egl_dlopen_handle();
if (handle != NULL) {
did_load = {{ template_utils.handle() }} == NULL;
handle = glad_egl_dlopen_handle({{ 'context' if options.mx }});
if (handle) {
userptr = glad_egl_build_userptr(handle);

if (userptr.get_proc_address_ptr != NULL) {
version = gladLoadEGLUserPtr(display, glad_egl_get_proc, &userptr);
}
version = gladLoadEGL{{ 'Context' if options.mx }}UserPtr({{ 'context, ' if options.mx }}display, glad_egl_get_proc, &userptr);

if (!version && did_load) {
gladLoaderUnloadEGL();
if (did_load) {
gladLoaderUnloadEGL{{ 'Context' if options.mx }}({{ 'context' if options.mx }});
}
}

return version;
}
{% endif %}

{% if options.mx_global %}
int gladLoaderLoadEGL(EGLDisplay display) {
return gladLoaderLoadEGLContext(gladGet{{ feature_set.name|api }}Context(), display);
}
{% endif %}

{% if options.on_demand %}
{% call template_utils.zero_initialized() %}static struct _glad_egl_userptr glad_egl_internal_loader_global_userptr{% endcall %}
static GLADapiproc glad_egl_internal_loader_get_proc(const char *name) {
Expand All @@ -81,19 +87,38 @@ static GLADapiproc glad_egl_internal_loader_get_proc(const char *name) {
}
{% endif %}

void gladLoaderUnloadEGL() {
if (_egl_handle != NULL) {
glad_close_dlopen_handle(_egl_handle);
_egl_handle = NULL;
{% if options.mx_global %}
void gladLoaderResetEGL(void) {
gladLoaderResetEGLContext(gladGetEGLContext());
}
{% endif %}

void gladLoaderUnloadEGL{{ 'Context' if options.mx }}({{ template_utils.context_arg(def='void') }}) {
if ({{ template_utils.handle() }} != NULL) {
glad_close_dlopen_handle({{ template_utils.handle() }});
{{ template_utils.handle() }} = NULL;
{% if options.on_demand %}
glad_egl_internal_loader_global_userptr.handle = NULL;
{% endif %}
}

{% if not options.mx %}
gladLoaderResetEGL();
{% else %}
gladLoaderResetEGLContext(context);
{% endif %}
}

void gladLoaderResetEGL() {
{%if options.mx_global %}
void gladLoaderUnloadEGL(void) {
gladLoaderUnloadEGLContext(gladGet{{ feature_set.name|api }}Context());
}
{% endif %}

void gladLoaderResetEGL{{ 'Context' if options.mx }}({{ template_utils.context_arg(def='void') }}) {
{% if options.mx %}
memset(context, 0, sizeof(GladEGLContext));
{% else %}
{% if not options.on_demand %}
{% for feature in feature_set.features %}
GLAD_{{ feature.name }} = 0;
Expand All @@ -114,6 +139,7 @@ void gladLoaderResetEGL() {
{{ command.name|ctx }} = NULL;
{% endfor %}
{% endfor %}
{% endif %}
}

#endif /* GLAD_EGL */
8 changes: 6 additions & 2 deletions glad/generator/c/templates/loader/egl.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
#ifdef GLAD_EGL

{% if not options.on_demand %}
GLAD_API_CALL int gladLoaderLoadEGL(EGLDisplay display);
GLAD_API_CALL int gladLoaderLoadEGL{{ 'Context' if options.mx }}({{ template_utils.context_arg(',') }} EGLDisplay display);
{% endif %}

GLAD_API_CALL void gladLoaderUnloadEGL{{ 'Context' if options.mx }}({{ template_utils.context_arg(def='void') }});
GLAD_API_CALL void gladLoaderResetEGL{{ 'Context' if options.mx }}({{ template_utils.context_arg(def='void') }});
{% if options.mx_global %}
GLAD_API_CALL int gladLoaderLoadEGL(EGLDisplay display);
GLAD_API_CALL void gladLoaderUnloadEGL(void);
GLAD_API_CALL void gladLoaderResetEGL(void);
{% endif %}

#endif

0 comments on commit d6d562c

Please sign in to comment.