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 int droid_get_buffers_parse_attachments(struct dri2_egl_surface *dri2_surf, unsigned int *attachments, int count) { int num_buffers = 0, i; /* fill dri2_surf->buffers */ for (i = 0; i < count * 2; i += 2) { __DRIbuffer *buf, *local; assert(num_buffers < ARRAY_SIZE(dri2_surf->buffers)); buf = &dri2_surf->buffers[num_buffers]; switch (attachments[i]) { case __DRI_BUFFER_BACK_LEFT: if (dri2_surf->base.Type == EGL_WINDOW_BIT) { buf->attachment = attachments[i]; buf->name = get_native_buffer_name(dri2_surf->buffer); buf->cpp = get_format_bpp(dri2_surf->buffer->format); buf->pitch = dri2_surf->buffer->stride * buf->cpp; buf->flags = 0; if (buf->name) num_buffers++; break; } /* fall through for pbuffers */ case __DRI_BUFFER_DEPTH: case __DRI_BUFFER_STENCIL: case __DRI_BUFFER_ACCUM: case __DRI_BUFFER_DEPTH_STENCIL: case __DRI_BUFFER_HIZ: local = droid_alloc_local_buffer(dri2_surf, attachments[i], attachments[i + 1]); if (local) { *buf = *local; num_buffers++; } break; case __DRI_BUFFER_FRONT_LEFT: case __DRI_BUFFER_FRONT_RIGHT: case __DRI_BUFFER_FAKE_FRONT_LEFT: case __DRI_BUFFER_FAKE_FRONT_RIGHT: case __DRI_BUFFER_BACK_RIGHT: default: /* no front or right buffers */ break; } } return num_buffers; }
static int get_back_bo(struct dri2_egl_surface *dri2_surf) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display); int fourcc, pitch; int offset = 0, fd; if (dri2_surf->dri_image) return 0; if (!dri2_surf->buffer) return -1; fd = get_native_buffer_fd(dri2_surf->buffer); if (fd < 0) { _eglLog(_EGL_WARNING, "Could not get native buffer FD"); return -1; } fourcc = get_fourcc(dri2_surf->buffer->format); pitch = dri2_surf->buffer->stride * get_format_bpp(dri2_surf->buffer->format); if (fourcc == -1 || pitch == 0) { _eglLog(_EGL_WARNING, "Invalid buffer fourcc(%x) or pitch(%d)", fourcc, pitch); return -1; } dri2_surf->dri_image = dri2_dpy->image->createImageFromFds(dri2_dpy->dri_screen, dri2_surf->base.Width, dri2_surf->base.Height, fourcc, &fd, 1, &pitch, &offset, dri2_surf); if (!dri2_surf->dri_image) return -1; return 0; }
static int get_back_bo(struct dri2_egl_surface *dri2_surf) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display); int fourcc, pitch; int offset = 0, fd; if (!dri2_surf->buffer) return -1; fd = get_native_buffer_fd(dri2_surf->buffer); if (fd < 0) return -1; fourcc = get_fourcc(get_format(dri2_surf->buffer->format)); pitch = dri2_surf->buffer->stride * get_format_bpp(dri2_surf->buffer->format); if (fourcc == -1 || pitch == 0) return -1; dri2_surf->dri_image = dri2_dpy->image->createImageFromFds(dri2_dpy->dri_screen, dri2_surf->base.Width, dri2_surf->base.Height, fourcc, &fd, 1, &pitch, &offset, dri2_surf); if (!dri2_surf->dri_image) return -1; return 0; }
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; }