This message will disappear after all relevant tasks have been resolved.
Semantic MediaWiki
There are 1 incomplete or pending task to finish installation of Semantic MediaWiki. An administrator or user with sufficient rights can complete it. This should be done before adding new data to avoid inconsistencies.
This article explain how to use the EGL texture 0-copy in a 3D application.
1. What is texture 0-copy?[edit source]
The texture 0-copy consists in using specific OpenGLES interfaces to avoid to copy the texture from the EGL application environment to the GPU execution environment.
The OpenGLES interfaces to be used (instead of the standard glTexImage2D interface) are:
- eglCreateImageKHR (create a reference on the image texture)
- eglDestroyImageKHR (destroy the reference of the image texture)
- glEGLImageTargetTexture2DOES (upload the texture)
The texture 0-copy procedure assumes that the texture buffer could be shared (e.g.: using DMABUF) and that the application will lock the texture until the OpenGLES draw procedure is completed.
The texture 0-copy is very useful when the texture to apply on a 3D object is refreshed with a high rate (e.g: video texture).
2. Example of implementation[edit source]
In this example we consider that the GPU natively support NV12 pixel format.
EGLint eglImgAttrs[30]; EGLImageKHR image; GLenum target; if (meta) { switch (meta->format) { case GST_VIDEO_FORMAT_NV12: format = DRM_FORMAT_NV12; n_planes = 2; target = GL_TEXTURE_EXTERNAL_OES; break; case GST_VIDEO_FORMAT_RGB16: format = DRM_FORMAT_RGB565; case GST_VIDEO_FORMAT_BGRx: format = DRM_FORMAT_XRGB8888; n_planes = 1; target = GL_TEXTURE_2D; break; default: fprintf(stdout, "%s: buffer format (0x%x) not supported for texture\n", __func__, meta->format); return; } } else { fprintf(stdout, "%s: no meta data found\n", __func__); return; } eglImgAttrs[atti++] = EGL_WIDTH; eglImgAttrs[atti++] = meta->width; eglImgAttrs[atti++] = EGL_HEIGHT; eglImgAttrs[atti++] = meta->height; eglImgAttrs[atti++] = EGL_LINUX_DRM_FOURCC_EXT; eglImgAttrs[atti++] = format; if (n_planes > 0) { eglImgAttrs[atti++] = EGL_DMA_BUF_PLANE0_FD_EXT; eglImgAttrs[atti++] = fd_mem; eglImgAttrs[atti++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT; eglImgAttrs[atti++] = meta->offset[0]; eglImgAttrs[atti++] = EGL_DMA_BUF_PLANE0_PITCH_EXT; eglImgAttrs[atti++] = meta->stride[0]; } if (n_planes > 1) { eglImgAttrs[atti++] = EGL_DMA_BUF_PLANE1_FD_EXT; eglImgAttrs[atti++] = fd_mem; eglImgAttrs[atti++] = EGL_DMA_BUF_PLANE1_OFFSET_EXT; eglImgAttrs[atti++] = meta->offset[1]; eglImgAttrs[atti++] = EGL_DMA_BUF_PLANE1_PITCH_EXT; eglImgAttrs[atti++] = meta->stride[1]; } if (n_planes > 2) { eglImgAttrs[atti++] = EGL_DMA_BUF_PLANE2_FD_EXT; eglImgAttrs[atti++] = fd_mem; eglImgAttrs[atti++] = EGL_DMA_BUF_PLANE2_OFFSET_EXT; eglImgAttrs[atti++] = meta->offset[2]; eglImgAttrs[atti++] = EGL_DMA_BUF_PLANE2_PITCH_EXT; eglImgAttrs[atti++] = meta->stride[2]; } eglImgAttrs[atti++] = EGL_NONE; image = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, eglImgAttrs); /* Updating the related input texture. */ glActiveTexture(GL_TEXTURE0); glBindTexture(target, input_textures_handle[stream_index]); glEGLImageTargetTexture2DOES(target, image); eglDestroyImageKHR(display, image);