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:
parent
f4a820a4ea
commit
d78b27961c
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user