Add exception handle for multithread case.
[platform/upstream/mesa.git] / src / egl / drivers / dri2 / egl_dri2.c
index f3a05a4..d04ed54 100644 (file)
@@ -826,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;
@@ -3585,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;
       }
@@ -3676,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,
@@ -3688,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);
@@ -3760,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,
@@ -3795,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,
@@ -4000,5 +4058,6 @@ const _EGLDriver _eglDriver = {
    .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,
 };