#include <sys/types.h>
#include <drm-uapi/drm_fourcc.h>
+#include "util/os_file.h"
+
#include "loader.h"
#include "egl_dri2.h"
-#include "egl_dri2_fallbacks.h"
#ifdef HAVE_DRM_GRALLOC
#include <gralloc_drm_handle.h>
droid_set_shared_buffer_mode(_EGLDisplay *disp, _EGLSurface *surf, bool mode)
{
#if ANDROID_API_LEVEL >= 24
- struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
struct ANativeWindow *window = dri2_surf->window;
}
static _EGLSurface *
-droid_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
- _EGLConfig *conf, void *native_window,
- const EGLint *attrib_list)
+droid_create_surface(_EGLDisplay *disp, EGLint type, _EGLConfig *conf,
+ void *native_window, const EGLint *attrib_list)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
}
static _EGLSurface *
-droid_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp,
- _EGLConfig *conf, void *native_window,
- const EGLint *attrib_list)
+droid_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf,
+ void *native_window, const EGLint *attrib_list)
{
- return droid_create_surface(drv, disp, EGL_WINDOW_BIT, conf,
+ return droid_create_surface(disp, EGL_WINDOW_BIT, conf,
native_window, attrib_list);
}
static _EGLSurface *
-droid_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *disp,
- _EGLConfig *conf, const EGLint *attrib_list)
+droid_create_pbuffer_surface(_EGLDisplay *disp, _EGLConfig *conf,
+ const EGLint *attrib_list)
{
- return droid_create_surface(drv, disp, EGL_PBUFFER_BIT, conf,
- NULL, attrib_list);
+ return droid_create_surface(disp, EGL_PBUFFER_BIT, conf,
+ NULL, attrib_list);
}
static EGLBoolean
-droid_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
+droid_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
}
static EGLBoolean
-droid_swap_interval(_EGLDriver *drv, _EGLDisplay *disp,
- _EGLSurface *surf, EGLint interval)
+droid_swap_interval(_EGLDisplay *disp, _EGLSurface *surf, EGLint interval)
{
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
struct ANativeWindow *window = dri2_surf->window;
}
static EGLint
-droid_query_buffer_age(_EGLDriver *drv,
- _EGLDisplay *disp, _EGLSurface *surface)
+droid_query_buffer_age(_EGLDisplay *disp, _EGLSurface *surface)
{
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surface);
}
static EGLBoolean
-droid_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
+droid_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
return EGL_TRUE;
}
-static _EGLImage *
-droid_create_image_from_prime_fds_yuv(_EGLDisplay *disp, _EGLContext *ctx,
+static __DRIimage *
+droid_create_image_from_prime_fds_yuv(_EGLDisplay *disp,
struct ANativeWindowBuffer *buf,
int num_fds, int fds[3])
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct android_ycbcr ycbcr;
- size_t offsets[3];
- size_t pitches[3];
+ int offsets[3];
+ int pitches[3];
enum chroma_order chroma_order;
int fourcc;
int ret;
+ unsigned error;
if (!dri2_dpy->gralloc->lock_ycbcr) {
_eglLog(_EGL_WARNING, "Gralloc does not support lock_ycbcr");
assert(num_fds == expected_planes);
}
- if (ycbcr.chroma_step == 2) {
- /* Semi-planar Y + CbCr or Y + CrCb format. */
- const EGLint attr_list_2plane[] = {
- EGL_WIDTH, buf->width,
- EGL_HEIGHT, buf->height,
- EGL_LINUX_DRM_FOURCC_EXT, fourcc,
- EGL_DMA_BUF_PLANE0_FD_EXT, fds[0],
- EGL_DMA_BUF_PLANE0_PITCH_EXT, pitches[0],
- EGL_DMA_BUF_PLANE0_OFFSET_EXT, offsets[0],
- EGL_DMA_BUF_PLANE1_FD_EXT, fds[1],
- EGL_DMA_BUF_PLANE1_PITCH_EXT, pitches[1],
- EGL_DMA_BUF_PLANE1_OFFSET_EXT, offsets[1],
- EGL_NONE, 0
- };
-
- return dri2_create_image_dma_buf(disp, ctx, NULL, attr_list_2plane);
- } else {
- /* Fully planar Y + Cb + Cr or Y + Cr + Cb format. */
- const EGLint attr_list_3plane[] = {
- EGL_WIDTH, buf->width,
- EGL_HEIGHT, buf->height,
- EGL_LINUX_DRM_FOURCC_EXT, fourcc,
- EGL_DMA_BUF_PLANE0_FD_EXT, fds[0],
- EGL_DMA_BUF_PLANE0_PITCH_EXT, pitches[0],
- EGL_DMA_BUF_PLANE0_OFFSET_EXT, offsets[0],
- EGL_DMA_BUF_PLANE1_FD_EXT, fds[1],
- EGL_DMA_BUF_PLANE1_PITCH_EXT, pitches[1],
- EGL_DMA_BUF_PLANE1_OFFSET_EXT, offsets[1],
- EGL_DMA_BUF_PLANE2_FD_EXT, fds[2],
- 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_3plane);
- }
+ return dri2_dpy->image->createImageFromDmaBufs(dri2_dpy->dri_screen,
+ buf->width, buf->height, fourcc,
+ fds, num_fds, pitches, offsets,
+ EGL_ITU_REC601_EXT,
+ EGL_YUV_NARROW_RANGE_EXT,
+ EGL_YUV_CHROMA_SITING_0_EXT,
+ EGL_YUV_CHROMA_SITING_0_EXT,
+ &error,
+ NULL);
}
-static _EGLImage *
-droid_create_image_from_prime_fds(_EGLDisplay *disp, _EGLContext *ctx,
- struct ANativeWindowBuffer *buf, int num_fds, int fds[3])
+static __DRIimage *
+droid_create_image_from_prime_fds(_EGLDisplay *disp,
+ struct ANativeWindowBuffer *buf)
{
- unsigned int pitch;
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ int pitches[4] = { 0 }, offsets[4] = { 0 };
+ unsigned error;
+ int num_fds;
+ int fds[3];
+
+ num_fds = get_native_buffer_fds(buf, fds);
+ if (num_fds == 0)
+ return NULL;
if (is_yuv(buf->format)) {
- _EGLImage *image;
+ __DRIimage *image;
- image = droid_create_image_from_prime_fds_yuv(disp, ctx, buf, num_fds, fds);
+ image = droid_create_image_from_prime_fds_yuv(disp, buf, num_fds, fds);
/*
* HACK: https://issuetracker.google.com/32077885
* There is no API available to properly query the IMPLEMENTATION_DEFINED
return NULL;
}
- pitch = buf->stride * get_format_bpp(buf->format);
- if (pitch == 0) {
+ pitches[0] = buf->stride * get_format_bpp(buf->format);
+ if (pitches[0] == 0) {
_eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
return NULL;
}
- const EGLint attr_list[] = {
- EGL_WIDTH, buf->width,
- EGL_HEIGHT, buf->height,
- EGL_LINUX_DRM_FOURCC_EXT, fourcc,
- EGL_DMA_BUF_PLANE0_FD_EXT, fds[0],
- EGL_DMA_BUF_PLANE0_PITCH_EXT, pitch,
- EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,
- EGL_NONE, 0
- };
-
- return dri2_create_image_dma_buf(disp, ctx, NULL, attr_list);
+ return dri2_dpy->image->createImageFromDmaBufs(dri2_dpy->dri_screen,
+ buf->width, buf->height, fourcc,
+ fds, num_fds, pitches, offsets,
+ EGL_ITU_REC601_EXT,
+ EGL_YUV_NARROW_RANGE_EXT,
+ EGL_YUV_CHROMA_SITING_0_EXT,
+ EGL_YUV_CHROMA_SITING_0_EXT,
+ &error,
+ NULL);
}
#ifdef HAVE_DRM_GRALLOC
}
static _EGLImage *
-droid_create_image_from_name(_EGLDisplay *disp, _EGLContext *ctx,
+droid_create_image_from_name(_EGLDisplay *disp,
struct ANativeWindowBuffer *buf)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
- struct dri2_egl_image *dri2_img;
+ __DRIimage *dri_image;
int name;
int 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;
- }
-
- _eglInitImage(&dri2_img->base, disp);
-
- dri2_img->dri_image =
+ return
dri2_dpy->image->createImageFromName(dri2_dpy->dri_screen,
buf->width,
buf->height,
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;
}
#endif /* HAVE_DRM_GRALLOC */
static EGLBoolean
-droid_query_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf,
+droid_query_surface(_EGLDisplay *disp, _EGLSurface *surf,
EGLint attribute, EGLint *value)
{
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
default:
break;
}
- return _eglQuerySurface(drv, disp, surf, attribute, value);
+ return _eglQuerySurface(disp, surf, attribute, value);
}
static _EGLImage *
_EGLContext *ctx,
struct ANativeWindowBuffer *buf)
{
- int fds[3];
- unsigned num_fds;
-
if (ctx != NULL) {
/* From the EGL_ANDROID_image_native_buffer spec:
*
return NULL;
}
- num_fds = get_native_buffer_fds(buf, fds);
- if (num_fds > 0)
- return droid_create_image_from_prime_fds(disp, ctx, buf, num_fds, fds);
+ __DRIimage *dri_image =
+ droid_create_image_from_prime_fds(disp, buf);
#ifdef HAVE_DRM_GRALLOC
- return droid_create_image_from_name(disp, ctx, buf);
-#else
- return NULL;
+ if (dri_image == NULL)
+ dri_image = droid_create_image_from_name(disp, buf);
#endif
+
+ if (dri_image)
+ return dri2_create_image_from_dri(disp, dri_image);
+
+ return NULL;
}
static _EGLImage *
-droid_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
- _EGLContext *ctx, EGLenum target,
- EGLClientBuffer buffer, const EGLint *attr_list)
+droid_create_image_khr(_EGLDisplay *disp, _EGLContext *ctx, EGLenum target,
+ EGLClientBuffer buffer, const EGLint *attr_list)
{
switch (target) {
case EGL_NATIVE_BUFFER_ANDROID:
return dri2_create_image_android_native_buffer(disp, ctx,
(struct ANativeWindowBuffer *) buffer);
default:
- return dri2_create_image_khr(drv, disp, ctx, target, buffer, attr_list);
+ return dri2_create_image_khr(disp, ctx, target, buffer, attr_list);
}
}
}
static EGLBoolean
-droid_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *disp)
+droid_add_configs_for_visuals(_EGLDisplay *disp)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
static const struct {
static const struct dri2_egl_display_vtbl droid_display_vtbl = {
.authenticate = NULL,
.create_window_surface = droid_create_window_surface,
- .create_pixmap_surface = dri2_fallback_create_pixmap_surface,
.create_pbuffer_surface = droid_create_pbuffer_surface,
.destroy_surface = droid_destroy_surface,
.create_image = droid_create_image_khr,
.swap_buffers = droid_swap_buffers,
- .swap_buffers_with_damage = dri2_fallback_swap_buffers_with_damage, /* Android implements the function */
- .swap_buffers_region = dri2_fallback_swap_buffers_region,
.swap_interval = droid_swap_interval,
- .post_sub_buffer = dri2_fallback_post_sub_buffer,
- .copy_buffers = dri2_fallback_copy_buffers,
.query_buffer_age = droid_query_buffer_age,
.query_surface = droid_query_surface,
- .create_wayland_buffer_from_image = dri2_fallback_create_wayland_buffer_from_image,
- .get_sync_values = dri2_fallback_get_sync_values,
.get_dri_drawable = dri2_surface_get_dri_drawable,
.set_shared_buffer_mode = droid_set_shared_buffer_mode,
};
static EGLBoolean
droid_load_driver(_EGLDisplay *disp, bool swrast)
{
- struct dri2_egl_display *dri2_dpy = disp->DriverData;
- const char *err;
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd);
if (dri2_dpy->driver_name == NULL)
* systems.) */
dri2_dpy->loader_extensions = droid_dri2_loader_extensions;
if (!dri2_load_driver(disp)) {
- err = "DRI2: failed to load driver";
goto error;
}
#else
free(dri2_dpy->driver_name);
dri2_dpy->driver_name = strdup("kms_swrast");
} else {
- err = "DRI3: failed to find software capable driver";
goto error;
}
}
dri2_dpy->loader_extensions = droid_image_loader_extensions;
if (!dri2_load_driver_dri3(disp)) {
- err = "DRI3: failed to load driver";
goto error;
}
#endif
return EGL_FALSE;
}
- dri2_dpy->fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
+ dri2_dpy->fd = os_dupfd_cloexec(fd);
if (dri2_dpy->fd < 0)
return EGL_FALSE;
#endif
EGLBoolean
-dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *disp)
+dri2_initialize_android(_EGLDisplay *disp)
{
_EGLDevice *dev;
bool device_opened = false;
/* Create configs *after* enabling extensions because presence of DRI
* driver extensions can affect the capabilities of EGLConfigs.
*/
- if (!droid_add_configs_for_visuals(drv, disp)) {
+ if (!droid_add_configs_for_visuals(disp)) {
err = "DRI2: failed to add configs";
goto cleanup;
}