From 396e04cf6977f5094bc27ccd13ab48ca09b65805 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Wed, 14 Mar 2018 18:12:21 +1100 Subject: [PATCH] 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). --- gst-libs/gst/gl/gstglformat.c | 59 ++++++++++++++++++++++++++++++++++++++++ gst-libs/gst/gl/gstglformat.h | 4 +++ gst-libs/gst/gl/gstglmemory.c | 55 ++++++++++--------------------------- gst-libs/gst/gl/gstglmemorypbo.c | 30 +++++--------------- 4 files changed, 85 insertions(+), 63 deletions(-) diff --git a/gst-libs/gst/gl/gstglformat.c b/gst-libs/gst/gl/gstglformat.c index 8427be4..b12e882 100644 --- a/gst-libs/gst/gl/gstglformat.c +++ b/gst-libs/gst/gl/gstglformat.c @@ -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: @@ -278,6 +284,59 @@ gst_gl_sized_gl_format_from_gl_format_type (GstGLContext * context, } /** + * 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 * diff --git a/gst-libs/gst/gl/gstglformat.h b/gst-libs/gst/gl/gstglformat.h index a799d40..a9f499f 100644 --- a/gst-libs/gst/gl/gstglformat.h +++ b/gst-libs/gst/gl/gstglformat.h @@ -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); diff --git a/gst-libs/gst/gl/gstglmemory.c b/gst-libs/gst/gl/gstglmemory.c index 30d5f5e..bf9782d 100644 --- a/gst-libs/gst/gl/gstglmemory.c +++ b/gst-libs/gst/gl/gstglmemory.c @@ -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, diff --git a/gst-libs/gst/gl/gstglmemorypbo.c b/gst-libs/gst/gl/gstglmemorypbo.c index 4a62a38..ced13df 100644 --- a/gst-libs/gst/gl/gstglmemorypbo.c +++ b/gst-libs/gst/gl/gstglmemorypbo.c @@ -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) { -- 2.7.4