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); if (fourcc == -1) { _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR"); return NULL; } 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, pitches[0], EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0, EGL_NONE, 0 }; return dri2_create_image_dma_buf(disp, ctx, NULL, attr_list); }
static _EGLImage * dri2_create_image_android_native_buffer(_EGLDisplay *disp, _EGLContext *ctx, struct ANativeWindowBuffer *buf) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_image *dri2_img; int name, fd; int format; if (ctx != NULL) { /* From the EGL_ANDROID_image_native_buffer spec: * * * If <target> is EGL_NATIVE_BUFFER_ANDROID and <ctx> is not * EGL_NO_CONTEXT, the error EGL_BAD_CONTEXT is generated. */ _eglError(EGL_BAD_CONTEXT, "eglCreateEGLImageKHR: for " "EGL_NATIVE_BUFFER_ANDROID, the context must be " "EGL_NO_CONTEXT"); return NULL; } if (!buf || buf->common.magic != ANDROID_NATIVE_BUFFER_MAGIC || buf->common.version != sizeof(*buf)) { _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR"); return NULL; } fd = get_native_buffer_fd(buf); if (fd >= 0) { const int fourcc = get_fourcc(get_format(buf->format)); const int pitch = buf->stride * get_format_bpp(buf->format); const EGLint attr_list[14] = { 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_OFFSET_EXT, 0, EGL_NONE, 0 }; if (fourcc == -1 || pitch == 0) return NULL; return dri2_create_image_dma_buf(disp, ctx, NULL, attr_list); } name = get_native_buffer_name(buf); if (!name) { _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR"); return NULL; } format = get_format(buf->format); if (format == -1) return NULL; dri2_img = calloc(1, sizeof(*dri2_img)); if (!dri2_img) { _eglError(EGL_BAD_ALLOC, "droid_create_image_mesa_drm"); return NULL; } if (!_eglInitImage(&dri2_img->base, disp)) { free(dri2_img); return NULL; } dri2_img->dri_image = dri2_dpy->image->createImageFromName(dri2_dpy->dri_screen, buf->width, buf->height, format, name, buf->stride, dri2_img); if (!dri2_img->dri_image) { free(dri2_img); _eglError(EGL_BAD_ALLOC, "droid_create_image_mesa_drm"); return NULL; } return &dri2_img->base; }