From 37bbf6a1792773f11c15a4da1588a7520ee2fb4e Mon Sep 17 00:00:00 2001 From: Jonathan Gray Date: Tue, 29 Jan 2019 11:52:33 +0000 Subject: Merge Mesa 18.3.2 --- lib/mesa/src/egl/drivers/dri2/egl_dri2.c | 345 +++++++++++++++++-------------- 1 file changed, 188 insertions(+), 157 deletions(-) (limited to 'lib/mesa/src/egl/drivers/dri2/egl_dri2.c') diff --git a/lib/mesa/src/egl/drivers/dri2/egl_dri2.c b/lib/mesa/src/egl/drivers/dri2/egl_dri2.c index a9c0070a6..4f226b271 100644 --- a/lib/mesa/src/egl/drivers/dri2/egl_dri2.c +++ b/lib/mesa/src/egl/drivers/dri2/egl_dri2.c @@ -48,6 +48,7 @@ #include #ifdef HAVE_WAYLAND_PLATFORM +#include #include "wayland-drm.h" #include "wayland-drm-client-protocol.h" #include "linux-dmabuf-unstable-v1-client-protocol.h" @@ -64,35 +65,7 @@ #include "util/u_vector.h" #include "mapi/glapi/glapi.h" -/* The kernel header drm_fourcc.h defines the DRM formats below. We duplicate - * some of the definitions here so that building Mesa won't bleeding-edge - * kernel headers. - */ -#ifndef DRM_FORMAT_R8 -#define DRM_FORMAT_R8 fourcc_code('R', '8', ' ', ' ') /* [7:0] R */ -#endif - -#ifndef DRM_FORMAT_RG88 -#define DRM_FORMAT_RG88 fourcc_code('R', 'G', '8', '8') /* [15:0] R:G 8:8 little endian */ -#endif - -#ifndef DRM_FORMAT_GR88 -#define DRM_FORMAT_GR88 fourcc_code('G', 'R', '8', '8') /* [15:0] G:R 8:8 little endian */ -#endif - -#ifndef DRM_FORMAT_R16 -#define DRM_FORMAT_R16 fourcc_code('R', '1', '6', ' ') /* [15:0] R 16 little endian */ -#endif - -#ifndef DRM_FORMAT_GR1616 -#define DRM_FORMAT_GR1616 fourcc_code('G', 'R', '3', '2') /* [31:0] R:G 16:16 little endian */ -#endif - -#ifndef DRM_FORMAT_MOD_INVALID -#define DRM_FORMAT_MOD_INVALID ((1ULL<<56) - 1) -#endif - -#define NUM_ATTRIBS 10 +#define NUM_ATTRIBS 12 static void dri_set_background_context(void *loaderPrivate) @@ -299,7 +272,10 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id, _eglSetConfigKey(&base, EGL_MAX_PBUFFER_HEIGHT, _EGL_MAX_PBUFFER_HEIGHT); break; - + case __DRI_ATTRIB_MUTABLE_RENDER_BUFFER: + if (disp->Extensions.KHR_mutable_render_buffer) + surface_type |= EGL_MUTABLE_RENDER_BUFFER_BIT_KHR; + break; default: key = dri2_to_egl_attribute_map[attrib]; if (key != 0) @@ -365,7 +341,7 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id, _eglLinkConfig(&conf->base); } else { - assert(0); + unreachable("duplicates should not be possible"); return NULL; } @@ -457,6 +433,9 @@ static const struct dri2_extension_match optional_core_extensions[] = { { __DRI2_RENDERER_QUERY, 1, offsetof(struct dri2_egl_display, rendererQuery) }, { __DRI2_INTEROP, 1, offsetof(struct dri2_egl_display, interop) }, { __DRI_IMAGE, 1, offsetof(struct dri2_egl_display, image) }, + { __DRI2_FLUSH_CONTROL, 1, offsetof(struct dri2_egl_display, flush_control) }, + { __DRI2_BLOB, 1, offsetof(struct dri2_egl_display, blob) }, + { __DRI_MUTABLE_RENDER_BUFFER_DRIVER, 1, offsetof(struct dri2_egl_display, mutable_render_buffer) }, { NULL, 0, 0 } }; @@ -694,6 +673,8 @@ dri2_setup_screen(_EGLDisplay *disp) dri2_renderer_query_integer(dri2_dpy, __DRI2_RENDERER_HAS_CONTEXT_PRIORITY); + disp->Extensions.EXT_pixel_format_float = EGL_TRUE; + if (dri2_renderer_query_integer(dri2_dpy, __DRI2_RENDERER_HAS_FRAMEBUFFER_SRGB)) disp->Extensions.KHR_gl_colorspace = EGL_TRUE; @@ -724,6 +705,9 @@ dri2_setup_screen(_EGLDisplay *disp) } } + if (dri2_dpy->blob) + disp->Extensions.ANDROID_blob_cache = EGL_TRUE; + disp->Extensions.KHR_reusable_sync = EGL_TRUE; if (dri2_dpy->image) { @@ -766,6 +750,9 @@ dri2_setup_screen(_EGLDisplay *disp) } #endif } + + if (dri2_dpy->flush_control) + disp->Extensions.KHR_context_flush_control = EGL_TRUE; } void @@ -871,6 +858,15 @@ dri2_setup_extensions(_EGLDisplay *disp) if (!dri2_bind_extensions(dri2_dpy, mandatory_core_extensions, extensions, false)) return EGL_FALSE; +#ifdef HAVE_DRI3_MODIFIERS + dri2_dpy->multibuffers_available = + (dri2_dpy->dri3_major_version > 1 || (dri2_dpy->dri3_major_version == 1 && + dri2_dpy->dri3_minor_version >= 2)) && + (dri2_dpy->present_major_version > 1 || (dri2_dpy->present_major_version == 1 && + dri2_dpy->present_minor_version >= 2)) && + (dri2_dpy->image && dri2_dpy->image->base.version >= 15); +#endif + dri2_bind_extensions(dri2_dpy, optional_core_extensions, extensions, true); return EGL_TRUE; } @@ -905,33 +901,23 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp) } switch (disp->Platform) { -#ifdef HAVE_SURFACELESS_PLATFORM case _EGL_PLATFORM_SURFACELESS: ret = dri2_initialize_surfaceless(drv, disp); break; -#endif -#ifdef HAVE_X11_PLATFORM case _EGL_PLATFORM_X11: ret = dri2_initialize_x11(drv, disp); break; -#endif -#ifdef HAVE_DRM_PLATFORM case _EGL_PLATFORM_DRM: ret = dri2_initialize_drm(drv, disp); break; -#endif -#ifdef HAVE_WAYLAND_PLATFORM case _EGL_PLATFORM_WAYLAND: ret = dri2_initialize_wayland(drv, disp); break; -#endif -#ifdef HAVE_ANDROID_PLATFORM case _EGL_PLATFORM_ANDROID: ret = dri2_initialize_android(drv, disp); break; -#endif default: - _eglLog(_EGL_WARNING, "No EGL platform enabled."); + unreachable("Callers ensure we cannot get here."); return EGL_FALSE; } @@ -988,43 +974,17 @@ dri2_display_destroy(_EGLDisplay *disp) #endif switch (disp->Platform) { -#ifdef HAVE_X11_PLATFORM case _EGL_PLATFORM_X11: - if (dri2_dpy->own_device) { - xcb_disconnect(dri2_dpy->conn); - } + dri2_teardown_x11(dri2_dpy); break; -#endif -#ifdef HAVE_DRM_PLATFORM case _EGL_PLATFORM_DRM: - if (dri2_dpy->own_device) { - gbm_device_destroy(&dri2_dpy->gbm_dri->base); - } + dri2_teardown_drm(dri2_dpy); break; -#endif -#ifdef HAVE_WAYLAND_PLATFORM case _EGL_PLATFORM_WAYLAND: - if (dri2_dpy->wl_drm) - wl_drm_destroy(dri2_dpy->wl_drm); - if (dri2_dpy->wl_dmabuf) - zwp_linux_dmabuf_v1_destroy(dri2_dpy->wl_dmabuf); - if (dri2_dpy->wl_shm) - wl_shm_destroy(dri2_dpy->wl_shm); - if (dri2_dpy->wl_registry) - wl_registry_destroy(dri2_dpy->wl_registry); - if (dri2_dpy->wl_queue) - wl_event_queue_destroy(dri2_dpy->wl_queue); - if (dri2_dpy->wl_dpy_wrapper) - wl_proxy_wrapper_destroy(dri2_dpy->wl_dpy_wrapper); - u_vector_finish(&dri2_dpy->wl_modifiers.argb8888); - u_vector_finish(&dri2_dpy->wl_modifiers.xrgb8888); - u_vector_finish(&dri2_dpy->wl_modifiers.rgb565); - if (dri2_dpy->own_device) { - wl_display_disconnect(dri2_dpy->wl_dpy); - } + dri2_teardown_wayland(dri2_dpy); break; -#endif default: + /* TODO: add teardown for other platforms */ break; } @@ -1148,7 +1108,7 @@ dri2_create_context_attribs_error(int dri_error) break; default: - assert(0); + assert(!"unknown dri_error code"); egl_error = EGL_BAD_MATCH; break; } @@ -1223,6 +1183,11 @@ dri2_fill_context_attribs(struct dri2_egl_context *dri2_ctx, ctx_attribs[pos++] = val; } + if (dri2_ctx->base.ReleaseBehavior == EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR) { + ctx_attribs[pos++] = __DRI_CTX_ATTRIB_RELEASE_BEHAVIOR; + ctx_attribs[pos++] = __DRI_CTX_RELEASE_BEHAVIOR_NONE; + } + *num_attribs = pos; return true; @@ -1243,6 +1208,9 @@ dri2_create_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, struct dri2_egl_config *dri2_config = dri2_egl_config(conf); const __DRIconfig *dri_config; int api; + unsigned error; + unsigned num_attribs = NUM_ATTRIBS; + uint32_t ctx_attribs[NUM_ATTRIBS]; (void) drv; @@ -1325,25 +1293,15 @@ dri2_create_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, dri_config = dri2_config->dri_config[1][0]; else dri_config = dri2_config->dri_config[0][0]; - - /* EGL_WINDOW_BIT is set only when there is a double-buffered dri_config. - * This makes sure the back buffer will always be used. - */ - if (conf->SurfaceType & EGL_WINDOW_BIT) - dri2_ctx->base.WindowRenderBuffer = EGL_BACK_BUFFER; } else dri_config = NULL; - if (dri2_dpy->image_driver) { - unsigned error; - unsigned num_attribs = NUM_ATTRIBS; - uint32_t ctx_attribs[NUM_ATTRIBS]; - - if (!dri2_fill_context_attribs(dri2_ctx, dri2_dpy, ctx_attribs, - &num_attribs)) - goto cleanup; + if (!dri2_fill_context_attribs(dri2_ctx, dri2_dpy, ctx_attribs, + &num_attribs)) + goto cleanup; + if (dri2_dpy->image_driver) { dri2_ctx->dri_context = dri2_dpy->image_driver->createContextAttribs(dri2_dpy->dri_screen, api, @@ -1356,14 +1314,6 @@ dri2_create_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, dri2_create_context_attribs_error(error); } else if (dri2_dpy->dri2) { if (dri2_dpy->dri2->base.version >= 3) { - unsigned error; - unsigned num_attribs = NUM_ATTRIBS; - uint32_t ctx_attribs[NUM_ATTRIBS]; - - if (!dri2_fill_context_attribs(dri2_ctx, dri2_dpy, ctx_attribs, - &num_attribs)) - goto cleanup; - dri2_ctx->dri_context = dri2_dpy->dri2->createContextAttribs(dri2_dpy->dri_screen, api, @@ -1385,14 +1335,6 @@ dri2_create_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, } else { assert(dri2_dpy->swrast); if (dri2_dpy->swrast->base.version >= 3) { - unsigned error; - unsigned num_attribs = NUM_ATTRIBS; - uint32_t ctx_attribs[NUM_ATTRIBS]; - - if (!dri2_fill_context_attribs(dri2_ctx, dri2_dpy, ctx_attribs, - &num_attribs)) - goto cleanup; - dri2_ctx->dri_context = dri2_dpy->swrast->createContextAttribs(dri2_dpy->dri_screen, api, @@ -1521,6 +1463,8 @@ dri2_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf, { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); + _EGLDisplay *old_disp = NULL; + struct dri2_egl_display *old_dri2_dpy = NULL; _EGLContext *old_ctx; _EGLSurface *old_dsurf, *old_rsurf; _EGLSurface *tmp_dsurf, *tmp_rsurf; @@ -1537,6 +1481,11 @@ dri2_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf, return EGL_FALSE; } + if (old_ctx) { + old_disp = old_ctx->Resource.Display; + old_dri2_dpy = dri2_egl_display(old_disp); + } + /* flush before context switch */ if (old_ctx) dri2_gl_flush(); @@ -1550,31 +1499,30 @@ dri2_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf, if (old_dsurf) dri2_surf_update_fence_fd(old_ctx, disp, old_dsurf); + + /* Disable shared buffer mode */ + if (old_dsurf && _eglSurfaceInSharedBufferMode(old_dsurf) && + old_dri2_dpy->vtbl->set_shared_buffer_mode) { + old_dri2_dpy->vtbl->set_shared_buffer_mode(old_disp, old_dsurf, false); + } + dri2_dpy->core->unbindContext(old_cctx); } unbind = (cctx == NULL && ddraw == NULL && rdraw == NULL); - if (unbind || dri2_dpy->core->bindContext(cctx, ddraw, rdraw)) { - dri2_destroy_surface(drv, disp, old_dsurf); - dri2_destroy_surface(drv, disp, old_rsurf); - - if (!unbind) - dri2_dpy->ref_count++; - if (old_ctx) { - EGLDisplay old_disp = _eglGetDisplayHandle(old_ctx->Resource.Display); - dri2_destroy_context(drv, disp, old_ctx); - dri2_display_release(old_disp); - } - - return EGL_TRUE; - } else { + if (!unbind && !dri2_dpy->core->bindContext(cctx, ddraw, rdraw)) { /* undo the previous _eglBindContext */ _eglBindContext(old_ctx, old_dsurf, old_rsurf, &ctx, &tmp_dsurf, &tmp_rsurf); assert(&dri2_ctx->base == ctx && tmp_dsurf == dsurf && tmp_rsurf == rsurf); + if (old_dsurf && _eglSurfaceInSharedBufferMode(old_dsurf) && + old_dri2_dpy->vtbl->set_shared_buffer_mode) { + old_dri2_dpy->vtbl->set_shared_buffer_mode(old_disp, old_dsurf, true); + } + _eglPutSurface(dsurf); _eglPutSurface(rsurf); _eglPutContext(ctx); @@ -1589,6 +1537,31 @@ dri2_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf, */ return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); } + + dri2_destroy_surface(drv, disp, old_dsurf); + dri2_destroy_surface(drv, disp, old_rsurf); + + if (!unbind) + dri2_dpy->ref_count++; + + if (old_ctx) { + dri2_destroy_context(drv, disp, old_ctx); + dri2_display_release(old_disp); + } + + if (dsurf && _eglSurfaceHasMutableRenderBuffer(dsurf) && + dri2_dpy->vtbl->set_shared_buffer_mode) { + /* Always update the shared buffer mode. This is obviously needed when + * the active EGL_RENDER_BUFFER is EGL_SINGLE_BUFFER. When + * EGL_RENDER_BUFFER is EGL_BACK_BUFFER, the update protects us in the + * case where external non-EGL API may have changed window's shared + * buffer mode since we last saw it. + */ + bool mode = (dsurf->ActiveRenderBuffer == EGL_SINGLE_BUFFER); + dri2_dpy->vtbl->set_shared_buffer_mode(disp, dsurf, mode); + } + + return EGL_TRUE; } __DRIdrawable * @@ -1842,7 +1815,7 @@ dri2_release_tex_image(_EGLDriver *drv, target = GL_TEXTURE_2D; break; default: - assert(0); + assert(!"missing texture target"); } if (dri2_dpy->tex_buffer->base.version >= 3 && @@ -1905,7 +1878,7 @@ egl_error_from_dri_image_error(int dri_error) case __DRI_IMAGE_ERROR_BAD_ACCESS: return EGL_BAD_ACCESS; default: - assert(0); + assert(!"unknown dri_error code"); return EGL_BAD_ALLOC; } } @@ -2004,7 +1977,8 @@ dri2_create_image_wayland_wl_buffer(_EGLDisplay *disp, _EGLContext *ctx, } dri_image = dri2_dpy->image->fromPlanar(buffer->driver_buffer, plane, NULL); - + if (dri_image == NULL && plane == 0) + dri_image = dri2_dpy->image->dupImage(buffer->driver_buffer, NULL); if (dri_image == NULL) { _eglError(EGL_BAD_PARAMETER, "dri2_create_image_wayland_wl_buffer"); return NULL; @@ -2250,13 +2224,13 @@ dri2_check_dma_buf_attribs(const _EGLImageAttribs *attrs) return EGL_TRUE; } -/* Returns the total number of file descriptors. Zero indicates an error. */ +/* Returns the total number of planes for the format or zero if it isn't a + * valid fourcc format. + */ static unsigned -dri2_check_dma_buf_format(const _EGLImageAttribs *attrs) +dri2_num_fourcc_format_planes(EGLint format) { - unsigned plane_n; - - switch (attrs->DMABufFourCC.Value) { + switch (format) { case DRM_FORMAT_R8: case DRM_FORMAT_RG88: case DRM_FORMAT_GR88: @@ -2304,14 +2278,14 @@ dri2_check_dma_buf_format(const _EGLImageAttribs *attrs) case DRM_FORMAT_YVYU: case DRM_FORMAT_UYVY: case DRM_FORMAT_VYUY: - plane_n = 1; - break; + return 1; + case DRM_FORMAT_NV12: case DRM_FORMAT_NV21: case DRM_FORMAT_NV16: case DRM_FORMAT_NV61: - plane_n = 2; - break; + return 2; + case DRM_FORMAT_YUV410: case DRM_FORMAT_YVU410: case DRM_FORMAT_YUV411: @@ -2322,10 +2296,20 @@ dri2_check_dma_buf_format(const _EGLImageAttribs *attrs) case DRM_FORMAT_YVU422: case DRM_FORMAT_YUV444: case DRM_FORMAT_YVU444: - plane_n = 3; - break; + return 3; + default: - _eglError(EGL_BAD_ATTRIBUTE, "invalid format"); + return 0; + } +} + +/* Returns the total number of file descriptors. Zero indicates an error. */ +static unsigned +dri2_check_dma_buf_format(const _EGLImageAttribs *attrs) +{ + unsigned plane_n = dri2_num_fourcc_format_planes(attrs->DMABufFourCC.Value); + if (plane_n == 0) { + _eglError(EGL_BAD_MATCH, "unknown drm fourcc format"); return 0; } @@ -2398,6 +2382,18 @@ dri2_query_dma_buf_formats(_EGLDriver *drv, _EGLDisplay *disp, formats, count)) return EGL_FALSE; + if (max > 0) { + /* Assert that all of the formats returned are actually fourcc formats. + * Some day, if we want the internal interface function to be able to + * return the fake fourcc formats defined in dri_interface.h, we'll have + * to do something more clever here to pair the list down to just real + * fourcc formats so that we don't leak the fake internal ones. + */ + for (int i = 0; i < *count; i++) { + assert(dri2_num_fourcc_format_planes(formats[i]) > 0); + } + } + return EGL_TRUE; } @@ -2408,6 +2404,9 @@ dri2_query_dma_buf_modifiers(_EGLDriver *drv, _EGLDisplay *disp, EGLint format, { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + if (dri2_num_fourcc_format_planes(format) == 0) + return _eglError(EGL_BAD_PARAMETER, "invalid fourcc format"); + if (max < 0) return _eglError(EGL_BAD_PARAMETER, "invalid value for max count of formats"); @@ -2484,8 +2483,8 @@ dri2_create_image_dma_buf(_EGLDisplay *disp, _EGLContext *ctx, * will be present in attrs.DMABufPlaneModifiersLo[0] and * attrs.DMABufPlaneModifiersHi[0] */ if (attrs.DMABufPlaneModifiersLo[0].IsPresent) { - modifier = (uint64_t) attrs.DMABufPlaneModifiersHi[0].Value << 32; - modifier |= (uint64_t) (attrs.DMABufPlaneModifiersLo[0].Value & 0xffffffff); + modifier = combine_u32_into_u64(attrs.DMABufPlaneModifiersHi[0].Value, + attrs.DMABufPlaneModifiersLo[0].Value); has_modifier = true; } @@ -2623,6 +2622,28 @@ dri2_export_drm_image_mesa(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img, return EGL_TRUE; } +/** + * Checks if we can support EGL_MESA_image_dma_buf_export on this image. + + * The spec provides a boolean return for the driver to reject exporting for + * basically any reason, but doesn't specify any particular error cases. For + * now, we just fail if we don't have a DRM fourcc for the format. + */ +static bool +dri2_can_export_dma_buf_image(_EGLDisplay *disp, _EGLImage *img) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + struct dri2_egl_image *dri2_img = dri2_egl_image(img); + EGLint fourcc; + + if (!dri2_dpy->image->queryImage(dri2_img->dri_image, + __DRI_IMAGE_ATTRIB_FOURCC, &fourcc)) { + return false; + } + + return true; +} + static EGLBoolean dri2_export_dma_buf_image_query_mesa(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img, @@ -2634,6 +2655,8 @@ dri2_export_dma_buf_image_query_mesa(_EGLDriver *drv, _EGLDisplay *disp, (void) drv; + if (!dri2_can_export_dma_buf_image(disp, img)) + return EGL_FALSE; if (nplanes) dri2_dpy->image->queryImage(dri2_img->dri_image, @@ -2657,6 +2680,9 @@ dri2_export_dma_buf_image_mesa(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *im (void) drv; + if (!dri2_can_export_dma_buf_image(disp, img)) + return EGL_FALSE; + /* rework later to provide multiple fds/strides/offsets */ if (fds) dri2_dpy->image->queryImage(dri2_img->dri_image, @@ -3058,6 +3084,17 @@ dri2_dup_native_fence_fd(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync) return dup(sync->SyncFd); } +static void +dri2_set_blob_cache_funcs(_EGLDriver *drv, _EGLDisplay *dpy, + EGLSetBlobFuncANDROID set, + EGLGetBlobFuncANDROID get) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy); + dri2_dpy->blob->set_cache_funcs(dri2_dpy->dri_screen, + dpy->BlobCacheSet, + dpy->BlobCacheGet); +} + static EGLint dri2_client_wait_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, EGLint flags, EGLTime timeout) @@ -3068,10 +3105,6 @@ dri2_client_wait_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, struct dri2_egl_sync *dri2_sync = dri2_egl_sync(sync); unsigned wait_flags = 0; - /* timespecs for cnd_timedwait */ - struct timespec current; - xtime expire; - EGLint ret = EGL_CONDITION_SATISFIED_KHR; /* The EGL_KHR_fence_sync spec states: @@ -3112,19 +3145,25 @@ dri2_client_wait_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, } else { /* if reusable sync has not been yet signaled */ if (dri2_sync->base.SyncStatus != EGL_SIGNALED_KHR) { + /* timespecs for cnd_timedwait */ + struct timespec current; + struct timespec expire; + + /* We override the clock to monotonic when creating the condition + * variable. */ clock_gettime(CLOCK_MONOTONIC, ¤t); /* calculating when to expire */ - expire.nsec = timeout % 1000000000L; - expire.sec = timeout / 1000000000L; + expire.tv_nsec = timeout % 1000000000L; + expire.tv_sec = timeout / 1000000000L; - expire.nsec += current.tv_nsec; - expire.sec += current.tv_sec; + expire.tv_nsec += current.tv_nsec; + expire.tv_sec += current.tv_sec; /* expire.nsec now is a number between 0 and 1999999998 */ - if (expire.nsec > 999999999L) { - expire.sec++; - expire.nsec -= 1000000000L; + if (expire.tv_nsec > 999999999L) { + expire.tv_sec++; + expire.tv_nsec -= 1000000000L; } mtx_lock(&dri2_sync->mutex); @@ -3216,16 +3255,11 @@ dri2_interop_export_object(_EGLDisplay *dpy, _EGLContext *ctx, /** * This is the main entrypoint into the driver, called by libEGL. - * Create a new _EGLDriver object and init its dispatch table. + * Gets an _EGLDriver object and init its dispatch table. */ -_EGLDriver * -_eglBuiltInDriver(void) +void +_eglInitDriver(_EGLDriver *dri2_drv) { - _EGLDriver *dri2_drv = calloc(1, sizeof *dri2_drv); - if (!dri2_drv) - return NULL; - - _eglInitDriverFallbacks(dri2_drv); dri2_drv->API.Initialize = dri2_initialize; dri2_drv->API.Terminate = dri2_terminate; dri2_drv->API.CreateContext = dri2_create_context; @@ -3274,8 +3308,5 @@ _eglBuiltInDriver(void) dri2_drv->API.GLInteropQueryDeviceInfo = dri2_interop_query_device_info; dri2_drv->API.GLInteropExportObject = dri2_interop_export_object; dri2_drv->API.DupNativeFenceFDANDROID = dri2_dup_native_fence_fd; - - dri2_drv->Name = "DRI2"; - - return dri2_drv; + dri2_drv->API.SetBlobCacheFuncsANDROID = dri2_set_blob_cache_funcs; } -- cgit v1.2.3