mirror of
https://github.com/brl/mutter.git
synced 2024-11-22 16:10:41 -05:00
cogl: Add support for creating custom EGL based textures
Add API to enable the caller to have a custom method for allocating an external texture. This will enable the possibility for mutter to generate a texture from for example an EGLStream without having to add support for that in Cogl. https://bugzilla.gnome.org/show_bug.cgi?id=773629
This commit is contained in:
parent
7c31fb2450
commit
1f0ce80fb4
@ -262,6 +262,7 @@ typedef enum _CoglFeatureID
|
|||||||
COGL_FEATURE_ID_PER_VERTEX_POINT_SIZE,
|
COGL_FEATURE_ID_PER_VERTEX_POINT_SIZE,
|
||||||
COGL_FEATURE_ID_TEXTURE_RG,
|
COGL_FEATURE_ID_TEXTURE_RG,
|
||||||
COGL_FEATURE_ID_BUFFER_AGE,
|
COGL_FEATURE_ID_BUFFER_AGE,
|
||||||
|
COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL,
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
_COGL_N_FEATURE_IDS /*< skip >*/
|
_COGL_N_FEATURE_IDS /*< skip >*/
|
||||||
|
@ -152,6 +152,7 @@ typedef long GLsizeiptr;
|
|||||||
#define GL_POLYGON_OFFSET_FILL 0x8037
|
#define GL_POLYGON_OFFSET_FILL 0x8037
|
||||||
#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
|
#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
|
||||||
#define GL_SAMPLE_COVERAGE 0x80A0
|
#define GL_SAMPLE_COVERAGE 0x80A0
|
||||||
|
#define GL_TEXTURE_EXTERNAL_OES 0x8D65
|
||||||
|
|
||||||
/* ErrorCode */
|
/* ErrorCode */
|
||||||
#define GL_NO_ERROR 0
|
#define GL_NO_ERROR 0
|
||||||
|
@ -111,6 +111,14 @@ _cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx,
|
|||||||
lengths[count++] = sizeof (texture_3d_extension) - 1;
|
lengths[count++] = sizeof (texture_3d_extension) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL))
|
||||||
|
{
|
||||||
|
static const char texture_3d_extension[] =
|
||||||
|
"#extension GL_OES_EGL_image_external : require\n";
|
||||||
|
strings[count] = texture_3d_extension;
|
||||||
|
lengths[count++] = sizeof (texture_3d_extension) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (shader_gl_type == GL_VERTEX_SHADER)
|
if (shader_gl_type == GL_VERTEX_SHADER)
|
||||||
{
|
{
|
||||||
strings[count] = vertex_boilerplate;
|
strings[count] = vertex_boilerplate;
|
||||||
|
@ -55,11 +55,17 @@ struct _CoglTexture2D
|
|||||||
GLenum gl_internal_format;
|
GLenum gl_internal_format;
|
||||||
/* The texture object number */
|
/* The texture object number */
|
||||||
GLuint gl_texture;
|
GLuint gl_texture;
|
||||||
|
GLenum gl_target;
|
||||||
GLenum gl_legacy_texobj_min_filter;
|
GLenum gl_legacy_texobj_min_filter;
|
||||||
GLenum gl_legacy_texobj_mag_filter;
|
GLenum gl_legacy_texobj_mag_filter;
|
||||||
GLint gl_legacy_texobj_wrap_mode_s;
|
GLint gl_legacy_texobj_wrap_mode_s;
|
||||||
GLint gl_legacy_texobj_wrap_mode_t;
|
GLint gl_legacy_texobj_wrap_mode_t;
|
||||||
CoglTexturePixel first_pixel;
|
CoglTexturePixel first_pixel;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
void *user_data;
|
||||||
|
GDestroyNotify destroy;
|
||||||
|
} egl_image_external;
|
||||||
};
|
};
|
||||||
|
|
||||||
CoglTexture2D *
|
CoglTexture2D *
|
||||||
|
@ -110,6 +110,8 @@ _cogl_texture_2d_create_base (CoglContext *ctx,
|
|||||||
tex_2d->mipmaps_dirty = TRUE;
|
tex_2d->mipmaps_dirty = TRUE;
|
||||||
tex_2d->auto_mipmap = TRUE;
|
tex_2d->auto_mipmap = TRUE;
|
||||||
|
|
||||||
|
tex_2d->gl_target = GL_TEXTURE_2D;
|
||||||
|
|
||||||
tex_2d->is_foreign = FALSE;
|
tex_2d->is_foreign = FALSE;
|
||||||
|
|
||||||
ctx->driver_vtable->texture_2d_init (tex_2d);
|
ctx->driver_vtable->texture_2d_init (tex_2d);
|
||||||
@ -557,7 +559,7 @@ _cogl_texture_2d_get_gl_texture (CoglTexture *tex,
|
|||||||
GLuint handle;
|
GLuint handle;
|
||||||
|
|
||||||
if (out_gl_target)
|
if (out_gl_target)
|
||||||
*out_gl_target = GL_TEXTURE_2D;
|
*out_gl_target = tex_2d->gl_target;
|
||||||
|
|
||||||
handle = ctx->driver_vtable->texture_2d_get_gl_handle (tex_2d);
|
handle = ctx->driver_vtable->texture_2d_get_gl_handle (tex_2d);
|
||||||
|
|
||||||
|
@ -242,6 +242,27 @@ cogl_egl_texture_2d_new_from_image (CoglContext *ctx,
|
|||||||
CoglPixelFormat format,
|
CoglPixelFormat format,
|
||||||
EGLImageKHR image,
|
EGLImageKHR image,
|
||||||
CoglError **error);
|
CoglError **error);
|
||||||
|
|
||||||
|
typedef gboolean (*CoglTexture2DEGLImageExternalAlloc) (CoglTexture2D *tex_2d,
|
||||||
|
gpointer user_data,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
CoglTexture2D *
|
||||||
|
cogl_texture_2d_new_from_egl_image_external (CoglContext *ctx,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
CoglTexture2DEGLImageExternalAlloc alloc,
|
||||||
|
gpointer user_data,
|
||||||
|
GDestroyNotify destroy,
|
||||||
|
CoglError **error);
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_texture_2d_egl_image_external_bind (CoglTexture2D *tex_2d);
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_texture_2d_egl_image_external_alloc_finish (CoglTexture2D *tex_2d,
|
||||||
|
void *user_data,
|
||||||
|
GDestroyNotify destroy);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
COGL_END_DECLS
|
COGL_END_DECLS
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include "cogl-spans.h"
|
#include "cogl-spans.h"
|
||||||
#include "cogl-meta-texture.h"
|
#include "cogl-meta-texture.h"
|
||||||
#include "cogl-framebuffer.h"
|
#include "cogl-framebuffer.h"
|
||||||
|
#include "cogl-texture-2d.h"
|
||||||
|
|
||||||
#ifdef COGL_HAS_EGL_SUPPORT
|
#ifdef COGL_HAS_EGL_SUPPORT
|
||||||
#include "cogl-egl-defines.h"
|
#include "cogl-egl-defines.h"
|
||||||
@ -154,7 +155,8 @@ typedef enum _CoglTextureSoureType {
|
|||||||
COGL_TEXTURE_SOURCE_TYPE_SIZED = 1,
|
COGL_TEXTURE_SOURCE_TYPE_SIZED = 1,
|
||||||
COGL_TEXTURE_SOURCE_TYPE_BITMAP,
|
COGL_TEXTURE_SOURCE_TYPE_BITMAP,
|
||||||
COGL_TEXTURE_SOURCE_TYPE_EGL_IMAGE,
|
COGL_TEXTURE_SOURCE_TYPE_EGL_IMAGE,
|
||||||
COGL_TEXTURE_SOURCE_TYPE_GL_FOREIGN
|
COGL_TEXTURE_SOURCE_TYPE_GL_FOREIGN,
|
||||||
|
COGL_TEXTURE_SOURCE_TYPE_EGL_IMAGE_EXTERNAL
|
||||||
} CoglTextureSourceType;
|
} CoglTextureSourceType;
|
||||||
|
|
||||||
typedef struct _CoglTextureLoader
|
typedef struct _CoglTextureLoader
|
||||||
@ -179,6 +181,14 @@ typedef struct _CoglTextureLoader
|
|||||||
int height;
|
int height;
|
||||||
CoglPixelFormat format;
|
CoglPixelFormat format;
|
||||||
} egl_image;
|
} egl_image;
|
||||||
|
#endif
|
||||||
|
#if defined (COGL_HAS_EGL_SUPPORT)
|
||||||
|
struct {
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
CoglTexture2DEGLImageExternalAlloc alloc;
|
||||||
|
CoglPixelFormat format;
|
||||||
|
} egl_image_external;
|
||||||
#endif
|
#endif
|
||||||
struct {
|
struct {
|
||||||
int width;
|
int width;
|
||||||
|
@ -160,6 +160,7 @@ _cogl_texture_free_loader (CoglTexture *texture)
|
|||||||
case COGL_TEXTURE_SOURCE_TYPE_SIZED:
|
case COGL_TEXTURE_SOURCE_TYPE_SIZED:
|
||||||
case COGL_TEXTURE_SOURCE_TYPE_EGL_IMAGE:
|
case COGL_TEXTURE_SOURCE_TYPE_EGL_IMAGE:
|
||||||
case COGL_TEXTURE_SOURCE_TYPE_GL_FOREIGN:
|
case COGL_TEXTURE_SOURCE_TYPE_GL_FOREIGN:
|
||||||
|
case COGL_TEXTURE_SOURCE_TYPE_EGL_IMAGE_EXTERNAL:
|
||||||
break;
|
break;
|
||||||
case COGL_TEXTURE_SOURCE_TYPE_BITMAP:
|
case COGL_TEXTURE_SOURCE_TYPE_BITMAP:
|
||||||
cogl_object_unref (loader->src.bitmap.bitmap);
|
cogl_object_unref (loader->src.bitmap.bitmap);
|
||||||
|
@ -46,11 +46,21 @@
|
|||||||
#include "cogl-error-private.h"
|
#include "cogl-error-private.h"
|
||||||
#include "cogl-util-gl-private.h"
|
#include "cogl-util-gl-private.h"
|
||||||
|
|
||||||
|
#if defined (COGL_HAS_EGL_SUPPORT)
|
||||||
|
#include <GLES2/gl2.h>
|
||||||
|
#include <GLES2/gl2ext.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
_cogl_texture_2d_gl_free (CoglTexture2D *tex_2d)
|
_cogl_texture_2d_gl_free (CoglTexture2D *tex_2d)
|
||||||
{
|
{
|
||||||
if (!tex_2d->is_foreign && tex_2d->gl_texture)
|
if (!tex_2d->is_foreign && tex_2d->gl_texture)
|
||||||
_cogl_delete_gl_texture (tex_2d->gl_texture);
|
_cogl_delete_gl_texture (tex_2d->gl_texture);
|
||||||
|
|
||||||
|
#if defined (COGL_HAS_EGL_SUPPORT)
|
||||||
|
g_clear_pointer (&tex_2d->egl_image_external.user_data,
|
||||||
|
tex_2d->egl_image_external.destroy);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
CoglBool
|
CoglBool
|
||||||
@ -101,6 +111,9 @@ _cogl_texture_2d_gl_init (CoglTexture2D *tex_2d)
|
|||||||
/* Wrap mode not yet set */
|
/* Wrap mode not yet set */
|
||||||
tex_2d->gl_legacy_texobj_wrap_mode_s = GL_FALSE;
|
tex_2d->gl_legacy_texobj_wrap_mode_s = GL_FALSE;
|
||||||
tex_2d->gl_legacy_texobj_wrap_mode_t = GL_FALSE;
|
tex_2d->gl_legacy_texobj_wrap_mode_t = GL_FALSE;
|
||||||
|
|
||||||
|
tex_2d->egl_image_external.user_data = NULL;
|
||||||
|
tex_2d->egl_image_external.destroy = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CoglBool
|
static CoglBool
|
||||||
@ -439,6 +452,96 @@ allocate_from_gl_foreign (CoglTexture2D *tex_2d,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined (COGL_HAS_EGL_SUPPORT)
|
||||||
|
static CoglBool
|
||||||
|
allocate_custom_egl_image_external (CoglTexture2D *tex_2d,
|
||||||
|
CoglTextureLoader *loader,
|
||||||
|
CoglError **error)
|
||||||
|
{
|
||||||
|
CoglTexture *tex = COGL_TEXTURE (tex_2d);
|
||||||
|
CoglContext *ctx = tex->context;
|
||||||
|
CoglPixelFormat internal_format = loader->src.egl_image_external.format;
|
||||||
|
|
||||||
|
_cogl_gl_util_clear_gl_errors (ctx);
|
||||||
|
|
||||||
|
GE (ctx, glActiveTexture (GL_TEXTURE0));
|
||||||
|
GE (ctx, glGenTextures (1, &tex_2d->gl_texture));
|
||||||
|
|
||||||
|
GE (ctx, glBindTexture (GL_TEXTURE_EXTERNAL_OES,
|
||||||
|
tex_2d->gl_texture));
|
||||||
|
|
||||||
|
if (_cogl_gl_util_get_error (ctx) != GL_NO_ERROR)
|
||||||
|
{
|
||||||
|
_cogl_set_error (error,
|
||||||
|
COGL_TEXTURE_ERROR,
|
||||||
|
COGL_TEXTURE_ERROR_BAD_PARAMETER,
|
||||||
|
"Could not create a CoglTexture2D from a given "
|
||||||
|
"EGLImage");
|
||||||
|
GE( ctx, glDeleteTextures (1, &tex_2d->gl_texture) );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GE (ctx, glTexParameteri(GL_TEXTURE_EXTERNAL_OES,
|
||||||
|
GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
|
||||||
|
GE (ctx, glTexParameteri(GL_TEXTURE_EXTERNAL_OES,
|
||||||
|
GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
|
||||||
|
|
||||||
|
if (!loader->src.egl_image_external.alloc (tex_2d,
|
||||||
|
tex_2d->egl_image_external.user_data,
|
||||||
|
error))
|
||||||
|
{
|
||||||
|
GE (ctx, glBindTexture (GL_TEXTURE_EXTERNAL_OES, 0));
|
||||||
|
GE (ctx, glDeleteTextures (1, &tex_2d->gl_texture));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GE (ctx, glBindTexture (GL_TEXTURE_EXTERNAL_OES, 0));
|
||||||
|
|
||||||
|
tex_2d->internal_format = internal_format;
|
||||||
|
tex_2d->gl_target = GL_TEXTURE_EXTERNAL_OES;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
CoglTexture2D *
|
||||||
|
cogl_texture_2d_new_from_egl_image_external (CoglContext *ctx,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
CoglTexture2DEGLImageExternalAlloc alloc,
|
||||||
|
gpointer user_data,
|
||||||
|
GDestroyNotify destroy,
|
||||||
|
CoglError **error)
|
||||||
|
{
|
||||||
|
CoglTextureLoader *loader;
|
||||||
|
CoglTexture2D *tex_2d;
|
||||||
|
CoglPixelFormat internal_format = COGL_PIXEL_FORMAT_ANY;
|
||||||
|
|
||||||
|
_COGL_RETURN_VAL_IF_FAIL (_cogl_context_get_winsys (ctx)->constraints &
|
||||||
|
COGL_RENDERER_CONSTRAINT_USES_EGL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
_COGL_RETURN_VAL_IF_FAIL (cogl_has_feature (ctx,
|
||||||
|
COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL),
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
loader = _cogl_texture_create_loader ();
|
||||||
|
loader->src_type = COGL_TEXTURE_SOURCE_TYPE_EGL_IMAGE_EXTERNAL;
|
||||||
|
loader->src.egl_image_external.width = width;
|
||||||
|
loader->src.egl_image_external.height = height;
|
||||||
|
loader->src.egl_image_external.alloc = alloc;
|
||||||
|
loader->src.egl_image_external.format = internal_format;
|
||||||
|
|
||||||
|
tex_2d = _cogl_texture_2d_create_base (ctx, width, height,
|
||||||
|
internal_format, loader);
|
||||||
|
|
||||||
|
|
||||||
|
tex_2d->egl_image_external.user_data = user_data;
|
||||||
|
tex_2d->egl_image_external.destroy = destroy;
|
||||||
|
|
||||||
|
return tex_2d;
|
||||||
|
}
|
||||||
|
#endif /* defined (COGL_HAS_EGL_SUPPORT) */
|
||||||
|
|
||||||
CoglBool
|
CoglBool
|
||||||
_cogl_texture_2d_gl_allocate (CoglTexture *tex,
|
_cogl_texture_2d_gl_allocate (CoglTexture *tex,
|
||||||
CoglError **error)
|
CoglError **error)
|
||||||
@ -462,6 +565,8 @@ _cogl_texture_2d_gl_allocate (CoglTexture *tex,
|
|||||||
#endif
|
#endif
|
||||||
case COGL_TEXTURE_SOURCE_TYPE_GL_FOREIGN:
|
case COGL_TEXTURE_SOURCE_TYPE_GL_FOREIGN:
|
||||||
return allocate_from_gl_foreign (tex_2d, loader, error);
|
return allocate_from_gl_foreign (tex_2d, loader, error);
|
||||||
|
case COGL_TEXTURE_SOURCE_TYPE_EGL_IMAGE_EXTERNAL:
|
||||||
|
return allocate_custom_egl_image_external (tex_2d, loader, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_return_val_if_reached (FALSE);
|
g_return_val_if_reached (FALSE);
|
||||||
|
Loading…
Reference in New Issue
Block a user