Difference between revisions of "EGL texture 0-copy"

[unchecked revision] [quality revision]
m
m (Replaced content with "<noinclude> {{ArticleMainWriter|VincentA}} {{ArticleApprovedVersion | Jean-ChristopheT | Nobody | No previous approved version | Automatic approval (article under construc...")
(Tag: Replaced)
Under construction.png Coming soon


Template:ArticleProposedVersion




This article explain how to use the EGL texture 0-copy in a 3D application.

1 What is texture 0-copy?[edit]

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]

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);

<noinclude>

{{ArticleMainWriter|VincentA}}
{{ArticleApprovedVersion | Jean-ChristopheT | Nobody | No previous approved version | Automatic approval (article under construction) | 19Feb’19}}
[[Category:GPU]]</noinclude>

{{UnderConstruction}}ArticleProposedVersion|VincentA|PhilippeC(Failed, 19Jan'18)|No previous approved version|Nobody | 10August'17}}

[[Category:GPU]]</noinclude>


{{ReviewsComments|PCO (W803) : the article name is not so nice}}
{{ReviewsComments|PCO (W803) : avoid "br"}}
{{ReviewsComments|PCO (W803) : bad titles, please use 2x{{=}}}}

This article explain how to use the EGL texture 0-copy in a 3D application.
=What is texture 0-copy?=
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.<br>

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)

{{ReviewsComments|PCO (W803) : It could be nice to add web links to these extension documentation }}
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.<br>


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).<br>


=Example of implementation=

{{ReviewsComments|PCO (W803) : please use the code template instead}}
In this example we consider that the GPU natively support NV12 pixel format.<pre>

      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);</pre>
Line 1: Line 1:
 
<noinclude>
 
<noinclude>
 
{{ArticleMainWriter|VincentA}}
 
{{ArticleMainWriter|VincentA}}
{{ArticleProposedVersion|VincentA|PhilippeC(Failed, 19Jan'18)|No previous approved version|Nobody | 10August'17}}
+
{{ArticleApprovedVersion | Jean-ChristopheT | Nobody | No previous approved version | Automatic approval (article under construction) | 19Feb’19}}
 
 
 
[[Category:GPU]]
 
[[Category:GPU]]
 
</noinclude>
 
</noinclude>
 
+
{{UnderConstruction}}
{{ReviewsComments|PCO (W803) : the article name is not so nice}}
 
{{ReviewsComments|PCO (W803) : avoid "br"}}
 
{{ReviewsComments|PCO (W803) : bad titles, please use 2x{{=}}}}
 
 
 
 
 
This article explain how to use the EGL texture 0-copy in a 3D application.
 
=What is texture 0-copy?=
 
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.<br>
 
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)
 
 
 
{{ReviewsComments|PCO (W803) : It could be nice to add web links to these extension documentation }}
 
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.<br>
 
 
 
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).<br>
 
 
 
=Example of implementation=
 
 
 
{{ReviewsComments|PCO (W803) : please use the code template instead}}
 
In this example we consider that the GPU natively support NV12 pixel format.
 
<pre>
 
      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);
 
</pre>
 

Attachments

Discussions