“EGL texture 0-copy”的版本间的差异

来自百问网嵌入式Linux wiki
(创建页面,内容为“Category:Linux_Operating_System Category:Visual Category:GPU”)
 
 
第1行: 第1行:
[[Category:Linux_Operating_System]]
+
{{ReviewsComments|PCO (W803) : the article name is not so nice}}
[[Category:Visual]]
+
{{ReviewsComments|PCO (W803) : avoid "br"}}
[[Category:GPU]]
+
{{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>
 +
 
 +
<noinclude>
 +
[[Category:GPU]]
 +
</noinclude>

2020年5月8日 (五) 22:38的最新版本

<securetransclude src="ProtectedTemplate:ReviewsComments" params="PCO (W803) : the article name is not so nice"></securetransclude>{{#set:Has reviews comments=true}} <securetransclude src="ProtectedTemplate:ReviewsComments" params="PCO (W803) : avoid "br""></securetransclude>{{#set:Has reviews comments=true}} <securetransclude src="ProtectedTemplate:ReviewsComments" params="PCO (W803) : bad titles, please use 2x'"`UNIQ--nowiki-00000000-QINU`"'"></securetransclude>{{#set:Has reviews comments=true}}


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

<securetransclude src="ProtectedTemplate:ReviewsComments" params="PCO (W803) : It could be nice to add web links to these extension documentation"></securetransclude>{{#set:Has reviews comments=true}} 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).

Example of implementation

<securetransclude src="ProtectedTemplate:ReviewsComments" params="PCO (W803) : please use the code template instead"></securetransclude>{{#set:Has reviews comments=true}} 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);