X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fegl%2Fdrivers%2Fdri2%2Fegl_dri2.c;h=d04ed5441c46af57e6d4623dbc4e2f3d99eebf21;hb=27470f329ef9d4b53e13f85af391ba5b42025d43;hp=adc272c7aca6a9814361b30ed2925f9c9868f56c;hpb=7a744aa3180bfbb52405b981d9d528ff511892d9;p=platform%2Fupstream%2Fmesa.git diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index adc272c..d04ed54 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -65,6 +65,7 @@ #include "util/libsync.h" #include "util/os_file.h" #include "util/u_atomic.h" +#include "util/u_call_once.h" #include "util/u_vector.h" #include "mapi/glapi/glapi.h" #include "util/bitscan.h" @@ -133,15 +134,19 @@ dri_set_background_context(void *loaderPrivate) } static void +dri2_gl_flush_get(_glapi_proc *glFlush) +{ + *glFlush = _glapi_get_proc_address("glFlush"); +} + +static void dri2_gl_flush() { static void (*glFlush)(void); - static mtx_t glFlushMutex = _MTX_INITIALIZER_NP; + static util_once_flag once = UTIL_ONCE_FLAG_INIT; - mtx_lock(&glFlushMutex); - if (!glFlush) - glFlush = _glapi_get_proc_address("glFlush"); - mtx_unlock(&glFlushMutex); + util_call_once_data(&once, + (util_call_once_data_func)dri2_gl_flush_get, &glFlush); /* if glFlush is not available things are horribly broken */ if (!glFlush) { @@ -153,12 +158,20 @@ dri2_gl_flush() } static GLboolean -dri_is_thread_safe(void *loaderPrivate) +dri_is_thread_safe(UNUSED void *loaderPrivate) { +#ifdef HAVE_X11_PLATFORM struct dri2_egl_surface *dri2_surf = loaderPrivate; - UNUSED _EGLDisplay *display = dri2_surf->base.Resource.Display; -#ifdef HAVE_X11_PLATFORM + /* loader_dri3_blit_context_get creates a context with + * loaderPrivate being NULL. Enabling glthread for a blitting + * context isn't useful so return false. + */ + if (!loaderPrivate) + return false; + + _EGLDisplay *display = dri2_surf->base.Resource.Display; + Display *xdpy = (Display*)display->PlatformDisplay; /* Check Xlib is running in thread safe mode when running on EGL/X11-xlib @@ -653,12 +666,9 @@ dri2_add_pbuffer_configs_for_visuals(_EGLDisplay *disp) GLboolean dri2_validate_egl_image(void *image, void *data) { - _EGLDisplay *disp = data; - _EGLImage *img; - - egl_lock(disp); - img = _eglLookupImage(image, disp); - egl_unlock(disp); + _EGLDisplay *disp = _eglLockDisplay(data); + _EGLImage *img = _eglLookupImage(image, disp); + _eglUnlockDisplay(disp); if (img == NULL) { _eglError(EGL_BAD_PARAMETER, "dri2_validate_egl_image"); @@ -816,6 +826,13 @@ dri2_load_driver_common(_EGLDisplay *disp, struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); const __DRIextension **extensions; + /*This exception only happen in multithread case, when _eglAtExit is * + *called and disp is freed in main thread. */ + if (dri2_dpy == NULL) { + _eglLog(_EGL_FATAL, "DRI2: disp is freed"); + return EGL_FALSE; + } + extensions = dri2_open_driver(disp); if (!extensions) return EGL_FALSE; @@ -1024,7 +1041,10 @@ dri2_setup_screen(_EGLDisplay *disp) disp->Extensions.EXT_protected_surface = dri2_renderer_query_integer(dri2_dpy, - __DRI2_RENDERER_HAS_PROTECTED_CONTENT); + __DRI2_RENDERER_HAS_PROTECTED_SURFACE); + disp->Extensions.EXT_protected_content = + dri2_renderer_query_integer(dri2_dpy, + __DRI2_RENDERER_HAS_PROTECTED_CONTEXT); } void @@ -1194,6 +1214,12 @@ dri2_initialize(_EGLDisplay *disp) case _EGL_PLATFORM_ANDROID: ret = dri2_initialize_android(disp); break; + +#ifdef HAVE_TIZEN_PLATFORM + case _EGL_PLATFORM_TIZEN: + ret = dri2_initialize_tizen(disp); + break; +#endif default: unreachable("Callers ensure we cannot get here."); return EGL_FALSE; @@ -1269,6 +1295,12 @@ dri2_display_destroy(_EGLDisplay *disp) case _EGL_PLATFORM_WAYLAND: dri2_teardown_wayland(dri2_dpy); break; + +#ifdef HAVE_TIZEN_PLATFORM + case _EGL_PLATFORM_TIZEN: + dri2_teardown_tizen(disp); + break; +#endif default: /* TODO: add teardown for other platforms */ break; @@ -1478,6 +1510,11 @@ dri2_fill_context_attribs(struct dri2_egl_context *dri2_ctx, ctx_attribs[pos++] = true; } + if (dri2_ctx->base.Protected) { + ctx_attribs[pos++] = __DRI_CTX_ATTRIB_PROTECTED; + ctx_attribs[pos++] = true; + } + *num_attribs = pos; return true; @@ -1822,17 +1859,17 @@ dri2_make_current(_EGLDisplay *disp, _EGLSurface *dsurf, old_dri2_dpy->vtbl->set_shared_buffer_mode(old_disp, old_dsurf, false); } - dri2_dpy->core->unbindContext(old_cctx); + old_dri2_dpy->core->unbindContext(old_cctx); if (old_dsurf) - dri2_surf_update_fence_fd(old_ctx, disp, old_dsurf); + dri2_surf_update_fence_fd(old_ctx, old_disp, old_dsurf); } ddraw = (dsurf) ? dri2_dpy->vtbl->get_dri_drawable(dsurf) : NULL; rdraw = (rsurf) ? dri2_dpy->vtbl->get_dri_drawable(rsurf) : NULL; cctx = (dri2_ctx) ? dri2_ctx->dri_context : NULL; - if (cctx || ddraw || rdraw) { + if (cctx) { if (!dri2_dpy->core->bindContext(cctx, ddraw, rdraw)) { _EGLContext *tmp_ctx; @@ -2434,8 +2471,6 @@ dri2_get_sync_values_chromium(_EGLDisplay *disp, _EGLSurface *surf, if (dri2_dpy->vtbl->get_sync_values) ret = dri2_dpy->vtbl->get_sync_values(disp, surf, ust, msc, sbc); - mtx_unlock(&dri2_dpy->lock); - return ret; } @@ -2560,8 +2595,6 @@ dri2_query_surface(_EGLDisplay *disp, _EGLSurface *surf, ret = dri2_dpy->vtbl->query_surface(disp, surf, attribute, value); } - mtx_unlock(&dri2_dpy->lock); - return ret; } @@ -2900,7 +2933,7 @@ dri2_query_dma_buf_modifiers(_EGLDisplay *disp, EGLint format, return dri2_egl_error_unlock(dri2_dpy, EGL_BAD_PARAMETER, "invalid value for max count of formats"); if (max > 0 && modifiers == NULL) - dri2_egl_error_unlock(dri2_dpy, EGL_BAD_PARAMETER, "invalid modifiers array"); + return dri2_egl_error_unlock(dri2_dpy, EGL_BAD_PARAMETER, "invalid modifiers array"); if (dri2_dpy->image->base.version < 15 || dri2_dpy->image->queryDmaBufModifiers == NULL) { @@ -2944,6 +2977,7 @@ dri2_create_image_dma_buf(_EGLDisplay *disp, _EGLContext *ctx, uint64_t modifier; bool has_modifier = false; unsigned error; + EGLint egl_error; /** * The spec says: @@ -3031,7 +3065,10 @@ dri2_create_image_dma_buf(_EGLDisplay *disp, _EGLContext *ctx, &error, NULL); } - dri2_create_image_khr_texture_error(error); + + egl_error = egl_error_from_dri_image_error(error); + if (egl_error != EGL_SUCCESS) + _eglError(egl_error, "createImageFromDmaBufs failed"); if (!dri_image) return EGL_NO_IMAGE_KHR; @@ -3452,6 +3489,94 @@ dri2_query_wayland_buffer_wl(_EGLDisplay *disp, struct wl_resource *buffer_resou } #endif +#ifdef HAVE_TIZEN_PLATFORM +static EGLBoolean +tizen_bind_wayland_display_wl(_EGLDisplay *disp, + struct wl_display *wl_dpy) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + + (void) wl_dpy; + + if (!dri2_dpy->tpl_display) + return EGL_FALSE; + + if (!tpl_display_get_native_handle(dri2_dpy->tpl_display)) + return EGL_FALSE; + + return EGL_TRUE; +} + +static EGLBoolean +tizen_unbind_wayland_display_wl(_EGLDisplay *disp, + struct wl_display *wl_dpy) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + + (void) wl_dpy; + + if (!dri2_dpy->tpl_display) + return EGL_FALSE; + + if (!tpl_display_get_native_handle(dri2_dpy->tpl_display)) + return EGL_FALSE; + + return EGL_TRUE; +} + +static EGLBoolean +tizen_query_wayland_buffer_wl(_EGLDisplay *disp, + struct wl_resource *buffer_resource, + EGLint attribute, EGLint *value) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + tbm_format tbm_format = 0; + int width = 0, height = 0; + tpl_result_t res; + + if (!dri2_dpy->tpl_display) + return EGL_FALSE; + + if (!tpl_display_get_native_handle(dri2_dpy->tpl_display)) + return EGL_FALSE; + + res = tpl_display_get_native_pixmap_info(dri2_dpy->tpl_display, + (tpl_handle_t)buffer_resource, + &width, &height, &tbm_format); + if (res != TPL_ERROR_NONE) + return EGL_FALSE; + + switch (attribute) { + case EGL_TEXTURE_FORMAT: + switch (tbm_format) { + case TBM_FORMAT_ARGB8888: + *value = EGL_TEXTURE_RGBA; + return EGL_TRUE; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wswitch" + case TBM_FORMAT_XRGB8888: + case TBM_FORMAT_RGB565: +#pragma GCC diagnostic pop + *value = EGL_TEXTURE_RGB; + return EGL_TRUE; + default: + break; + } + break; + case EGL_WIDTH: + *value = width; + return EGL_TRUE; + case EGL_HEIGHT: + *value = height; + return EGL_TRUE; + default: + break; + } + + return EGL_FALSE; +} +#endif + static void dri2_egl_ref_sync(struct dri2_egl_sync *sync) { @@ -3467,10 +3592,17 @@ dri2_egl_unref_sync(struct dri2_egl_display *dri2_dpy, case EGL_SYNC_REUSABLE_KHR: cnd_destroy(&dri2_sync->cond); break; +#ifdef HAVE_TIZEN_PLATFORM + case EGL_SYNC_NATIVE_FENCE_TIZEN: + if (dri2_sync->base.SyncFd != EGL_NO_NATIVE_FENCE_FD_TIZEN) + close(dri2_sync->base.SyncFd); + break; +#else case EGL_SYNC_NATIVE_FENCE_ANDROID: if (dri2_sync->base.SyncFd != EGL_NO_NATIVE_FENCE_FD_ANDROID) close(dri2_sync->base.SyncFd); break; +#endif default: break; } @@ -3558,7 +3690,8 @@ dri2_create_sync(_EGLDisplay *disp, EGLenum type, const EGLAttrib *attrib_list) dri2_sync->base.SyncStatus = EGL_UNSIGNALED_KHR; break; - case EGL_SYNC_NATIVE_FENCE_ANDROID: +#ifdef HAVE_TIZEN_PLATFORM + case EGL_SYNC_NATIVE_FENCE_TIZEN: if (dri2_dpy->fence->create_fence_fd) { dri2_sync->fence = dri2_dpy->fence->create_fence_fd( dri2_ctx->dri_context, @@ -3570,6 +3703,20 @@ dri2_create_sync(_EGLDisplay *disp, EGLenum type, const EGLAttrib *attrib_list) } break; } +#else + case EGL_SYNC_NATIVE_FENCE_ANDROID: + if (dri2_dpy->fence->create_fence_fd) { + dri2_sync->fence = dri2_dpy->fence->create_fence_fd( + dri2_ctx->dri_context, + dri2_sync->base.SyncFd); + } + if (!dri2_sync->fence) { + _eglError(EGL_BAD_ATTRIBUTE, "eglCreateSyncKHR"); + free(dri2_sync); + return NULL; + } + break; +#endif p_atomic_set(&dri2_sync->refcount, 1); mtx_unlock(&dri2_dpy->lock); @@ -3642,6 +3789,31 @@ dri2_dup_native_fence_fd(_EGLDisplay *disp, _EGLSync *sync) return os_dupfd_cloexec(sync->SyncFd); } +static EGLint +dri2_dup_native_fence_fd_tizen(_EGLDisplay *dpy, _EGLSync *sync) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy); + struct dri2_egl_sync *dri2_sync = dri2_egl_sync(sync); + + assert(sync->Type == EGL_SYNC_NATIVE_FENCE_TIZEN); + + if (sync->SyncFd == EGL_NO_NATIVE_FENCE_FD_TIZEN) { + /* try to retrieve the actual native fence fd.. if rendering is + * not flushed this will just return -1, aka NO_NATIVE_FENCE_FD: + */ + sync->SyncFd = dri2_dpy->fence->get_fence_fd(dri2_dpy->dri_screen, + dri2_sync->fence); + } + + if (sync->SyncFd == EGL_NO_NATIVE_FENCE_FD_TIZEN) { + /* if native fence fd still not created, return an error: */ + _eglError(EGL_BAD_PARAMETER, "eglDupNativeFenceFDTIZEN"); + return EGL_NO_NATIVE_FENCE_FD_TIZEN; + } + + return dup(sync->SyncFd); +} + static void dri2_set_blob_cache_funcs(_EGLDisplay *disp, EGLSetBlobFuncANDROID set, @@ -3677,7 +3849,11 @@ dri2_client_wait_sync(_EGLDisplay *disp, _EGLSync *sync, switch (sync->Type) { case EGL_SYNC_FENCE_KHR: +#ifdef HAVE_TIZEN_PLATFORM + case EGL_SYNC_NATIVE_FENCE_TIZEN: +#else case EGL_SYNC_NATIVE_FENCE_ANDROID: +#endif case EGL_SYNC_CL_EVENT_KHR: if (dri2_dpy->fence->client_wait_sync(dri2_ctx ? dri2_ctx->dri_context : NULL, dri2_sync->fence, wait_flags, @@ -3810,6 +3986,20 @@ dri2_interop_export_object(_EGLDisplay *disp, _EGLContext *ctx, return dri2_dpy->interop->export_object(dri2_ctx->dri_context, in, out); } +static int +dri2_interop_flush_objects(_EGLDisplay *disp, _EGLContext *ctx, + unsigned count, struct mesa_glinterop_export_in *objects, + GLsync *sync) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); + + if (!dri2_dpy->interop || dri2_dpy->interop->base.version < 2) + return MESA_GLINTEROP_UNSUPPORTED; + + return dri2_dpy->interop->flush_objects(dri2_ctx->dri_context, count, objects, sync); +} + const _EGLDriver _eglDriver = { .Initialize = dri2_initialize, .Terminate = dri2_terminate, @@ -3852,6 +4042,11 @@ const _EGLDriver _eglDriver = { .UnbindWaylandDisplayWL = dri2_unbind_wayland_display_wl, .QueryWaylandBufferWL = dri2_query_wayland_buffer_wl, #endif +#ifdef HAVE_TIZEN_PLATFORM + .BindWaylandDisplayWL = tizen_bind_wayland_display_wl, + .UnbindWaylandDisplayWL = tizen_unbind_wayland_display_wl, + .QueryWaylandBufferWL = tizen_query_wayland_buffer_wl, + #endif .GetSyncValuesCHROMIUM = dri2_get_sync_values_chromium, .GetMscRateANGLE = dri2_get_msc_rate_angle, .CreateSyncKHR = dri2_create_sync, @@ -3861,6 +4056,8 @@ const _EGLDriver _eglDriver = { .DestroySyncKHR = dri2_destroy_sync, .GLInteropQueryDeviceInfo = dri2_interop_query_device_info, .GLInteropExportObject = dri2_interop_export_object, + .GLInteropFlushObjects = dri2_interop_flush_objects, .DupNativeFenceFDANDROID = dri2_dup_native_fence_fd, + .DupNativeFenceFDTIZEN = dri2_dup_native_fence_fd_tizen, .SetBlobCacheFuncsANDROID = dri2_set_blob_cache_funcs, };