#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>
return -1;
}
-static int get_format(int format)
-{
- switch (format) {
- case HAL_PIXEL_FORMAT_BGRA_8888: return __DRI_IMAGE_FORMAT_ARGB8888;
- case HAL_PIXEL_FORMAT_RGB_565: return __DRI_IMAGE_FORMAT_RGB565;
- case HAL_PIXEL_FORMAT_RGBA_8888: return __DRI_IMAGE_FORMAT_ABGR8888;
- case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
- /*
- * HACK: Hardcode this to RGBX_8888 as per cros_gralloc hack.
- * TODO: Revert this once https://issuetracker.google.com/32077885 is fixed.
- */
- case HAL_PIXEL_FORMAT_RGBX_8888: return __DRI_IMAGE_FORMAT_XBGR8888;
- case HAL_PIXEL_FORMAT_RGBA_FP16: return __DRI_IMAGE_FORMAT_ABGR16161616F;
- case HAL_PIXEL_FORMAT_RGBA_1010102: return __DRI_IMAGE_FORMAT_ABGR2101010;
- default:
- _eglLog(_EGL_WARNING, "unsupported native buffer format 0x%x", format);
- }
- return -1;
-}
-
/* returns # of fds, and by reference the actual fds */
static unsigned
get_native_buffer_fds(struct ANativeWindowBuffer *buf, int fds[3])
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);
if (type == EGL_WINDOW_BIT) {
int format;
int buffer_count;
- const int min_buffers = 3;
+ int min_buffer_count, max_buffer_count;
+
+ /* Prefer triple buffering for performance reasons. */
+ const int preferred_buffer_count = 3;
if (window->common.magic != ANDROID_NATIVE_WINDOW_MAGIC) {
_eglError(EGL_BAD_NATIVE_WINDOW, "droid_create_surface");
goto cleanup_surface;
}
- /* Query ANativeWindow for MIN_UNDEQUEUED_BUFFER, set buffer count
- * and allocate color_buffers.
+ /* Query ANativeWindow for MIN_UNDEQUEUED_BUFFER, minimum amount
+ * of undequeued buffers.
*/
if (window->query(window, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
- &buffer_count)) {
+ &min_buffer_count)) {
_eglError(EGL_BAD_NATIVE_WINDOW, "droid_create_surface");
goto cleanup_surface;
}
- if (buffer_count < min_buffers)
- buffer_count = min_buffers;
+ /* Query for maximum buffer count, application can set this
+ * to limit the total amount of buffers.
+ */
+ if (window->query(window, NATIVE_WINDOW_MAX_BUFFER_COUNT,
+ &max_buffer_count)) {
+ _eglError(EGL_BAD_NATIVE_WINDOW, "droid_create_surface");
+ goto cleanup_surface;
+ }
+
+ /* Clamp preferred between minimum (min undequeued + 1 dequeued)
+ * and maximum.
+ */
+ buffer_count = CLAMP(preferred_buffer_count, min_buffer_count + 1,
+ max_buffer_count);
+
if (native_window_set_buffer_count(window, buffer_count)) {
_eglError(EGL_BAD_NATIVE_WINDOW, "droid_create_surface");
goto cleanup_surface;
window->query(window, NATIVE_WINDOW_WIDTH, &dri2_surf->base.Width);
window->query(window, NATIVE_WINDOW_HEIGHT, &dri2_surf->base.Height);
+
+ uint32_t usage = strcmp(dri2_dpy->driver_name, "kms_swrast") == 0
+ ? GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN
+ : GRALLOC_USAGE_HW_RENDER;
+ native_window_set_usage(window, usage);
}
config = dri2_get_dri_config(dri2_conf, type,
}
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,
+droid_swap_interval(const _EGLDriver *drv, _EGLDisplay *disp,
_EGLSurface *surf, EGLint interval)
{
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
}
static EGLint
-droid_query_buffer_age(_EGLDriver *drv,
+droid_query_buffer_age(const _EGLDriver *drv,
_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(const _EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
}
#ifdef HAVE_DRM_GRALLOC
+static int get_format(int format)
+{
+ switch (format) {
+ case HAL_PIXEL_FORMAT_BGRA_8888: return __DRI_IMAGE_FORMAT_ARGB8888;
+ case HAL_PIXEL_FORMAT_RGB_565: return __DRI_IMAGE_FORMAT_RGB565;
+ case HAL_PIXEL_FORMAT_RGBA_8888: return __DRI_IMAGE_FORMAT_ABGR8888;
+ case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
+ /*
+ * HACK: Hardcode this to RGBX_8888 as per cros_gralloc hack.
+ * TODO: Revert this once https://issuetracker.google.com/32077885 is fixed.
+ */
+ case HAL_PIXEL_FORMAT_RGBX_8888: return __DRI_IMAGE_FORMAT_XBGR8888;
+ case HAL_PIXEL_FORMAT_RGBA_FP16: return __DRI_IMAGE_FORMAT_ABGR16161616F;
+ case HAL_PIXEL_FORMAT_RGBA_1010102: return __DRI_IMAGE_FORMAT_ABGR2101010;
+ default:
+ _eglLog(_EGL_WARNING, "unsupported native buffer format 0x%x", format);
+ }
+ return -1;
+}
+
static _EGLImage *
droid_create_image_from_name(_EGLDisplay *disp, _EGLContext *ctx,
struct ANativeWindowBuffer *buf)
#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 *
}
static _EGLImage *
-droid_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
+droid_create_image_khr(const _EGLDriver *drv, _EGLDisplay *disp,
_EGLContext *ctx, EGLenum target,
EGLClientBuffer buffer, const EGLint *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;
disp->Extensions.ANDROID_framebuffer_target = EGL_TRUE;
disp->Extensions.ANDROID_image_native_buffer = EGL_TRUE;
disp->Extensions.ANDROID_recordable = EGL_TRUE;
- disp->Extensions.EXT_buffer_age = EGL_TRUE;
+
+ /* Querying buffer age requires a buffer to be dequeued. Without
+ * EGL_ANDROID_native_fence_sync, dequeue might call eglClientWaitSync and
+ * result in a deadlock (the lock is already held by eglQuerySurface).
+ */
+ if (disp->Extensions.ANDROID_native_fence_sync) {
+ disp->Extensions.EXT_buffer_age = EGL_TRUE;
+ } else {
+ /* disable KHR_partial_update that might have been enabled in
+ * dri2_setup_screen
+ */
+ disp->Extensions.KHR_partial_update = EGL_FALSE;
+ }
+
disp->Extensions.KHR_image = EGL_TRUE;
#if ANDROID_API_LEVEL >= 24
if (dri2_dpy->mutable_render_buffer &&
/* 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;
}