#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)
{
case HAL_PIXEL_FORMAT_RGB_565:
bpp = 2;
break;
+ case HAL_PIXEL_FORMAT_YV12:
+ bpp = 1;
+ break;
default:
bpp = 0;
break;
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);
}
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);
}