libobs-opengl: Add create_texture_from_pixmap for EGL

create_texture_from_pixmap is only implemented for X11/EGL where it will
bind the provided X11 pixmap to a texture with glEGLImageTargetTexture2DOES
This commit is contained in:
Kurt Kartaltepe 2022-05-13 19:38:12 -07:00 committed by Georges Basile Stavracas Neto
parent f4a820a4ea
commit d78b27961c
10 changed files with 119 additions and 15 deletions

View File

@ -177,6 +177,31 @@ create_dmabuf_egl_image(EGLDisplay egl_display, unsigned int width,
EGL_LINUX_DMA_BUF_EXT, 0, attribs);
}
struct gs_texture *gl_egl_create_texture_from_eglimage(
EGLDisplay egl_display, uint32_t width, uint32_t height,
enum gs_color_format color_format, EGLint target, EGLImage image)
{
UNUSED_PARAMETER(target);
struct gs_texture *texture = NULL;
texture = gs_texture_create(width, height, color_format, 1, NULL,
GS_DYNAMIC);
const GLuint gltex = *(GLuint *)gs_texture_get_obj(texture);
gl_bind_texture(GL_TEXTURE_2D, gltex);
gl_tex_param_i(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
gl_tex_param_i(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
if (!gl_success("glEGLImageTargetTexture2DOES")) {
gs_texture_destroy(texture);
texture = NULL;
}
gl_bind_texture(GL_TEXTURE_2D, 0);
return texture;
}
struct gs_texture *
gl_egl_create_dmabuf_image(EGLDisplay egl_display, unsigned int width,
unsigned int height, uint32_t drm_format,
@ -199,24 +224,42 @@ gl_egl_create_dmabuf_image(EGLDisplay egl_display, unsigned int width,
return NULL;
}
if ((texture = gs_texture_create(width, height, color_format, 1, NULL,
GS_DYNAMIC)) == NULL) {
texture = gl_egl_create_texture_from_eglimage(egl_display, width,
height, color_format,
GL_TEXTURE_2D, egl_image);
if (texture)
eglDestroyImage(egl_display, egl_image);
return texture;
}
struct gs_texture *
gl_egl_create_texture_from_pixmap(EGLDisplay egl_display, uint32_t width,
uint32_t height,
enum gs_color_format color_format,
EGLint target, EGLClientBuffer pixmap)
{
if (!init_egl_image_target_texture_2d_ext())
return NULL;
const EGLAttrib pixmap_attrs[] = {
EGL_IMAGE_PRESERVED_KHR,
EGL_TRUE,
EGL_NONE,
};
EGLImage image = eglCreateImage(egl_display, EGL_NO_CONTEXT,
EGL_NATIVE_PIXMAP_KHR, pixmap,
pixmap_attrs);
if (image == EGL_NO_IMAGE) {
blog(LOG_ERROR, "Cannot create EGLImage: %s",
gl_egl_error_to_string(eglGetError()));
return NULL;
}
const GLuint gltex = *(GLuint *)gs_texture_get_obj(texture);
gl_bind_texture(GL_TEXTURE_2D, gltex);
gl_tex_param_i(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
gl_tex_param_i(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, egl_image);
if (!gl_success("glEGLImageTargetTexture2DOES")) {
gs_texture_destroy(texture);
texture = NULL;
}
gl_bind_texture(GL_TEXTURE_2D, 0);
eglDestroyImage(egl_display, egl_image);
struct gs_texture *texture = gl_egl_create_texture_from_eglimage(
egl_display, width, height, color_format, target, image);
eglDestroyImage(egl_display, image);
return texture;
}

View File

@ -21,3 +21,9 @@ bool gl_egl_query_dmabuf_modifiers_for_format(EGLDisplay egl_display,
uint32_t drm_format,
uint64_t **modifiers,
size_t *n_modifiers);
struct gs_texture *
gl_egl_create_texture_from_pixmap(EGLDisplay egl_display, uint32_t width,
uint32_t height,
enum gs_color_format color_format,
EGLint target, EGLClientBuffer pixmap);

View File

@ -157,3 +157,11 @@ extern bool device_query_dmabuf_modifiers_for_format(gs_device_t *device,
return gl_vtable->device_query_dmabuf_modifiers_for_format(
device, drm_format, modifiers, n_modifiers);
}
struct gs_texture *device_texture_create_from_pixmap(
gs_device_t *device, uint32_t width, uint32_t height,
enum gs_color_format color_format, uint32_t target, void *pixmap)
{
return gl_vtable->device_texture_create_from_pixmap(
device, width, height, color_format, target, pixmap);
}

View File

@ -68,4 +68,9 @@ struct gl_winsys_vtable {
uint32_t drm_format,
uint64_t **modifiers,
size_t *n_modifiers);
struct gs_texture *(*device_texture_create_from_pixmap)(
gs_device_t *device, uint32_t width, uint32_t height,
enum gs_color_format color_format, uint32_t target,
void *pixmap);
};

View File

@ -383,6 +383,13 @@ static bool gl_wayland_egl_device_query_dmabuf_modifiers_for_format(
plat->display, drm_format, modifiers, n_modifiers);
}
static struct gs_texture *gl_wayland_egl_device_texture_create_from_pixmap(
gs_device_t *device, uint32_t width, uint32_t height,
enum gs_color_format color_format, uint32_t target, void *pixmap)
{
return NULL;
}
static const struct gl_winsys_vtable egl_wayland_winsys_vtable = {
.windowinfo_create = gl_wayland_egl_windowinfo_create,
.windowinfo_destroy = gl_wayland_egl_windowinfo_destroy,
@ -404,6 +411,8 @@ static const struct gl_winsys_vtable egl_wayland_winsys_vtable = {
gl_wayland_egl_device_query_dmabuf_capabilities,
.device_query_dmabuf_modifiers_for_format =
gl_wayland_egl_device_query_dmabuf_modifiers_for_format,
.device_texture_create_from_pixmap =
gl_wayland_egl_device_texture_create_from_pixmap,
};
const struct gl_winsys_vtable *gl_wayland_egl_get_winsys_vtable(void)

View File

@ -650,6 +650,17 @@ static struct gs_texture *gl_x11_egl_device_texture_create_from_dmabuf(
fds, strides, offsets, modifiers);
}
static struct gs_texture *gl_x11_egl_device_texture_create_from_pixmap(
gs_device_t *device, uint32_t width, uint32_t height,
enum gs_color_format color_format, uint32_t target, void *pixmap)
{
struct gl_platform *plat = device->plat;
return gl_egl_create_texture_from_pixmap(plat->edisplay, width, height,
color_format, target,
(EGLClientBuffer)pixmap);
}
static bool gl_x11_egl_device_query_dmabuf_capabilities(
gs_device_t *device, enum gs_dmabuf_flags *dmabuf_flags,
uint32_t **drm_formats, size_t *n_formats)
@ -691,6 +702,8 @@ static const struct gl_winsys_vtable egl_x11_winsys_vtable = {
gl_x11_egl_device_query_dmabuf_capabilities,
.device_query_dmabuf_modifiers_for_format =
gl_x11_egl_device_query_dmabuf_modifiers_for_format,
.device_texture_create_from_pixmap =
gl_x11_egl_device_texture_create_from_pixmap,
};
const struct gl_winsys_vtable *gl_x11_egl_get_winsys_vtable(void)

View File

@ -237,6 +237,7 @@ bool load_graphics_imports(struct gs_exports *exports, void *module,
GRAPHICS_IMPORT(device_texture_create_from_dmabuf);
GRAPHICS_IMPORT(device_query_dmabuf_capabilities);
GRAPHICS_IMPORT(device_query_dmabuf_modifiers_for_format);
GRAPHICS_IMPORT(device_texture_create_from_pixmap);
#endif
return success;

View File

@ -360,6 +360,10 @@ struct gs_exports {
uint32_t drm_format,
uint64_t **modifiers,
size_t *n_modifiers);
struct gs_texture *(*device_texture_create_from_pixmap)(
gs_device_t *device, uint32_t width, uint32_t height,
enum gs_color_format color_format, uint32_t target,
void *pixmap);
#endif
};

View File

@ -1421,6 +1421,16 @@ bool gs_query_dmabuf_modifiers_for_format(uint32_t drm_format,
graphics->device, drm_format, modifiers, n_modifiers);
}
gs_texture_t *gs_texture_create_from_pixmap(uint32_t width, uint32_t height,
enum gs_color_format color_format,
uint32_t target, void *pixmap)
{
graphics_t *graphics = thread_graphics;
return graphics->exports.device_texture_create_from_pixmap(
graphics->device, width, height, color_format, target, pixmap);
}
#endif
gs_texture_t *gs_cubetexture_create(uint32_t size,

View File

@ -987,6 +987,11 @@ EXPORT bool gs_query_dmabuf_modifiers_for_format(uint32_t drm_format,
uint64_t **modifiers,
size_t *n_modifiers);
EXPORT gs_texture_t *
gs_texture_create_from_pixmap(uint32_t width, uint32_t height,
enum gs_color_format color_format,
uint32_t target, void *pixmap);
#endif
/* inline functions used by modules */