static void _upload_memory (GstGLMemory * gl_mem, GstMapInfo * info, gsize maxsize) { GstGLContext *context = gl_mem->mem.context; const GstGLFuncs *gl; GLenum gl_format, gl_type, gl_target; gpointer data; gsize plane_start; if ((gl_mem->transfer_state & GST_GL_MEMORY_TRANSFER_NEED_UPLOAD) == 0) return; gl = context->gl_vtable; gl_type = GL_UNSIGNED_BYTE; if (gl_mem->tex_type == GST_VIDEO_GL_TEXTURE_TYPE_RGB16) gl_type = GL_UNSIGNED_SHORT_5_6_5; gl_format = gst_gl_format_from_gl_texture_type (gl_mem->tex_type); gl_target = gl_mem->tex_target; if (USING_OPENGL (context) || USING_GLES3 (context) || USING_OPENGL3 (context)) { gl->PixelStorei (GL_UNPACK_ROW_LENGTH, gl_mem->unpack_length); } else if (USING_GLES2 (context)) { gl->PixelStorei (GL_UNPACK_ALIGNMENT, gl_mem->unpack_length); } GST_LOG ("upload for texture id:%u, with pbo %u %ux%u", gl_mem->tex_id, gl_mem->mem.id, gl_mem->tex_width, GL_MEM_HEIGHT (gl_mem)); /* find the start of the plane data including padding */ plane_start = _find_plane_frame_start (gl_mem); if (gl_mem->mem.id && CONTEXT_SUPPORTS_PBO_UPLOAD (context)) { gl->BindBuffer (GL_PIXEL_UNPACK_BUFFER, gl_mem->mem.id); data = (void *) plane_start; } else { data = (gpointer) ((gintptr) plane_start + (gintptr) gl_mem->mem.data); } gl->BindTexture (gl_target, gl_mem->tex_id); gl->TexSubImage2D (gl_target, 0, 0, 0, gl_mem->tex_width, GL_MEM_HEIGHT (gl_mem), gl_format, gl_type, data); if (gl_mem->mem.id && CONTEXT_SUPPORTS_PBO_UPLOAD (context)) gl->BindBuffer (GL_PIXEL_UNPACK_BUFFER, 0); /* Reset to default values */ if (USING_OPENGL (context) || USING_GLES3 (context)) { gl->PixelStorei (GL_UNPACK_ROW_LENGTH, 0); } else if (USING_GLES2 (context)) { gl->PixelStorei (GL_UNPACK_ALIGNMENT, 4); } gl->BindTexture (gl_target, 0); gl_mem->transfer_state &= ~GST_GL_MEMORY_TRANSFER_NEED_UPLOAD; }
static gpointer _gl_mem_map_gpu_access (GstGLMemoryPBO * gl_mem, GstMapInfo * info, gsize size) { gpointer data = &gl_mem->mem.tex_id; if ((info->flags & GST_MAP_READ) == GST_MAP_READ) { if (gl_mem->pbo && CONTEXT_SUPPORTS_PBO_UPLOAD (gl_mem->mem.mem.context)) { GstMapInfo pbo_info; /* data -> pbo */ if (!gst_memory_map (GST_MEMORY_CAST (gl_mem->pbo), &pbo_info, GST_MAP_READ | GST_MAP_GL)) { GST_CAT_ERROR (GST_CAT_GL_MEMORY, "Failed to map pbo"); return NULL; } /* pbo -> texture */ _upload_pbo_memory (gl_mem, info, gl_mem->pbo, &pbo_info); gst_memory_unmap (GST_MEMORY_CAST (gl_mem->pbo), &pbo_info); } else { GstGLMemoryAllocatorClass *alloc_class; alloc_class = GST_GL_MEMORY_ALLOCATOR_CLASS (parent_class); data = alloc_class->map ((GstGLBaseMemory *) gl_mem, info, size); } } return data; }
/** * gst_gl_memory_pbo_download_transfer: * @gl_mem: a #GstGLMemoryPBO * * Transfer the texture data from the PBO into the texture if necessary. * * Since: 1.8 */ void gst_gl_memory_pbo_upload_transfer (GstGLMemoryPBO * gl_mem) { g_return_if_fail (gst_is_gl_memory ((GstMemory *) gl_mem)); if (gl_mem->pbo && CONTEXT_SUPPORTS_PBO_UPLOAD (gl_mem->mem.mem.context)) gst_gl_context_thread_add (gl_mem->mem.mem.context, (GstGLContextThreadFunc) _upload_transfer, gl_mem); }
static void _upload_pbo_memory (GstGLMemoryPBO * gl_mem, GstMapInfo * info, GstGLBuffer * pbo, GstMapInfo * pbo_info) { GstGLContext *context = gl_mem->mem.mem.context; const GstGLFuncs *gl; guint gl_format, gl_type, gl_target; guint pbo_id; gsize plane_start; if (!GST_MEMORY_FLAG_IS_SET (gl_mem, GST_GL_BASE_MEMORY_TRANSFER_NEED_UPLOAD)) return; g_return_if_fail (CONTEXT_SUPPORTS_PBO_UPLOAD (context)); gl = context->gl_vtable; pbo_id = *(guint *) pbo_info->data; gl_type = GL_UNSIGNED_BYTE; if (gl_mem->mem.tex_type == GST_VIDEO_GL_TEXTURE_TYPE_RGB16) gl_type = GL_UNSIGNED_SHORT_5_6_5; gl_format = gst_gl_format_from_gl_texture_type (gl_mem->mem.tex_type); gl_target = gst_gl_texture_target_to_gl (gl_mem->mem.tex_target); if (USING_OPENGL (context) || USING_GLES3 (context) || USING_OPENGL3 (context)) { gl->PixelStorei (GL_UNPACK_ROW_LENGTH, gl_mem->mem.unpack_length); } else if (USING_GLES2 (context)) { gl->PixelStorei (GL_UNPACK_ALIGNMENT, gl_mem->mem.unpack_length); } GST_CAT_LOG (GST_CAT_GL_MEMORY, "upload for texture id:%u, with pbo %u %ux%u", gl_mem->mem.tex_id, pbo_id, gl_mem->mem.tex_width, GL_MEM_HEIGHT (gl_mem)); /* find the start of the plane data including padding */ plane_start = gst_gl_get_plane_start (&gl_mem->mem.info, &gl_mem->mem.valign, gl_mem->mem.plane) + GST_MEMORY_CAST (gl_mem)->offset; gl->BindBuffer (GL_PIXEL_UNPACK_BUFFER, pbo_id); gl->BindTexture (gl_target, gl_mem->mem.tex_id); gl->TexSubImage2D (gl_target, 0, 0, 0, gl_mem->mem.tex_width, GL_MEM_HEIGHT (gl_mem), gl_format, gl_type, (void *) plane_start); gl->BindBuffer (GL_PIXEL_UNPACK_BUFFER, 0); gl->BindTexture (gl_target, 0); /* Reset to default values */ if (USING_OPENGL (context) || USING_GLES3 (context)) { gl->PixelStorei (GL_UNPACK_ROW_LENGTH, 0); } else if (USING_GLES2 (context)) { gl->PixelStorei (GL_UNPACK_ALIGNMENT, 4); } }
static gboolean _gl_mem_create (GstGLMemoryPBO * gl_mem, GError ** error) { GstGLContext *context = gl_mem->mem.mem.context; GstGLBaseMemoryAllocatorClass *alloc_class; alloc_class = GST_GL_BASE_MEMORY_ALLOCATOR_CLASS (parent_class); if (!alloc_class->create ((GstGLBaseMemory *) gl_mem, error)) return FALSE; if (CONTEXT_SUPPORTS_PBO_DOWNLOAD (context) || CONTEXT_SUPPORTS_PBO_UPLOAD (context)) { GstAllocationParams alloc_params = { 0, GST_MEMORY_CAST (gl_mem)->align, 0, 0 }; GstGLBaseMemoryAllocator *buf_allocator; GstGLBufferAllocationParams *params; buf_allocator = GST_GL_BASE_MEMORY_ALLOCATOR (gst_allocator_find (GST_GL_BUFFER_ALLOCATOR_NAME)); params = gst_gl_buffer_allocation_params_new (context, GST_MEMORY_CAST (gl_mem)->size, &alloc_params, GL_PIXEL_UNPACK_BUFFER, GL_STREAM_DRAW); /* FIXME: lazy init this for resource constrained platforms * Will need to fix pbo detection based on the existence of the mem.id then */ gl_mem->pbo = (GstGLBuffer *) gst_gl_base_memory_alloc (buf_allocator, (GstGLAllocationParams *) params); gst_gl_allocation_params_free ((GstGLAllocationParams *) params); gst_object_unref (buf_allocator); GST_CAT_LOG (GST_CAT_GL_MEMORY, "generated pbo %u", gl_mem->pbo->id); } return TRUE; }
static void _upload_pbo_memory (GstGLMemoryPBO * gl_mem, GstMapInfo * info, GstGLBuffer * pbo, GstMapInfo * pbo_info) { GstGLContext *context = gl_mem->mem.mem.context; const GstGLFuncs *gl; guint pbo_id; if (!GST_MEMORY_FLAG_IS_SET (gl_mem, GST_GL_BASE_MEMORY_TRANSFER_NEED_UPLOAD)) return; g_return_if_fail (CONTEXT_SUPPORTS_PBO_UPLOAD (context)); gl = context->gl_vtable; pbo_id = *(guint *) pbo_info->data; GST_CAT_LOG (GST_CAT_GL_MEMORY, "upload for texture id:%u, with pbo %u %ux%u", gl_mem->mem.tex_id, pbo_id, gl_mem->mem.tex_width, GL_MEM_HEIGHT (gl_mem)); gl->BindBuffer (GL_PIXEL_UNPACK_BUFFER, pbo_id); gst_gl_memory_texsubimage (GST_GL_MEMORY_CAST (gl_mem), NULL); gl->BindBuffer (GL_PIXEL_UNPACK_BUFFER, 0); }