Refactor EGL/GL API loading
Remove glapi.sh code generation, replace it with hand-written loading code that checks extension strings before calling eglGetProcAddress. The GLES2 renderer still uses global state because of: - {PUSH,POP}_GLES2_DEBUG macros - wlr_gles2_texture_from_* taking a wlr_egl instead of the renderer
This commit is contained in:
parent
774548696c
commit
515679e4fe
|
@ -11,7 +11,6 @@
|
||||||
#include <wlr/types/wlr_matrix.h>
|
#include <wlr/types/wlr_matrix.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include "backend/drm/drm.h"
|
#include "backend/drm/drm.h"
|
||||||
#include "glapi.h"
|
|
||||||
|
|
||||||
bool init_drm_renderer(struct wlr_drm_backend *drm,
|
bool init_drm_renderer(struct wlr_drm_backend *drm,
|
||||||
struct wlr_drm_renderer *renderer, wlr_renderer_create_func_t create_renderer_func) {
|
struct wlr_drm_renderer *renderer, wlr_renderer_create_func_t create_renderer_func) {
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include <wlr/render/gles2.h>
|
#include <wlr/render/gles2.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include "backend/headless.h"
|
#include "backend/headless.h"
|
||||||
#include "glapi.h"
|
|
||||||
#include "util/signal.h"
|
#include "util/signal.h"
|
||||||
|
|
||||||
struct wlr_headless_backend *headless_backend_from_backend(
|
struct wlr_headless_backend *headless_backend_from_backend(
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include <wlr/render/gles2.h>
|
#include <wlr/render/gles2.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include "backend/rdp.h"
|
#include "backend/rdp.h"
|
||||||
#include "glapi.h"
|
|
||||||
#include "util/signal.h"
|
#include "util/signal.h"
|
||||||
|
|
||||||
struct wlr_rdp_backend *rdp_backend_from_backend(
|
struct wlr_rdp_backend *rdp_backend_from_backend(
|
||||||
|
|
103
glgen.sh
103
glgen.sh
|
@ -1,103 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# Generates a simple GL/EGL extension function loader.
|
|
||||||
#
|
|
||||||
# The input is a .txt file, with each function to load on its own line.
|
|
||||||
# If a line starts with a -, it is optional, and will not cause the loader
|
|
||||||
# to fail if it can't load the function. You'll need to check if that function
|
|
||||||
# is NULL before using it.
|
|
||||||
|
|
||||||
if [ $# -ne 2 ]; then
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
SPEC=$1
|
|
||||||
OUTDIR=$2
|
|
||||||
|
|
||||||
BASE=$(basename "$SPEC" .txt)
|
|
||||||
INCLUDE_GUARD=$(printf %s_%s_H "$OUTDIR" "$BASE" | tr -c [:alnum:] _ | tr [:lower:] [:upper:])
|
|
||||||
|
|
||||||
DECL=""
|
|
||||||
DEFN=""
|
|
||||||
LOADER=""
|
|
||||||
|
|
||||||
DECL_FMT='extern %s %s;'
|
|
||||||
DEFN_FMT='%s %s;'
|
|
||||||
LOADER_FMT='%s = (%s)eglGetProcAddress("%s");'
|
|
||||||
CHECK_FMT='if (!%s) {
|
|
||||||
wlr_log(WLR_ERROR, "Unable to load %s");
|
|
||||||
return false;
|
|
||||||
}'
|
|
||||||
|
|
||||||
while read -r COMMAND; do
|
|
||||||
OPTIONAL=0
|
|
||||||
FUNC_PTR_FMT='PFN%sPROC'
|
|
||||||
|
|
||||||
case $COMMAND in
|
|
||||||
-*)
|
|
||||||
OPTIONAL=1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
case $COMMAND in
|
|
||||||
*WL)
|
|
||||||
FUNC_PTR_FMT='PFN%s'
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
COMMAND=${COMMAND#-}
|
|
||||||
FUNC_PTR=$(printf "$FUNC_PTR_FMT" "$COMMAND" | tr [:lower:] [:upper:])
|
|
||||||
|
|
||||||
DECL="$DECL$(printf "\n$DECL_FMT" "$FUNC_PTR" "$COMMAND")"
|
|
||||||
DEFN="$DEFN$(printf "\n$DEFN_FMT" "$FUNC_PTR" "$COMMAND")"
|
|
||||||
LOADER="$LOADER$(printf "\n$LOADER_FMT" "$COMMAND" "$FUNC_PTR" "$COMMAND")"
|
|
||||||
|
|
||||||
if [ $OPTIONAL -eq 0 ]; then
|
|
||||||
LOADER="$LOADER$(printf "\n$CHECK_FMT" "$COMMAND" "$COMMAND")"
|
|
||||||
fi
|
|
||||||
done < "$SPEC"
|
|
||||||
|
|
||||||
cat > "$OUTDIR/$BASE.h" << EOF
|
|
||||||
#ifndef $INCLUDE_GUARD
|
|
||||||
#define $INCLUDE_GUARD
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <wlr/config.h>
|
|
||||||
|
|
||||||
#if !WLR_HAS_X11_BACKEND && !WLR_HAS_XWAYLAND
|
|
||||||
#ifndef MESA_EGL_NO_X11_HEADERS
|
|
||||||
#define MESA_EGL_NO_X11_HEADERS
|
|
||||||
#endif
|
|
||||||
#ifndef EGL_NO_X11
|
|
||||||
#define EGL_NO_X11
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <EGL/egl.h>
|
|
||||||
#include <EGL/eglext.h>
|
|
||||||
#include <EGL/eglmesaext.h>
|
|
||||||
#include <GLES2/gl2.h>
|
|
||||||
#include <GLES2/gl2ext.h>
|
|
||||||
|
|
||||||
bool load_$BASE(void);
|
|
||||||
$DECL
|
|
||||||
|
|
||||||
#endif
|
|
||||||
EOF
|
|
||||||
|
|
||||||
cat > "$OUTDIR/$BASE.c" << EOF
|
|
||||||
#include <wlr/util/log.h>
|
|
||||||
#include "$BASE.h"
|
|
||||||
$DEFN
|
|
||||||
|
|
||||||
bool load_$BASE(void) {
|
|
||||||
static bool done = false;
|
|
||||||
if (done) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
$LOADER
|
|
||||||
|
|
||||||
done = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
EOF
|
|
|
@ -14,6 +14,16 @@
|
||||||
#include <wlr/render/wlr_texture.h>
|
#include <wlr/render/wlr_texture.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
|
|
||||||
|
struct wlr_gles2_procs {
|
||||||
|
PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES;
|
||||||
|
PFNGLDEBUGMESSAGECALLBACKKHRPROC glDebugMessageCallbackKHR;
|
||||||
|
PFNGLDEBUGMESSAGECONTROLKHRPROC glDebugMessageControlKHR;
|
||||||
|
PFNGLPOPDEBUGGROUPKHRPROC glPopDebugGroupKHR;
|
||||||
|
PFNGLPUSHDEBUGGROUPKHRPROC glPushDebugGroupKHR;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct wlr_gles2_procs gles2_procs;
|
||||||
|
|
||||||
struct wlr_gles2_pixel_format {
|
struct wlr_gles2_pixel_format {
|
||||||
enum wl_shm_format wl_format;
|
enum wl_shm_format wl_format;
|
||||||
GLint gl_format, gl_type;
|
GLint gl_format, gl_type;
|
||||||
|
@ -33,7 +43,6 @@ struct wlr_gles2_renderer {
|
||||||
struct wlr_renderer wlr_renderer;
|
struct wlr_renderer wlr_renderer;
|
||||||
|
|
||||||
struct wlr_egl *egl;
|
struct wlr_egl *egl;
|
||||||
const char *exts_str;
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
bool read_format_bgra_ext;
|
bool read_format_bgra_ext;
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
|
|
||||||
#include <EGL/egl.h>
|
#include <EGL/egl.h>
|
||||||
#include <EGL/eglext.h>
|
#include <EGL/eglext.h>
|
||||||
|
// TODO: remove eglmesaext.h
|
||||||
|
#include <EGL/eglmesaext.h>
|
||||||
#include <pixman.h>
|
#include <pixman.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
|
@ -34,8 +36,6 @@ struct wlr_egl {
|
||||||
EGLConfig config;
|
EGLConfig config;
|
||||||
EGLContext context;
|
EGLContext context;
|
||||||
|
|
||||||
const char *exts_str;
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
bool bind_wayland_display_wl;
|
bool bind_wayland_display_wl;
|
||||||
bool buffer_age_ext;
|
bool buffer_age_ext;
|
||||||
|
@ -43,10 +43,25 @@ struct wlr_egl {
|
||||||
bool image_dma_buf_export_mesa;
|
bool image_dma_buf_export_mesa;
|
||||||
bool image_dmabuf_import_ext;
|
bool image_dmabuf_import_ext;
|
||||||
bool image_dmabuf_import_modifiers_ext;
|
bool image_dmabuf_import_modifiers_ext;
|
||||||
bool swap_buffers_with_damage_ext;
|
bool swap_buffers_with_damage;
|
||||||
bool swap_buffers_with_damage_khr;
|
|
||||||
} exts;
|
} exts;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT;
|
||||||
|
PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC eglCreatePlatformWindowSurfaceEXT;
|
||||||
|
PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR;
|
||||||
|
PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR;
|
||||||
|
PFNEGLQUERYWAYLANDBUFFERWL eglQueryWaylandBufferWL;
|
||||||
|
PFNEGLBINDWAYLANDDISPLAYWL eglBindWaylandDisplayWL;
|
||||||
|
PFNEGLUNBINDWAYLANDDISPLAYWL eglUnbindWaylandDisplayWL;
|
||||||
|
PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC eglSwapBuffersWithDamage; // KHR or EXT
|
||||||
|
PFNEGLQUERYDMABUFFORMATSEXTPROC eglQueryDmaBufFormatsEXT;
|
||||||
|
PFNEGLQUERYDMABUFMODIFIERSEXTPROC eglQueryDmaBufModifiersEXT;
|
||||||
|
PFNEGLEXPORTDMABUFIMAGEQUERYMESAPROC eglExportDMABUFImageQueryMESA;
|
||||||
|
PFNEGLEXPORTDMABUFIMAGEMESAPROC eglExportDMABUFImageMESA;
|
||||||
|
PFNEGLDEBUGMESSAGECONTROLKHRPROC eglDebugMessageControlKHR;
|
||||||
|
} procs;
|
||||||
|
|
||||||
struct wl_display *wl_display;
|
struct wl_display *wl_display;
|
||||||
|
|
||||||
struct wlr_drm_format_set dmabuf_formats;
|
struct wlr_drm_format_set dmabuf_formats;
|
||||||
|
|
170
render/egl.c
170
render/egl.c
|
@ -5,7 +5,6 @@
|
||||||
#include <wlr/render/egl.h>
|
#include <wlr/render/egl.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include <wlr/util/region.h>
|
#include <wlr/util/region.h>
|
||||||
#include "glapi.h"
|
|
||||||
|
|
||||||
static bool egl_get_config(EGLDisplay disp, EGLint *attribs, EGLConfig *out,
|
static bool egl_get_config(EGLDisplay disp, EGLint *attribs, EGLConfig *out,
|
||||||
EGLint visual_id) {
|
EGLint visual_id) {
|
||||||
|
@ -77,6 +76,15 @@ static bool check_egl_ext(const char *exts, const char *ext) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void load_egl_proc(void *proc_ptr, const char *name) {
|
||||||
|
void *proc = (void *)eglGetProcAddress(name);
|
||||||
|
if (proc == NULL) {
|
||||||
|
wlr_log(WLR_ERROR, "eglGetProcAddress(%s) failed", name);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
*(void **)proc_ptr = proc;
|
||||||
|
}
|
||||||
|
|
||||||
static int get_egl_dmabuf_formats(struct wlr_egl *egl, int **formats);
|
static int get_egl_dmabuf_formats(struct wlr_egl *egl, int **formats);
|
||||||
static int get_egl_dmabuf_modifiers(struct wlr_egl *egl, int format,
|
static int get_egl_dmabuf_modifiers(struct wlr_egl *egl, int format,
|
||||||
uint64_t **modifiers);
|
uint64_t **modifiers);
|
||||||
|
@ -125,11 +133,72 @@ out:
|
||||||
|
|
||||||
bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *remote_display,
|
bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *remote_display,
|
||||||
EGLint *config_attribs, EGLint visual_id) {
|
EGLint *config_attribs, EGLint visual_id) {
|
||||||
if (!load_glapi()) {
|
const char *exts_str = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
|
||||||
|
if (exts_str == NULL) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to query EGL extensions");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eglDebugMessageControlKHR) {
|
if (!check_egl_ext(exts_str, "EGL_EXT_platform_base")) {
|
||||||
|
wlr_log(WLR_ERROR, "EGL_EXT_platform_base not supported");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
load_egl_proc(&egl->procs.eglGetPlatformDisplayEXT,
|
||||||
|
"eglGetPlatformDisplayEXT");
|
||||||
|
load_egl_proc(&egl->procs.eglCreatePlatformWindowSurfaceEXT,
|
||||||
|
"eglCreatePlatformWindowSurfaceEXT");
|
||||||
|
|
||||||
|
if (check_egl_ext(exts_str, "EGL_KHR_image_base")) {
|
||||||
|
egl->exts.image_base_khr = true;
|
||||||
|
load_egl_proc(&egl->procs.eglCreateImageKHR, "eglCreateImageKHR");
|
||||||
|
load_egl_proc(&egl->procs.eglDestroyImageKHR, "eglDestroyImageKHR");
|
||||||
|
}
|
||||||
|
|
||||||
|
egl->exts.buffer_age_ext =
|
||||||
|
check_egl_ext(exts_str, "EGL_EXT_buffer_age");
|
||||||
|
|
||||||
|
if (check_egl_ext(exts_str, "EGL_KHR_swap_buffers_with_damage")) {
|
||||||
|
egl->exts.swap_buffers_with_damage = true;
|
||||||
|
load_egl_proc(&egl->procs.eglSwapBuffersWithDamage,
|
||||||
|
"eglSwapBuffersWithDamageKHR");
|
||||||
|
} else if (check_egl_ext(exts_str, "EGL_EXT_swap_buffers_with_damage")) {
|
||||||
|
egl->exts.swap_buffers_with_damage = true;
|
||||||
|
load_egl_proc(&egl->procs.eglSwapBuffersWithDamage,
|
||||||
|
"eglSwapBuffersWithDamageEXT");
|
||||||
|
}
|
||||||
|
|
||||||
|
egl->exts.image_dmabuf_import_ext =
|
||||||
|
check_egl_ext(exts_str, "EGL_EXT_image_dma_buf_import");
|
||||||
|
if (check_egl_ext(exts_str, "EGL_EXT_image_dma_buf_import_modifiers")) {
|
||||||
|
egl->exts.image_dmabuf_import_modifiers_ext = true;
|
||||||
|
load_egl_proc(&egl->procs.eglQueryDmaBufFormatsEXT,
|
||||||
|
"eglQueryDmaBufFormatsEXT");
|
||||||
|
load_egl_proc(&egl->procs.eglQueryDmaBufModifiersEXT,
|
||||||
|
"eglQueryDmaBufModifiersEXT");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_egl_ext(exts_str, "EGL_MESA_image_dma_buf_export")) {
|
||||||
|
egl->exts.image_dma_buf_export_mesa = true;
|
||||||
|
load_egl_proc(&egl->procs.eglExportDMABUFImageQueryMESA,
|
||||||
|
"eglExportDMABUFImageQueryMESA");
|
||||||
|
load_egl_proc(&egl->procs.eglExportDMABUFImageMESA,
|
||||||
|
"eglExportDMABUFImageMESA");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_egl_ext(exts_str, "EGL_WL_bind_wayland_display")) {
|
||||||
|
egl->exts.bind_wayland_display_wl = true;
|
||||||
|
load_egl_proc(&egl->procs.eglBindWaylandDisplayWL,
|
||||||
|
"eglBindWaylandDisplayWL");
|
||||||
|
load_egl_proc(&egl->procs.eglUnbindWaylandDisplayWL,
|
||||||
|
"eglUnbindWaylandDisplayWL");
|
||||||
|
load_egl_proc(&egl->procs.eglQueryWaylandBufferWL,
|
||||||
|
"eglQueryWaylandBufferWL");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_egl_ext(exts_str, "EGL_KHR_debug")) {
|
||||||
|
load_egl_proc(&egl->procs.eglDebugMessageControlKHR,
|
||||||
|
"eglDebugMessageControlKHR");
|
||||||
|
|
||||||
static const EGLAttrib debug_attribs[] = {
|
static const EGLAttrib debug_attribs[] = {
|
||||||
EGL_DEBUG_MSG_CRITICAL_KHR, EGL_TRUE,
|
EGL_DEBUG_MSG_CRITICAL_KHR, EGL_TRUE,
|
||||||
EGL_DEBUG_MSG_ERROR_KHR, EGL_TRUE,
|
EGL_DEBUG_MSG_ERROR_KHR, EGL_TRUE,
|
||||||
|
@ -137,7 +206,7 @@ bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *remote_display,
|
||||||
EGL_DEBUG_MSG_INFO_KHR, EGL_TRUE,
|
EGL_DEBUG_MSG_INFO_KHR, EGL_TRUE,
|
||||||
EGL_NONE,
|
EGL_NONE,
|
||||||
};
|
};
|
||||||
eglDebugMessageControlKHR(egl_log, debug_attribs);
|
egl->procs.eglDebugMessageControlKHR(egl_log, debug_attribs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eglBindAPI(EGL_OPENGL_ES_API) == EGL_FALSE) {
|
if (eglBindAPI(EGL_OPENGL_ES_API) == EGL_FALSE) {
|
||||||
|
@ -147,9 +216,11 @@ bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *remote_display,
|
||||||
|
|
||||||
if (platform == EGL_PLATFORM_SURFACELESS_MESA) {
|
if (platform == EGL_PLATFORM_SURFACELESS_MESA) {
|
||||||
assert(remote_display == NULL);
|
assert(remote_display == NULL);
|
||||||
egl->display = eglGetPlatformDisplayEXT(platform, EGL_DEFAULT_DISPLAY, NULL);
|
egl->display = egl->procs.eglGetPlatformDisplayEXT(platform,
|
||||||
|
EGL_DEFAULT_DISPLAY, NULL);
|
||||||
} else {
|
} else {
|
||||||
egl->display = eglGetPlatformDisplayEXT(platform, remote_display, NULL);
|
egl->display = egl->procs.eglGetPlatformDisplayEXT(platform,
|
||||||
|
remote_display, NULL);
|
||||||
}
|
}
|
||||||
if (egl->display == EGL_NO_DISPLAY) {
|
if (egl->display == EGL_NO_DISPLAY) {
|
||||||
wlr_log(WLR_ERROR, "Failed to create EGL display");
|
wlr_log(WLR_ERROR, "Failed to create EGL display");
|
||||||
|
@ -169,44 +240,14 @@ bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *remote_display,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
egl->exts_str = eglQueryString(egl->display, EGL_EXTENSIONS);
|
|
||||||
|
|
||||||
wlr_log(WLR_INFO, "Using EGL %d.%d", (int)major, (int)minor);
|
wlr_log(WLR_INFO, "Using EGL %d.%d", (int)major, (int)minor);
|
||||||
wlr_log(WLR_INFO, "Supported EGL extensions: %s", egl->exts_str);
|
wlr_log(WLR_INFO, "Supported EGL extensions: %s", exts_str);
|
||||||
wlr_log(WLR_INFO, "EGL vendor: %s", eglQueryString(egl->display, EGL_VENDOR));
|
wlr_log(WLR_INFO, "EGL vendor: %s", eglQueryString(egl->display, EGL_VENDOR));
|
||||||
|
|
||||||
egl->exts.image_base_khr =
|
|
||||||
check_egl_ext(egl->exts_str, "EGL_KHR_image_base")
|
|
||||||
&& eglCreateImageKHR && eglDestroyImageKHR;
|
|
||||||
|
|
||||||
egl->exts.buffer_age_ext =
|
|
||||||
check_egl_ext(egl->exts_str, "EGL_EXT_buffer_age");
|
|
||||||
egl->exts.swap_buffers_with_damage_ext =
|
|
||||||
(check_egl_ext(egl->exts_str, "EGL_EXT_swap_buffers_with_damage") &&
|
|
||||||
eglSwapBuffersWithDamageEXT);
|
|
||||||
egl->exts.swap_buffers_with_damage_khr =
|
|
||||||
(check_egl_ext(egl->exts_str, "EGL_KHR_swap_buffers_with_damage") &&
|
|
||||||
eglSwapBuffersWithDamageKHR);
|
|
||||||
|
|
||||||
egl->exts.image_dmabuf_import_ext =
|
|
||||||
check_egl_ext(egl->exts_str, "EGL_EXT_image_dma_buf_import");
|
|
||||||
egl->exts.image_dmabuf_import_modifiers_ext =
|
|
||||||
check_egl_ext(egl->exts_str, "EGL_EXT_image_dma_buf_import_modifiers")
|
|
||||||
&& eglQueryDmaBufFormatsEXT && eglQueryDmaBufModifiersEXT;
|
|
||||||
|
|
||||||
egl->exts.image_dma_buf_export_mesa =
|
|
||||||
check_egl_ext(egl->exts_str, "EGL_MESA_image_dma_buf_export") &&
|
|
||||||
eglExportDMABUFImageQueryMESA && eglExportDMABUFImageMESA;
|
|
||||||
|
|
||||||
init_dmabuf_formats(egl);
|
init_dmabuf_formats(egl);
|
||||||
|
|
||||||
egl->exts.bind_wayland_display_wl =
|
|
||||||
check_egl_ext(egl->exts_str, "EGL_WL_bind_wayland_display")
|
|
||||||
&& eglBindWaylandDisplayWL && eglUnbindWaylandDisplayWL
|
|
||||||
&& eglQueryWaylandBufferWL;
|
|
||||||
|
|
||||||
bool ext_context_priority =
|
bool ext_context_priority =
|
||||||
check_egl_ext(egl->exts_str, "EGL_IMG_context_priority");
|
check_egl_ext(exts_str, "EGL_IMG_context_priority");
|
||||||
|
|
||||||
size_t atti = 0;
|
size_t atti = 0;
|
||||||
EGLint attribs[5];
|
EGLint attribs[5];
|
||||||
|
@ -272,7 +313,7 @@ void wlr_egl_finish(struct wlr_egl *egl) {
|
||||||
eglMakeCurrent(egl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
eglMakeCurrent(egl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||||
if (egl->wl_display) {
|
if (egl->wl_display) {
|
||||||
assert(egl->exts.bind_wayland_display_wl);
|
assert(egl->exts.bind_wayland_display_wl);
|
||||||
eglUnbindWaylandDisplayWL(egl->display, egl->wl_display);
|
egl->procs.eglUnbindWaylandDisplayWL(egl->display, egl->wl_display);
|
||||||
}
|
}
|
||||||
|
|
||||||
eglDestroyContext(egl->display, egl->context);
|
eglDestroyContext(egl->display, egl->context);
|
||||||
|
@ -285,7 +326,7 @@ bool wlr_egl_bind_display(struct wlr_egl *egl, struct wl_display *local_display)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eglBindWaylandDisplayWL(egl->display, local_display)) {
|
if (egl->procs.eglBindWaylandDisplayWL(egl->display, local_display)) {
|
||||||
egl->wl_display = local_display;
|
egl->wl_display = local_display;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -300,13 +341,13 @@ bool wlr_egl_destroy_image(struct wlr_egl *egl, EGLImage image) {
|
||||||
if (!image) {
|
if (!image) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return eglDestroyImageKHR(egl->display, image);
|
return egl->procs.eglDestroyImageKHR(egl->display, image);
|
||||||
}
|
}
|
||||||
|
|
||||||
EGLSurface wlr_egl_create_surface(struct wlr_egl *egl, void *window) {
|
EGLSurface wlr_egl_create_surface(struct wlr_egl *egl, void *window) {
|
||||||
assert(eglCreatePlatformWindowSurfaceEXT);
|
assert(egl->procs.eglCreatePlatformWindowSurfaceEXT);
|
||||||
EGLSurface surf = eglCreatePlatformWindowSurfaceEXT(egl->display,
|
EGLSurface surf = egl->procs.eglCreatePlatformWindowSurfaceEXT(
|
||||||
egl->config, window, NULL);
|
egl->display, egl->config, window, NULL);
|
||||||
if (surf == EGL_NO_SURFACE) {
|
if (surf == EGL_NO_SURFACE) {
|
||||||
wlr_log(WLR_ERROR, "Failed to create EGL surface");
|
wlr_log(WLR_ERROR, "Failed to create EGL surface");
|
||||||
return EGL_NO_SURFACE;
|
return EGL_NO_SURFACE;
|
||||||
|
@ -355,8 +396,7 @@ bool wlr_egl_swap_buffers(struct wlr_egl *egl, EGLSurface surface,
|
||||||
}
|
}
|
||||||
|
|
||||||
EGLBoolean ret;
|
EGLBoolean ret;
|
||||||
if (damage != NULL && (egl->exts.swap_buffers_with_damage_ext ||
|
if (damage != NULL && egl->exts.swap_buffers_with_damage) {
|
||||||
egl->exts.swap_buffers_with_damage_khr)) {
|
|
||||||
EGLint width = 0, height = 0;
|
EGLint width = 0, height = 0;
|
||||||
eglQuerySurface(egl->display, surface, EGL_WIDTH, &width);
|
eglQuerySurface(egl->display, surface, EGL_WIDTH, &width);
|
||||||
eglQuerySurface(egl->display, surface, EGL_HEIGHT, &height);
|
eglQuerySurface(egl->display, surface, EGL_HEIGHT, &height);
|
||||||
|
@ -387,13 +427,8 @@ bool wlr_egl_swap_buffers(struct wlr_egl *egl, EGLSurface surface,
|
||||||
memset(egl_damage, 0, sizeof(egl_damage));
|
memset(egl_damage, 0, sizeof(egl_damage));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (egl->exts.swap_buffers_with_damage_ext) {
|
ret = egl->procs.eglSwapBuffersWithDamage(egl->display, surface,
|
||||||
ret = eglSwapBuffersWithDamageEXT(egl->display, surface, egl_damage,
|
egl_damage, nrects);
|
||||||
nrects);
|
|
||||||
} else {
|
|
||||||
ret = eglSwapBuffersWithDamageKHR(egl->display, surface, egl_damage,
|
|
||||||
nrects);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ret = eglSwapBuffers(egl->display, surface);
|
ret = eglSwapBuffers(egl->display, surface);
|
||||||
}
|
}
|
||||||
|
@ -412,16 +447,17 @@ EGLImageKHR wlr_egl_create_image_from_wl_drm(struct wlr_egl *egl,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!eglQueryWaylandBufferWL(egl->display, data, EGL_TEXTURE_FORMAT, fmt)) {
|
if (!egl->procs.eglQueryWaylandBufferWL(egl->display, data,
|
||||||
|
EGL_TEXTURE_FORMAT, fmt)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
eglQueryWaylandBufferWL(egl->display, data, EGL_WIDTH, width);
|
egl->procs.eglQueryWaylandBufferWL(egl->display, data, EGL_WIDTH, width);
|
||||||
eglQueryWaylandBufferWL(egl->display, data, EGL_HEIGHT, height);
|
egl->procs.eglQueryWaylandBufferWL(egl->display, data, EGL_HEIGHT, height);
|
||||||
|
|
||||||
EGLint _inverted_y;
|
EGLint _inverted_y;
|
||||||
if (eglQueryWaylandBufferWL(egl->display, data, EGL_WAYLAND_Y_INVERTED_WL,
|
if (egl->procs.eglQueryWaylandBufferWL(egl->display, data,
|
||||||
&_inverted_y)) {
|
EGL_WAYLAND_Y_INVERTED_WL, &_inverted_y)) {
|
||||||
*inverted_y = !!_inverted_y;
|
*inverted_y = !!_inverted_y;
|
||||||
} else {
|
} else {
|
||||||
*inverted_y = false;
|
*inverted_y = false;
|
||||||
|
@ -431,8 +467,8 @@ EGLImageKHR wlr_egl_create_image_from_wl_drm(struct wlr_egl *egl,
|
||||||
EGL_WAYLAND_PLANE_WL, 0,
|
EGL_WAYLAND_PLANE_WL, 0,
|
||||||
EGL_NONE,
|
EGL_NONE,
|
||||||
};
|
};
|
||||||
return eglCreateImageKHR(egl->display, egl->context, EGL_WAYLAND_BUFFER_WL,
|
return egl->procs.eglCreateImageKHR(egl->display, egl->context,
|
||||||
data, attribs);
|
EGL_WAYLAND_BUFFER_WL, data, attribs);
|
||||||
}
|
}
|
||||||
|
|
||||||
EGLImageKHR wlr_egl_create_image_from_dmabuf(struct wlr_egl *egl,
|
EGLImageKHR wlr_egl_create_image_from_dmabuf(struct wlr_egl *egl,
|
||||||
|
@ -517,7 +553,7 @@ EGLImageKHR wlr_egl_create_image_from_dmabuf(struct wlr_egl *egl,
|
||||||
attribs[atti++] = EGL_NONE;
|
attribs[atti++] = EGL_NONE;
|
||||||
assert(atti < sizeof(attribs)/sizeof(attribs[0]));
|
assert(atti < sizeof(attribs)/sizeof(attribs[0]));
|
||||||
|
|
||||||
return eglCreateImageKHR(egl->display, EGL_NO_CONTEXT,
|
return egl->procs.eglCreateImageKHR(egl->display, EGL_NO_CONTEXT,
|
||||||
EGL_LINUX_DMA_BUF_EXT, NULL, attribs);
|
EGL_LINUX_DMA_BUF_EXT, NULL, attribs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -551,7 +587,7 @@ static int get_egl_dmabuf_formats(struct wlr_egl *egl, int **formats) {
|
||||||
}
|
}
|
||||||
|
|
||||||
EGLint num;
|
EGLint num;
|
||||||
if (!eglQueryDmaBufFormatsEXT(egl->display, 0, NULL, &num)) {
|
if (!egl->procs.eglQueryDmaBufFormatsEXT(egl->display, 0, NULL, &num)) {
|
||||||
wlr_log(WLR_ERROR, "Failed to query number of dmabuf formats");
|
wlr_log(WLR_ERROR, "Failed to query number of dmabuf formats");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -562,7 +598,7 @@ static int get_egl_dmabuf_formats(struct wlr_egl *egl, int **formats) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!eglQueryDmaBufFormatsEXT(egl->display, num, *formats, &num)) {
|
if (!egl->procs.eglQueryDmaBufFormatsEXT(egl->display, num, *formats, &num)) {
|
||||||
wlr_log(WLR_ERROR, "Failed to query dmabuf format");
|
wlr_log(WLR_ERROR, "Failed to query dmabuf format");
|
||||||
free(*formats);
|
free(*formats);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -582,7 +618,7 @@ static int get_egl_dmabuf_modifiers(struct wlr_egl *egl, int format,
|
||||||
}
|
}
|
||||||
|
|
||||||
EGLint num;
|
EGLint num;
|
||||||
if (!eglQueryDmaBufModifiersEXT(egl->display, format, 0,
|
if (!egl->procs.eglQueryDmaBufModifiersEXT(egl->display, format, 0,
|
||||||
NULL, NULL, &num)) {
|
NULL, NULL, &num)) {
|
||||||
wlr_log(WLR_ERROR, "Failed to query dmabuf number of modifiers");
|
wlr_log(WLR_ERROR, "Failed to query dmabuf number of modifiers");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -598,7 +634,7 @@ static int get_egl_dmabuf_modifiers(struct wlr_egl *egl, int format,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!eglQueryDmaBufModifiersEXT(egl->display, format, num,
|
if (!egl->procs.eglQueryDmaBufModifiersEXT(egl->display, format, num,
|
||||||
*modifiers, NULL, &num)) {
|
*modifiers, NULL, &num)) {
|
||||||
wlr_log(WLR_ERROR, "Failed to query dmabuf modifiers");
|
wlr_log(WLR_ERROR, "Failed to query dmabuf modifiers");
|
||||||
free(*modifiers);
|
free(*modifiers);
|
||||||
|
@ -621,7 +657,7 @@ bool wlr_egl_export_image_to_dmabuf(struct wlr_egl *egl, EGLImageKHR image,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only one set of modifiers is returned for all planes
|
// Only one set of modifiers is returned for all planes
|
||||||
if (!eglExportDMABUFImageQueryMESA(egl->display, image,
|
if (!egl->procs.eglExportDMABUFImageQueryMESA(egl->display, image,
|
||||||
(int *)&attribs->format, &attribs->n_planes, &attribs->modifier)) {
|
(int *)&attribs->format, &attribs->n_planes, &attribs->modifier)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -631,7 +667,7 @@ bool wlr_egl_export_image_to_dmabuf(struct wlr_egl *egl, EGLImageKHR image,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!eglExportDMABUFImageMESA(egl->display, image, attribs->fd,
|
if (!egl->procs.eglExportDMABUFImageMESA(egl->display, image, attribs->fd,
|
||||||
(EGLint *)attribs->stride, (EGLint *)attribs->offset)) {
|
(EGLint *)attribs->stride, (EGLint *)attribs->offset)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
eglGetPlatformDisplayEXT
|
|
||||||
eglCreatePlatformWindowSurfaceEXT
|
|
||||||
-eglCreateImageKHR
|
|
||||||
-eglDestroyImageKHR
|
|
||||||
-eglQueryWaylandBufferWL
|
|
||||||
-eglBindWaylandDisplayWL
|
|
||||||
-eglUnbindWaylandDisplayWL
|
|
||||||
-glEGLImageTargetTexture2DOES
|
|
||||||
-eglSwapBuffersWithDamageEXT
|
|
||||||
-eglSwapBuffersWithDamageKHR
|
|
||||||
-eglQueryDmaBufFormatsEXT
|
|
||||||
-eglQueryDmaBufModifiersEXT
|
|
||||||
-eglExportDMABUFImageQueryMESA
|
|
||||||
-eglExportDMABUFImageMESA
|
|
||||||
-eglDebugMessageControlKHR
|
|
||||||
-glDebugMessageCallbackKHR
|
|
||||||
-glDebugMessageControlKHR
|
|
||||||
-glPopDebugGroupKHR
|
|
||||||
-glPushDebugGroupKHR
|
|
|
@ -11,9 +11,10 @@
|
||||||
#include <wlr/render/wlr_renderer.h>
|
#include <wlr/render/wlr_renderer.h>
|
||||||
#include <wlr/types/wlr_matrix.h>
|
#include <wlr/types/wlr_matrix.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include "glapi.h"
|
|
||||||
#include "render/gles2.h"
|
#include "render/gles2.h"
|
||||||
|
|
||||||
|
struct wlr_gles2_procs gles2_procs = {0};
|
||||||
|
|
||||||
static const struct wlr_renderer_impl renderer_impl;
|
static const struct wlr_renderer_impl renderer_impl;
|
||||||
|
|
||||||
static struct wlr_gles2_renderer *gles2_get_renderer(
|
static struct wlr_gles2_renderer *gles2_get_renderer(
|
||||||
|
@ -219,13 +220,13 @@ static bool gles2_resource_is_wl_drm_buffer(struct wlr_renderer *wlr_renderer,
|
||||||
struct wl_resource *resource) {
|
struct wl_resource *resource) {
|
||||||
struct wlr_gles2_renderer *renderer = gles2_get_renderer(wlr_renderer);
|
struct wlr_gles2_renderer *renderer = gles2_get_renderer(wlr_renderer);
|
||||||
|
|
||||||
if (!eglQueryWaylandBufferWL) {
|
if (!renderer->egl->exts.bind_wayland_display_wl) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
EGLint fmt;
|
EGLint fmt;
|
||||||
return eglQueryWaylandBufferWL(renderer->egl->display, resource,
|
return renderer->egl->procs.eglQueryWaylandBufferWL(renderer->egl->display,
|
||||||
EGL_TEXTURE_FORMAT, &fmt);
|
resource, EGL_TEXTURE_FORMAT, &fmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gles2_wl_drm_buffer_get_size(struct wlr_renderer *wlr_renderer,
|
static void gles2_wl_drm_buffer_get_size(struct wlr_renderer *wlr_renderer,
|
||||||
|
@ -233,12 +234,14 @@ static void gles2_wl_drm_buffer_get_size(struct wlr_renderer *wlr_renderer,
|
||||||
struct wlr_gles2_renderer *renderer =
|
struct wlr_gles2_renderer *renderer =
|
||||||
gles2_get_renderer(wlr_renderer);
|
gles2_get_renderer(wlr_renderer);
|
||||||
|
|
||||||
if (!eglQueryWaylandBufferWL) {
|
if (!renderer->egl->exts.bind_wayland_display_wl) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
eglQueryWaylandBufferWL(renderer->egl->display, buffer, EGL_WIDTH, width);
|
renderer->egl->procs.eglQueryWaylandBufferWL(renderer->egl->display,
|
||||||
eglQueryWaylandBufferWL(renderer->egl->display, buffer, EGL_HEIGHT, height);
|
buffer, EGL_WIDTH, width);
|
||||||
|
renderer->egl->procs.eglQueryWaylandBufferWL(renderer->egl->display,
|
||||||
|
buffer, EGL_HEIGHT, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct wlr_drm_format_set *gles2_get_dmabuf_formats(
|
static const struct wlr_drm_format_set *gles2_get_dmabuf_formats(
|
||||||
|
@ -376,7 +379,7 @@ static void gles2_destroy(struct wlr_renderer *wlr_renderer) {
|
||||||
|
|
||||||
if (renderer->exts.debug_khr) {
|
if (renderer->exts.debug_khr) {
|
||||||
glDisable(GL_DEBUG_OUTPUT_KHR);
|
glDisable(GL_DEBUG_OUTPUT_KHR);
|
||||||
glDebugMessageCallbackKHR(NULL, NULL);
|
gles2_procs.glDebugMessageCallbackKHR(NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(renderer);
|
free(renderer);
|
||||||
|
@ -405,19 +408,19 @@ static const struct wlr_renderer_impl renderer_impl = {
|
||||||
};
|
};
|
||||||
|
|
||||||
void push_gles2_marker(const char *file, const char *func) {
|
void push_gles2_marker(const char *file, const char *func) {
|
||||||
if (!glPushDebugGroupKHR) {
|
if (!gles2_procs.glPushDebugGroupKHR) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int len = snprintf(NULL, 0, "%s:%s", file, func) + 1;
|
int len = snprintf(NULL, 0, "%s:%s", file, func) + 1;
|
||||||
char str[len];
|
char str[len];
|
||||||
snprintf(str, len, "%s:%s", file, func);
|
snprintf(str, len, "%s:%s", file, func);
|
||||||
glPushDebugGroupKHR(GL_DEBUG_SOURCE_APPLICATION_KHR, 1, -1, str);
|
gles2_procs.glPushDebugGroupKHR(GL_DEBUG_SOURCE_APPLICATION_KHR, 1, -1, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pop_gles2_marker(void) {
|
void pop_gles2_marker(void) {
|
||||||
if (glPopDebugGroupKHR) {
|
if (gles2_procs.glPopDebugGroupKHR) {
|
||||||
glPopDebugGroupKHR();
|
gles2_procs.glPopDebugGroupKHR();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,6 +519,15 @@ static bool check_gl_ext(const char *exts, const char *ext) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void load_gl_proc(void *proc_ptr, const char *name) {
|
||||||
|
void *proc = (void *)eglGetProcAddress(name);
|
||||||
|
if (proc == NULL) {
|
||||||
|
wlr_log(WLR_ERROR, "eglGetProcAddress(%s) failed", name);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
*(void **)proc_ptr = proc;
|
||||||
|
}
|
||||||
|
|
||||||
extern const GLchar quad_vertex_src[];
|
extern const GLchar quad_vertex_src[];
|
||||||
extern const GLchar quad_fragment_src[];
|
extern const GLchar quad_fragment_src[];
|
||||||
extern const GLchar ellipse_fragment_src[];
|
extern const GLchar ellipse_fragment_src[];
|
||||||
|
@ -525,7 +537,9 @@ extern const GLchar tex_fragment_src_rgbx[];
|
||||||
extern const GLchar tex_fragment_src_external[];
|
extern const GLchar tex_fragment_src_external[];
|
||||||
|
|
||||||
struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl) {
|
struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl) {
|
||||||
if (!load_glapi()) {
|
const char *exts_str = (const char *)glGetString(GL_EXTENSIONS);
|
||||||
|
if (exts_str == NULL) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to get GL_EXTENSIONS");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -542,37 +556,44 @@ struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer->exts_str = (const char *)glGetString(GL_EXTENSIONS);
|
|
||||||
wlr_log(WLR_INFO, "Using %s", glGetString(GL_VERSION));
|
wlr_log(WLR_INFO, "Using %s", glGetString(GL_VERSION));
|
||||||
wlr_log(WLR_INFO, "GL vendor: %s", glGetString(GL_VENDOR));
|
wlr_log(WLR_INFO, "GL vendor: %s", glGetString(GL_VENDOR));
|
||||||
wlr_log(WLR_INFO, "GL renderer: %s", glGetString(GL_RENDERER));
|
wlr_log(WLR_INFO, "GL renderer: %s", glGetString(GL_RENDERER));
|
||||||
wlr_log(WLR_INFO, "Supported GLES2 extensions: %s", renderer->exts_str);
|
wlr_log(WLR_INFO, "Supported GLES2 extensions: %s", exts_str);
|
||||||
|
|
||||||
if (!check_gl_ext(renderer->exts_str, "GL_EXT_texture_format_BGRA8888")) {
|
if (!check_gl_ext(exts_str, "GL_EXT_texture_format_BGRA8888")) {
|
||||||
wlr_log(WLR_ERROR, "BGRA8888 format not supported by GLES2");
|
wlr_log(WLR_ERROR, "BGRA8888 format not supported by GLES2");
|
||||||
free(renderer);
|
free(renderer);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer->exts.read_format_bgra_ext =
|
renderer->exts.read_format_bgra_ext =
|
||||||
check_gl_ext(renderer->exts_str, "GL_EXT_read_format_bgra");
|
check_gl_ext(exts_str, "GL_EXT_read_format_bgra");
|
||||||
renderer->exts.debug_khr =
|
|
||||||
check_gl_ext(renderer->exts_str, "GL_KHR_debug") &&
|
if (check_gl_ext(exts_str, "GL_KHR_debug")) {
|
||||||
glDebugMessageCallbackKHR && glDebugMessageControlKHR;
|
renderer->exts.debug_khr = true;
|
||||||
renderer->exts.egl_image_external_oes =
|
load_gl_proc(&gles2_procs.glDebugMessageCallbackKHR,
|
||||||
check_gl_ext(renderer->exts_str, "GL_OES_EGL_image_external") &&
|
"glDebugMessageCallbackKHR");
|
||||||
glEGLImageTargetTexture2DOES;
|
load_gl_proc(&gles2_procs.glDebugMessageControlKHR,
|
||||||
|
"glDebugMessageControlKHR");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_gl_ext(exts_str, "GL_OES_EGL_image_external")) {
|
||||||
|
renderer->exts.egl_image_external_oes = true;
|
||||||
|
load_gl_proc(&gles2_procs.glEGLImageTargetTexture2DOES,
|
||||||
|
"glEGLImageTargetTexture2DOES");
|
||||||
|
}
|
||||||
|
|
||||||
if (renderer->exts.debug_khr) {
|
if (renderer->exts.debug_khr) {
|
||||||
glEnable(GL_DEBUG_OUTPUT_KHR);
|
glEnable(GL_DEBUG_OUTPUT_KHR);
|
||||||
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR);
|
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR);
|
||||||
glDebugMessageCallbackKHR(gles2_log, NULL);
|
gles2_procs.glDebugMessageCallbackKHR(gles2_log, NULL);
|
||||||
|
|
||||||
// Silence unwanted message types
|
// Silence unwanted message types
|
||||||
glDebugMessageControlKHR(GL_DONT_CARE, GL_DEBUG_TYPE_POP_GROUP_KHR,
|
gles2_procs.glDebugMessageControlKHR(GL_DONT_CARE,
|
||||||
GL_DONT_CARE, 0, NULL, GL_FALSE);
|
GL_DEBUG_TYPE_POP_GROUP_KHR, GL_DONT_CARE, 0, NULL, GL_FALSE);
|
||||||
glDebugMessageControlKHR(GL_DONT_CARE, GL_DEBUG_TYPE_PUSH_GROUP_KHR,
|
gles2_procs.glDebugMessageControlKHR(GL_DONT_CARE,
|
||||||
GL_DONT_CARE, 0, NULL, GL_FALSE);
|
GL_DEBUG_TYPE_PUSH_GROUP_KHR, GL_DONT_CARE, 0, NULL, GL_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
PUSH_GLES2_DEBUG;
|
PUSH_GLES2_DEBUG;
|
||||||
|
@ -641,7 +662,7 @@ error:
|
||||||
|
|
||||||
if (renderer->exts.debug_khr) {
|
if (renderer->exts.debug_khr) {
|
||||||
glDisable(GL_DEBUG_OUTPUT_KHR);
|
glDisable(GL_DEBUG_OUTPUT_KHR);
|
||||||
glDebugMessageCallbackKHR(NULL, NULL);
|
gles2_procs.glDebugMessageCallbackKHR(NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(renderer);
|
free(renderer);
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
#include <wlr/render/wlr_texture.h>
|
#include <wlr/render/wlr_texture.h>
|
||||||
#include <wlr/types/wlr_matrix.h>
|
#include <wlr/types/wlr_matrix.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include "glapi.h"
|
|
||||||
#include "render/gles2.h"
|
#include "render/gles2.h"
|
||||||
#include "util/signal.h"
|
#include "util/signal.h"
|
||||||
|
|
||||||
|
@ -91,12 +90,12 @@ static bool gles2_texture_to_dmabuf(struct wlr_texture *wlr_texture,
|
||||||
if (!texture->image) {
|
if (!texture->image) {
|
||||||
assert(texture->target == GL_TEXTURE_2D);
|
assert(texture->target == GL_TEXTURE_2D);
|
||||||
|
|
||||||
if (!eglCreateImageKHR) {
|
if (!texture->egl->exts.image_base_khr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
texture->image = eglCreateImageKHR(texture->egl->display,
|
texture->image = texture->egl->procs.eglCreateImageKHR(
|
||||||
texture->egl->context, EGL_GL_TEXTURE_2D_KHR,
|
texture->egl->display, texture->egl->context, EGL_GL_TEXTURE_2D_KHR,
|
||||||
(EGLClientBuffer)(uintptr_t)texture->tex, NULL);
|
(EGLClientBuffer)(uintptr_t)texture->tex, NULL);
|
||||||
if (texture->image == EGL_NO_IMAGE_KHR) {
|
if (texture->image == EGL_NO_IMAGE_KHR) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -188,7 +187,7 @@ struct wlr_texture *wlr_gles2_texture_from_wl_drm(struct wlr_egl *egl,
|
||||||
wlr_egl_make_current(egl, EGL_NO_SURFACE, NULL);
|
wlr_egl_make_current(egl, EGL_NO_SURFACE, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!glEGLImageTargetTexture2DOES) {
|
if (!gles2_procs.glEGLImageTargetTexture2DOES) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,7 +229,8 @@ struct wlr_texture *wlr_gles2_texture_from_wl_drm(struct wlr_egl *egl,
|
||||||
|
|
||||||
glGenTextures(1, &texture->tex);
|
glGenTextures(1, &texture->tex);
|
||||||
glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture->tex);
|
glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture->tex);
|
||||||
glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, texture->image);
|
gles2_procs.glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES,
|
||||||
|
texture->image);
|
||||||
|
|
||||||
POP_GLES2_DEBUG;
|
POP_GLES2_DEBUG;
|
||||||
return &texture->wlr_texture;
|
return &texture->wlr_texture;
|
||||||
|
@ -242,7 +242,7 @@ struct wlr_texture *wlr_gles2_texture_from_dmabuf(struct wlr_egl *egl,
|
||||||
wlr_egl_make_current(egl, EGL_NO_SURFACE, NULL);
|
wlr_egl_make_current(egl, EGL_NO_SURFACE, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!glEGLImageTargetTexture2DOES) {
|
if (!gles2_procs.glEGLImageTargetTexture2DOES) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,7 +290,8 @@ struct wlr_texture *wlr_gles2_texture_from_dmabuf(struct wlr_egl *egl,
|
||||||
|
|
||||||
glGenTextures(1, &texture->tex);
|
glGenTextures(1, &texture->tex);
|
||||||
glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture->tex);
|
glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture->tex);
|
||||||
glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, texture->image);
|
gles2_procs.glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES,
|
||||||
|
texture->image);
|
||||||
|
|
||||||
POP_GLES2_DEBUG;
|
POP_GLES2_DEBUG;
|
||||||
return &texture->wlr_texture;
|
return &texture->wlr_texture;
|
||||||
|
|
|
@ -1,12 +1,3 @@
|
||||||
glgen = find_program('../glgen.sh')
|
|
||||||
|
|
||||||
glapi = custom_target(
|
|
||||||
'glapi',
|
|
||||||
input: 'glapi.txt',
|
|
||||||
output: ['@BASENAME@.c', '@BASENAME@.h'],
|
|
||||||
command: [glgen, '@INPUT@', '@OUTDIR@'],
|
|
||||||
)
|
|
||||||
|
|
||||||
lib_wlr_render = static_library(
|
lib_wlr_render = static_library(
|
||||||
'wlr_render',
|
'wlr_render',
|
||||||
files(
|
files(
|
||||||
|
@ -20,7 +11,6 @@ lib_wlr_render = static_library(
|
||||||
'wlr_renderer.c',
|
'wlr_renderer.c',
|
||||||
'wlr_texture.c',
|
'wlr_texture.c',
|
||||||
),
|
),
|
||||||
glapi,
|
|
||||||
include_directories: wlr_inc,
|
include_directories: wlr_inc,
|
||||||
dependencies: [
|
dependencies: [
|
||||||
egl,
|
egl,
|
||||||
|
@ -33,5 +23,4 @@ lib_wlr_render = static_library(
|
||||||
|
|
||||||
wlr_render = declare_dependency(
|
wlr_render = declare_dependency(
|
||||||
link_with: lib_wlr_render,
|
link_with: lib_wlr_render,
|
||||||
sources: glapi[1],
|
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue