Exemple #1
0
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;
}