Implemented internal_wait_sync with release_fence_fd from tpl_surface.
authorJoonbum Ko <joonbum.ko@samsung.com>
Wed, 3 Jun 2020 04:25:41 +0000 (13:25 +0900)
committerXuelian Bai <xuelian.bai@samsung.com>
Tue, 21 Feb 2023 06:32:50 +0000 (14:32 +0800)
Change-Id: Ieb1ddcee8f196e4e7138fc04bbb1fce2547bb92a
Signed-off-by: Joonbum Ko <joonbum.ko@samsung.com>
src/egl/drivers/dri2/platform_tizen.c

index eeb87ed..3792c83 100755 (executable)
@@ -45,6 +45,7 @@
 
 #include "egl_dri2.h"
 #include "loader.h"
+#include "util/u_atomic.h"
 
 #include <wayland-client.h>
 #include <drm-uapi/drm_fourcc.h>
@@ -167,11 +168,66 @@ get_native_buffer_name(tbm_surface_h tbm_surface)
 }
 
 static EGLBoolean
+tizen_internal_wait_sync_for_release_fence(struct dri2_egl_surface *dri2_surf,
+                                           int32_t release_fence_fd)
+{
+   _EGLContext *ctx = _eglGetCurrentContext();
+   _EGLDisplay *disp = dri2_surf->base.Resource.Display;
+
+   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+   struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
+   struct dri2_egl_sync *dri2_sync;
+
+   EGLint attrib_list[] = {
+      EGL_SYNC_NATIVE_FENCE_FD_TIZEN,
+      release_fence_fd,
+      EGL_NONE,
+   };
+
+   dri2_sync = calloc(1, sizeof(struct dri2_egl_sync));
+   if (!dri2_sync) {
+      return EGL_FALSE;
+   }
+
+   if (!_eglInitSync(&dri2_sync->base, disp,
+                     EGL_SYNC_NATIVE_FENCE_TIZEN,
+                     attrib_list)) {
+      free(dri2_sync);
+      return EGL_FALSE;
+   }
+
+   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) {
+      free(dri2_sync);
+      return EGL_FALSE;
+   }
+
+   if (p_atomic_dec_zero(&dri2_sync->refcount)) {
+         close(dri2_sync->base.SyncFd);
+
+         if (dri2_sync->fence)
+            dri2_dpy->fence->destroy_fence(dri2_dpy->dri_screen, dri2_sync->fence);
+         free(dri2_sync);
+   }
+
+   return EGL_TRUE;
+}
+
+static EGLBoolean
 tizen_window_dequeue_buffer(struct dri2_egl_surface *dri2_surf)
 {
    int width, height;
+   int32_t release_fence;
 
-   dri2_surf->tbm_surface = tpl_surface_dequeue_buffer(dri2_surf->tpl_surface);
+   dri2_surf->tbm_surface = tpl_surface_dequeue_buffer_with_sync(
+                              dri2_surf->tpl_surface,
+                              UINT64_MAX,
+                              &release_fence);
 
    if (!dri2_surf->tbm_surface)
      return EGL_FALSE;
@@ -179,6 +235,14 @@ tizen_window_dequeue_buffer(struct dri2_egl_surface *dri2_surf)
    dri2_surf->valid = true;
    tbm_surface_internal_ref(dri2_surf->tbm_surface);
 
+   if (release_fence != -1) {
+      EGLBoolean ret;
+      ret = tizen_internal_wait_sync_for_release_fence(dri2_surf, release_fence);
+      if (!ret) {
+         _eglLog(_EGL_WARNING, "%s : %d : failed to create sync fence.", __func__, __LINE__);
+      }
+   }
+
    tpl_surface_get_size(dri2_surf->tpl_surface, &width, &height);
    if (dri2_surf->base.Width != width ||
        dri2_surf->base.Height != height) {
@@ -1616,6 +1680,7 @@ dri2_initialize_tizen(_EGLDisplay *disp)
    disp->Extensions.TIZEN_image_native_surface = EGL_TRUE;
    disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
    disp->Extensions.WL_create_wayland_buffer_from_image = EGL_FALSE;
+   disp->Extensions.KHR_fence_sync = EGL_TRUE;
 
    if (dri2_dpy->fence->base.version >= 2 &&
        dri2_dpy->fence->get_capabilities) {