i965: replace all dup() with os_dupfd_cloexec()
[mesa.git] / src / mesa / drivers / dri / i965 / brw_sync.c
index 5b78503b34facef6b0bdd2611bd0afa318656ddc..78b18443be61c858eb243205c1fdc4ffab046264 100644 (file)
@@ -40,7 +40,7 @@
 
 #include <libsync.h> /* Requires Android or libdrm-2.4.72 */
 
-#include "main/imports.h"
+#include "util/os_file.h"
 
 #include "brw_context.h"
 #include "intel_batchbuffer.h"
@@ -110,6 +110,35 @@ brw_fence_finish(struct brw_fence *fence)
 static bool MUST_CHECK
 brw_fence_insert_locked(struct brw_context *brw, struct brw_fence *fence)
 {
+   __DRIcontext *driContext = brw->driContext;
+   __DRIdrawable *driDrawable = driContext->driDrawablePriv;
+
+   /*
+    * From KHR_fence_sync:
+    *
+    *   When the condition of the sync object is satisfied by the fence
+    *   command, the sync is signaled by the associated client API context,
+    *   causing any eglClientWaitSyncKHR commands (see below) blocking on
+    *   <sync> to unblock. The only condition currently supported is
+    *   EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR, which is satisfied by
+    *   completion of the fence command corresponding to the sync object,
+    *   and all preceding commands in the associated client API context's
+    *   command stream. The sync object will not be signaled until all
+    *   effects from these commands on the client API's internal and
+    *   framebuffer state are fully realized. No other state is affected by
+    *   execution of the fence command.
+    *
+    * Note the emphasis there on ensuring that the framebuffer is fully
+    * realised before the fence is signaled. We cannot just flush the batch,
+    * but must also resolve the drawable first. The importance of this is,
+    * for example, in creating a fence for a frame to be passed to a
+    * remote compositor. Without us flushing the drawable explicitly, the
+    * resolve will be in a following batch (when the client finally calls
+    * SwapBuffers, or triggers a resolve via some other path) and so the
+    * compositor may read the incomplete framebuffer instead.
+    */
+   if (driDrawable)
+      intel_resolve_for_dri2_flush(brw, driDrawable);
    brw_emit_mi_flush(brw);
 
    switch (fence->type) {
@@ -117,7 +146,7 @@ brw_fence_insert_locked(struct brw_context *brw, struct brw_fence *fence)
       assert(!fence->batch_bo);
       assert(!fence->signalled);
 
-      fence->batch_bo = brw->batch.bo;
+      fence->batch_bo = brw->batch.batch.bo;
       brw_bo_reference(fence->batch_bo);
 
       if (intel_batchbuffer_flush(brw) < 0) {
@@ -308,7 +337,7 @@ brw_fence_server_wait(struct brw_context *brw, struct brw_fence *fence)
 }
 
 static struct gl_sync_object *
-brw_gl_new_sync(struct gl_context *ctx, GLuint id)
+brw_gl_new_sync(struct gl_context *ctx)
 {
    struct brw_gl_sync *sync;
 
@@ -325,6 +354,7 @@ brw_gl_delete_sync(struct gl_context *ctx, struct gl_sync_object *_sync)
    struct brw_gl_sync *sync = (struct brw_gl_sync *) _sync;
 
    brw_fence_finish(&sync->fence);
+   free(sync->gl.Label);
    free(sync);
 }
 
@@ -335,6 +365,9 @@ brw_gl_fence_sync(struct gl_context *ctx, struct gl_sync_object *_sync,
    struct brw_context *brw = brw_context(ctx);
    struct brw_gl_sync *sync = (struct brw_gl_sync *) _sync;
 
+   /* brw_fence_insert_locked() assumes it must do a complete flush */
+   assert(condition == GL_SYNC_GPU_COMMANDS_COMPLETE);
+
    brw_fence_init(brw, &sync->fence, BRW_FENCE_TYPE_BO_WAIT);
 
    if (!brw_fence_insert_locked(brw, &sync->fence)) {
@@ -470,7 +503,7 @@ brw_dri_create_fence_fd(__DRIcontext *dri_ctx, int fd)
          goto fail;
    } else {
       /* Import the sync fd as an in-fence. */
-      fence->sync_fd = fd;
+      fence->sync_fd = os_dupfd_cloexec(fd);
    }
 
    assert(fence->sync_fd != -1);
@@ -487,7 +520,7 @@ static int
 brw_dri_get_fence_fd_locked(struct brw_fence *fence)
 {
    assert(fence->type == BRW_FENCE_TYPE_SYNC_FD);
-   return dup(fence->sync_fd);
+   return os_dupfd_cloexec(fence->sync_fd);
 }
 
 static int