title: texture for YUV420 to RGB conversion in OpenGL ES
body: <p>I have to convert and display YUV420P images to RGB colorspace using the AMD GPU on a Freescale iMX53 processor (OpenGL ES 2.0, EGL). Linux OS, no X11. To achieve this I should be able to create an appropriate image holding the YUV420P data: this could be either a YUV420P/YV12 image type or 3  simple 8-bit images, one for each component (Y, U, V).</p>
  
  <p>glTexImage2D is excluded, because it's slow, the YUV420P frames are the results of a real time video decoding @25FPS and with glTexImage2D we can't keep the desired framerate.</p>
  
  <p>There's an alternative: eglCreateImageKHR/glEGLImageTargetTexture2DOES. The only problem is that these can't handle any image format that would be suitable for YUV420/YV12 data.</p>
  
  <pre><code>EGLint attribs[] = {
    EGL_WIDTH, 800,
    EGL_HEIGHT, 480,
    EGL_IMAGE_FORMAT_FSL, EGL_FORMAT_YUV_YV12_FSL,
    EGL_NONE
  };
  
  EGLint const req_attribs[] = {
    EGL_RED_SIZE, 5,
    EGL_GREEN_SIZE, 6,
    EGL_BLUE_SIZE, 5,
    EGL_ALPHA_SIZE, 0,
    EGL_SAMPLES, 0,
    EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,
    EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
    EGL_NONE
  };
  
  ...
  
  display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
  eglInitialize(display, NULL, NULL);
  eglBindAPI(EGL_OPENGL_ES_API);
  eglChooseConfig(display, req_attribs, config, ARRAY_SIZE(config), &amp;num_configs);
  ctx = eglCreateContext(display, curr_config, NULL, NULL);
  surface = eglCreateWindowSurface(display, curr_config, fb_handle, NULL);
  
  ...
  
  EGLImageKHR yuv_img = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_NEW_IMAGE_FSL, NULL, attribs); 
  eglQueryImageFSL(display, yuv_img, EGL_CLIENTBUFFER_TYPE_FSL, (EGLint *)&amp;ptr);
  glGenTextures(1, &amp;texture);
  glBindTexture(GL_TEXTURE_2D, texture);
  glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, yuv_img);
  </code></pre>
  
  <p>glEGLImageTargetTexture2DOES(...) fails. If I change the appropriate line in 'attribs' to this:</p>
  
  <p>EGL_IMAGE_FORMAT_FSL, EGL_FORMAT_RGB_565_FSL,</p>
  
  <p>then the image can be assigned to an OpenGL ES texture, but it's not appropriate to hold either 8-bit data (Y/U/V) or a YUV420/YV12 data. Searching the net (including Freescale community forum) I've haven't found any solution to this.</p>
  
  <p>How can I create an image which:</p>
  
  <ul>
  <li>is fast to create;</li>
  <li>eventually can be assigned to an already existing buffer (physical address or virtual address is given);</li>
  <li>can be used in the fragment/vertex shader program to perform YUV --> RGB conversion;</li>
  </ul>
  
  <p>Constraint is to avoid unneccessary memcpy(...)s due to performance reasons.</p>