gl/memory: store the internal format as the texture format

Instead of having special cases at each GL texture creation, upload,
readback or copy for all non-8-bits-per-components.
Simply store the more specific format and retrieve the generic
component/type tuple from that.

Introduce a helper function for retrieving the generic GL format (RGBA,
RGB, RG, R, L, A) and type (BYTE, SHORT, SHORT_5_6_5) from a sized
GL format enum (RGBA8, RGB565, RG8, etc).
This commit is contained in:
Matthew Waters 2018-03-14 18:12:21 +11:00
parent 131f9b4e2b
commit 396e04cf69
4 changed files with 85 additions and 63 deletions

View file

@ -56,21 +56,26 @@ _gl_format_n_components (guint format)
switch (format) {
case GST_VIDEO_GL_TEXTURE_TYPE_RGBA:
case GST_GL_RGBA:
case GST_GL_RGBA8:
return 4;
case GST_VIDEO_GL_TEXTURE_TYPE_RGB:
case GST_VIDEO_GL_TEXTURE_TYPE_RGB16:
case GST_GL_RGB:
case GST_GL_RGB8:
case GST_GL_RGB565:
return 3;
case GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE_ALPHA:
case GST_VIDEO_GL_TEXTURE_TYPE_RG:
case GST_GL_LUMINANCE_ALPHA:
case GST_GL_RG:
case GST_GL_RG8:
return 2;
case GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE:
case GST_VIDEO_GL_TEXTURE_TYPE_R:
case GST_GL_LUMINANCE:
case GST_GL_ALPHA:
case GST_GL_RED:
case GST_GL_R8:
return 1;
default:
return 0;
@ -159,6 +164,7 @@ gst_gl_format_from_video_info (GstGLContext * context, GstVideoInfo * vinfo,
case GST_VIDEO_FORMAT_RGB16:
case GST_VIDEO_FORMAT_BGR16:
return GST_GL_RGB565;
break;
case GST_VIDEO_FORMAT_GRAY16_BE:
case GST_VIDEO_FORMAT_GRAY16_LE:
case GST_VIDEO_FORMAT_YUY2:
@ -277,6 +283,59 @@ gst_gl_sized_gl_format_from_gl_format_type (GstGLContext * context,
return 0;
}
/**
* gst_gl_format_type_from_sized_gl_format:
* @format: the sized internal #GstGLFormat
* @unsized_format: (out): location for the resulting unsized #GstGLFormat
* @gl_type: (out): location for the resulting GL type
*
* Get the unsized format and type from @format for usage in glReadPixels,
* glTex{Sub}Image*, glTexImage* and similar functions.
*/
void
gst_gl_format_type_from_sized_gl_format (GstGLFormat format,
GstGLFormat * unsized_format, guint * gl_type)
{
g_return_if_fail (unsized_format != NULL);
g_return_if_fail (gl_type != NULL);
switch (format) {
case GST_GL_RGBA8:
*unsized_format = GST_GL_RGBA;
*gl_type = GL_UNSIGNED_BYTE;
break;
case GST_GL_RGB8:
*unsized_format = GST_GL_RGB;
*gl_type = GL_UNSIGNED_BYTE;
break;
case GST_GL_RGB565:
*unsized_format = GST_GL_RGB;
*gl_type = GL_UNSIGNED_SHORT_5_6_5;
break;
case GST_GL_RG8:
*unsized_format = GST_GL_RG;
*gl_type = GL_UNSIGNED_BYTE;
break;
case GST_GL_R8:
*unsized_format = GST_GL_RED;
*gl_type = GL_UNSIGNED_BYTE;
break;
case GST_GL_RGBA:
case GST_GL_RGB:
case GST_GL_RG:
case GST_GL_RED:
case GST_GL_LUMINANCE:
case GST_GL_LUMINANCE_ALPHA:
case GST_GL_ALPHA:
*unsized_format = format;
*gl_type = GL_UNSIGNED_BYTE;
break;
default:
g_assert_not_reached ();
return;
}
}
/**
* gst_gl_texture_target_to_string:
* @target: a #GstGLTextureTarget

View file

@ -131,6 +131,10 @@ GST_GL_API
guint gst_gl_sized_gl_format_from_gl_format_type (GstGLContext * context,
guint format,
guint type);
GST_GL_API
void gst_gl_format_type_from_sized_gl_format (GstGLFormat format,
GstGLFormat * unsized_format,
guint * gl_type);
GST_GL_API
GstGLTextureTarget gst_gl_texture_target_from_string (const gchar * str);

View file

@ -123,18 +123,16 @@ static inline void
_calculate_unpack_length (GstGLMemory * gl_mem, GstGLContext * context)
{
guint n_gl_bytes;
guint tex_type;
guint tex_format, tex_type;
gl_mem->tex_scaling[0] = 1.0f;
gl_mem->tex_scaling[1] = 1.0f;
gl_mem->unpack_length = 1;
gl_mem->tex_width = GL_MEM_WIDTH (gl_mem);
tex_type = GL_UNSIGNED_BYTE;
if (gl_mem->tex_format == GST_GL_RGB565)
tex_type = GL_UNSIGNED_SHORT_5_6_5;
n_gl_bytes = gst_gl_format_type_n_bytes (gl_mem->tex_format, tex_type);
gst_gl_format_type_from_sized_gl_format (gl_mem->tex_format, &tex_format,
&tex_type);
n_gl_bytes = gst_gl_format_type_n_bytes (tex_format, tex_type);
if (n_gl_bytes == 0) {
GST_ERROR ("Unsupported texture type %d", gl_mem->tex_format);
return;
@ -243,16 +241,9 @@ _gl_tex_create (GstGLMemory * gl_mem, GError ** error)
GLenum tex_format;
GLenum tex_type;
tex_format = gl_mem->tex_format;
tex_type = GL_UNSIGNED_BYTE;
if (gl_mem->tex_format == GST_GL_RGB565) {
tex_format = GST_GL_RGB;
tex_type = GL_UNSIGNED_SHORT_5_6_5;
}
internal_format =
gst_gl_sized_gl_format_from_gl_format_type (context, tex_format,
tex_type);
internal_format = gl_mem->tex_format;
gst_gl_format_type_from_sized_gl_format (internal_format, &tex_format,
&tex_type);
if (!gl_mem->texture_wrapped) {
gl_mem->tex_id =
@ -363,10 +354,7 @@ gst_gl_memory_read_pixels (GstGLMemory * gl_mem, gpointer read_pointer)
guint format, type;
guint fbo;
format = gl_mem->tex_format;
type = GL_UNSIGNED_BYTE;
if (gl_mem->tex_format == GST_GL_RGB565)
type = GL_UNSIGNED_SHORT_5_6_5;
gst_gl_format_type_from_sized_gl_format (gl_mem->tex_format, &format, &type);
/* FIXME: avoid creating a framebuffer every download/copy */
gl->GenFramebuffers (1, &fbo);
@ -441,10 +429,8 @@ _gl_tex_download_get_tex_image (GstGLMemory * gl_mem, GstMapInfo * info,
GST_CAT_TRACE (GST_CAT_GL_MEMORY, "attempting download of texture %u "
"using glGetTexImage", gl_mem->tex_id);
format = gl_mem->tex_format;
type = GL_UNSIGNED_BYTE;
if (gl_mem->tex_format == GST_GL_RGB565)
type = GL_UNSIGNED_SHORT_5_6_5;
gst_gl_format_type_from_sized_gl_format (gl_mem->tex_format, &format,
&type);
target = gst_gl_texture_target_to_gl (gl_mem->tex_target);
gl->BindTexture (target, gl_mem->tex_id);
@ -524,12 +510,8 @@ gst_gl_memory_texsubimage (GstGLMemory * gl_mem, gpointer read_pointer)
gl = context->gl_vtable;
gl_type = GL_UNSIGNED_BYTE;
gl_format = gl_mem->tex_format;
if (gl_mem->tex_format == GST_GL_RGB565) {
gl_format = GST_GL_RGB;
gl_type = GL_UNSIGNED_SHORT_5_6_5;
}
gst_gl_format_type_from_sized_gl_format (gl_mem->tex_format, &gl_format,
&gl_type);
gl_target = gst_gl_texture_target_to_gl (gl_mem->tex_target);
@ -784,16 +766,9 @@ _gl_tex_copy_thread (GstGLContext * context, gpointer data)
guint internal_format, out_gl_format, out_gl_type, out_tex_target;
out_tex_target = gst_gl_texture_target_to_gl (copy_params->tex_target);
out_gl_format = copy_params->src->tex_format;
out_gl_type = GL_UNSIGNED_BYTE;
if (copy_params->out_format == GST_GL_RGB565) {
out_gl_format = GST_GL_RGB;
out_gl_type = GL_UNSIGNED_SHORT_5_6_5;
}
internal_format =
gst_gl_sized_gl_format_from_gl_format_type (context, out_gl_format,
out_gl_type);
internal_format = copy_params->src->tex_format;
gst_gl_format_type_from_sized_gl_format (internal_format, &out_gl_format,
&out_gl_type);
copy_params->tex_id =
_new_texture (context, out_tex_target,

View file

@ -420,16 +420,11 @@ _gl_mem_copy_thread (GstGLContext * context, gpointer data)
out_stride = copy_params->out_stride;
gl = context->gl_vtable;
out_gl_format = copy_params->out_format;
out_gl_type = GL_UNSIGNED_BYTE;
if (copy_params->out_format == GST_GL_RGB565) {
out_gl_format = GST_GL_RGB;
out_gl_type = GL_UNSIGNED_SHORT_5_6_5;
}
in_gl_format = src->mem.tex_format;
in_gl_type = GL_UNSIGNED_BYTE;
if (src->mem.tex_format == GST_GL_RGB565)
in_gl_type = GL_UNSIGNED_SHORT_5_6_5;
gst_gl_format_type_from_sized_gl_format (copy_params->out_format,
&out_gl_format, &out_gl_type);
gst_gl_format_type_from_sized_gl_format (src->mem.tex_format, &in_gl_format,
&in_gl_type);
if (!gl->GenFramebuffers) {
GST_CAT_ERROR (GST_CAT_GL_MEMORY,
@ -450,21 +445,10 @@ _gl_mem_copy_thread (GstGLContext * context, gpointer data)
}
if (!tex_id) {
guint internal_format;
guint out_gl_type;
out_gl_type = GL_UNSIGNED_BYTE;
if (copy_params->out_format == GST_GL_RGB565)
out_gl_type = GL_UNSIGNED_SHORT_5_6_5;
internal_format =
gst_gl_sized_gl_format_from_gl_format_type (context, out_gl_format,
out_gl_type);
tex_id =
_new_texture (context, out_tex_target,
internal_format, out_gl_format, out_gl_type, copy_params->out_width,
copy_params->out_height);
copy_params->out_format, out_gl_format, out_gl_type,
copy_params->out_width, copy_params->out_height);
}
if (!tex_id) {