egl/android: Add support for YV12 pixel format (v2)
authorTomasz Figa <tfiga@chromium.org>
Tue, 2 Aug 2016 11:07:54 +0000 (20:07 +0900)
committerChad Versace <chad@kiwitree.net>
Mon, 8 Aug 2016 21:18:38 +0000 (14:18 -0700)
This patch adds support for YV12 pixel format to the Android platform
backend. Only creating EGL images is supported, it is not added to the
list of available visuals.

v2: Use const array defined just for YV12 instead of trying to be overly
    generic.

Signed-off-by: Tomasz Figa <tfiga@chromium.org>
Signed-off-by: Kalyan Kondapally <kalyan.kondapally@intel.com>
Tested-by: Rob Herring <rob@kernel.org>
Reviewed-by: Chad Versace <chad@kiwitree.net>
Change-Id: I4aeb2d67a95c5cdd10b530c549b23146c8f0b983

src/egl/drivers/dri2/platform_android.c

index 596833e8501a0343efae4db7fce2c43de8b9970f..25ceb0e6270ffb8e9e27514942e8cee0f19a1405 100644 (file)
@@ -40,6 +40,8 @@
 #include "egl_dri2_fallbacks.h"
 #include "gralloc_drm.h"
 
+#define ALIGN(val, align)      (((val) + (align) - 1) & ~((align) - 1))
+
 static int
 get_format_bpp(int native)
 {
@@ -57,6 +59,9 @@ get_format_bpp(int native)
    case HAL_PIXEL_FORMAT_RGB_565:
       bpp = 2;
       break;
+   case HAL_PIXEL_FORMAT_YV12:
+      bpp = 1;
+      break;
    default:
       bpp = 0;
       break;
@@ -73,6 +78,7 @@ static int get_fourcc(int native)
    case HAL_PIXEL_FORMAT_BGRA_8888: return __DRI_IMAGE_FOURCC_ARGB8888;
    case HAL_PIXEL_FORMAT_RGBA_8888: return __DRI_IMAGE_FOURCC_ABGR8888;
    case HAL_PIXEL_FORMAT_RGBX_8888: return __DRI_IMAGE_FOURCC_XBGR8888;
+   case HAL_PIXEL_FORMAT_YV12:      return __DRI_IMAGE_FOURCC_YVU420;
    default:
       _eglLog(_EGL_WARNING, "unsupported native buffer format 0x%x", native);
    }
@@ -483,22 +489,60 @@ static _EGLImage *
 droid_create_image_from_prime_fd(_EGLDisplay *disp, _EGLContext *ctx,
                                  struct ANativeWindowBuffer *buf, int fd)
 {
+   unsigned int offsets[3] = { 0, 0, 0 };
+   unsigned int pitches[3] = { 0, 0, 0 };
+
    const int fourcc = get_fourcc(buf->format);
-   const int pitch = buf->stride * get_format_bpp(buf->format);
+   if (fourcc == -1) {
+      _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
+      return NULL;
+   }
 
-   const EGLint attr_list[14] = {
+   pitches[0] = buf->stride * get_format_bpp(buf->format);
+   if (pitches[0] == 0) {
+      _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
+      return NULL;
+   }
+
+   switch (buf->format) {
+   case HAL_PIXEL_FORMAT_YV12:
+      /* Y plane is assumed to be at offset 0. */
+      /* Cr plane is located after Y plane */
+      offsets[1] = offsets[0] + pitches[0] * buf->height;
+      pitches[1] = ALIGN(pitches[0] / 2, 16);
+      /* Cb plane is located after Cr plane */
+      offsets[2] = offsets[1] + pitches[1] * buf->height / 2;
+      pitches[2] = pitches[1];
+
+      const EGLint attr_list_yv12[] = {
+         EGL_WIDTH, buf->width,
+         EGL_HEIGHT, buf->height,
+         EGL_LINUX_DRM_FOURCC_EXT, fourcc,
+         EGL_DMA_BUF_PLANE0_FD_EXT, fd,
+         EGL_DMA_BUF_PLANE0_PITCH_EXT, pitches[0],
+         EGL_DMA_BUF_PLANE0_OFFSET_EXT, offsets[0],
+         EGL_DMA_BUF_PLANE1_FD_EXT, fd,
+         EGL_DMA_BUF_PLANE1_PITCH_EXT, pitches[1],
+         EGL_DMA_BUF_PLANE1_OFFSET_EXT, offsets[1],
+         EGL_DMA_BUF_PLANE2_FD_EXT, fd,
+         EGL_DMA_BUF_PLANE2_PITCH_EXT, pitches[2],
+         EGL_DMA_BUF_PLANE2_OFFSET_EXT, offsets[2],
+         EGL_NONE, 0
+      };
+
+      return dri2_create_image_dma_buf(disp, ctx, NULL, attr_list_yv12);
+   }
+
+   const EGLint attr_list[] = {
       EGL_WIDTH, buf->width,
       EGL_HEIGHT, buf->height,
       EGL_LINUX_DRM_FOURCC_EXT, fourcc,
       EGL_DMA_BUF_PLANE0_FD_EXT, fd,
-      EGL_DMA_BUF_PLANE0_PITCH_EXT, pitch,
+      EGL_DMA_BUF_PLANE0_PITCH_EXT, pitches[0],
       EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,
       EGL_NONE, 0
    };
 
-   if (fourcc == -1 || pitch == 0)
-      return NULL;
-
    return dri2_create_image_dma_buf(disp, ctx, NULL, attr_list);
 }