void GLAPIENTRY _mesa_DeleteSync(GLsync sync) { GET_CURRENT_CONTEXT(ctx); struct gl_sync_object *const syncObj = (struct gl_sync_object *) sync; ASSERT_OUTSIDE_BEGIN_END(ctx); /* From the GL_ARB_sync spec: * * DeleteSync will silently ignore a <sync> value of zero. An * INVALID_VALUE error is generated if <sync> is neither zero nor the * name of a sync object. */ if (sync == 0) { return; } if (!_mesa_validate_sync(syncObj)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glDeleteSync"); return; } /* If there are no client-waits or server-waits pending on this sync, delete * the underlying object. */ syncObj->DeletePending = GL_TRUE; _mesa_unref_sync_object(ctx, syncObj); }
static void wait_sync(struct gl_context *ctx, struct gl_sync_object *syncObj, GLbitfield flags, GLuint64 timeout) { ctx->Driver.ServerWaitSync(ctx, syncObj, flags, timeout); _mesa_unref_sync_object(ctx, syncObj, 1); }
static GLenum client_wait_sync(struct gl_context *ctx, struct gl_sync_object *syncObj, GLbitfield flags, GLuint64 timeout) { GLenum ret; /* From the GL_ARB_sync spec: * * ClientWaitSync returns one of four status values. A return value of * ALREADY_SIGNALED indicates that <sync> was signaled at the time * ClientWaitSync was called. ALREADY_SIGNALED will always be returned * if <sync> was signaled, even if the value of <timeout> is zero. */ ctx->Driver.CheckSync(ctx, syncObj); if (syncObj->StatusFlag) { ret = GL_ALREADY_SIGNALED; } else { if (timeout == 0) { ret = GL_TIMEOUT_EXPIRED; } else { ctx->Driver.ClientWaitSync(ctx, syncObj, flags, timeout); ret = syncObj->StatusFlag ? GL_CONDITION_SATISFIED : GL_TIMEOUT_EXPIRED; } } _mesa_unref_sync_object(ctx, syncObj, 1); return ret; }
static ALWAYS_INLINE void delete_sync(struct gl_context *ctx, GLsync sync, bool no_error) { struct gl_sync_object *syncObj; /* From the GL_ARB_sync spec: * * DeleteSync will silently ignore a <sync> value of zero. An * INVALID_VALUE error is generated if <sync> is neither zero nor the * name of a sync object. */ if (sync == 0) { return; } syncObj = _mesa_get_and_ref_sync(ctx, sync, true); if (!no_error && !syncObj) { _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteSync (not a valid sync object)"); return; } /* If there are no client-waits or server-waits pending on this sync, delete * the underlying object. Note that we double-unref the object, as * _mesa_get_and_ref_sync above took an extra refcount to make sure the * pointer is valid for us to manipulate. */ syncObj->DeletePending = GL_TRUE; _mesa_unref_sync_object(ctx, syncObj, 2); }
GLenum GLAPIENTRY _mesa_ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) { GET_CURRENT_CONTEXT(ctx); struct gl_sync_object *const syncObj = (struct gl_sync_object *) sync; GLenum ret; ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_WAIT_FAILED); if (!_mesa_validate_sync(syncObj)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glClientWaitSync"); return GL_WAIT_FAILED; } if ((flags & ~GL_SYNC_FLUSH_COMMANDS_BIT) != 0) { _mesa_error(ctx, GL_INVALID_ENUM, "glClientWaitSync(flags=0x%x)", flags); return GL_WAIT_FAILED; } _mesa_ref_sync_object(ctx, syncObj); /* From the GL_ARB_sync spec: * * ClientWaitSync returns one of four status values. A return value of * ALREADY_SIGNALED indicates that <sync> was signaled at the time * ClientWaitSync was called. ALREADY_SIGNALED will always be returned * if <sync> was signaled, even if the value of <timeout> is zero. */ ctx->Driver.CheckSync(ctx, syncObj); if (syncObj->StatusFlag) { ret = GL_ALREADY_SIGNALED; } else { if (timeout == 0) { ret = GL_TIMEOUT_EXPIRED; } else { ctx->Driver.ClientWaitSync(ctx, syncObj, flags, timeout); ret = syncObj->StatusFlag ? GL_CONDITION_SATISFIED : GL_TIMEOUT_EXPIRED; } } _mesa_unref_sync_object(ctx, syncObj); return ret; }
void GLAPIENTRY _mesa_GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values) { GET_CURRENT_CONTEXT(ctx); struct gl_sync_object *syncObj; GLsizei size = 0; GLint v[1]; syncObj = _mesa_get_and_ref_sync(ctx, sync, true); if (!syncObj) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetSynciv (not a valid sync object)"); return; } switch (pname) { case GL_OBJECT_TYPE: v[0] = GL_SYNC_FENCE; size = 1; break; case GL_SYNC_CONDITION: v[0] = syncObj->SyncCondition; size = 1; break; case GL_SYNC_STATUS: /* Update the state of the sync by dipping into the driver. Note that * this call won't block. It just updates state in the common object * data from the current driver state. */ ctx->Driver.CheckSync(ctx, syncObj); v[0] = (syncObj->StatusFlag) ? GL_SIGNALED : GL_UNSIGNALED; size = 1; break; case GL_SYNC_FLAGS: v[0] = syncObj->Flags; size = 1; break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetSynciv(pname=0x%x)\n", pname); _mesa_unref_sync_object(ctx, syncObj, 1); return; } /* Section 4.1.3 (Sync Object Queries) of the OpenGL ES 3.10 spec says: * * "An INVALID_VALUE error is generated if bufSize is negative." */ if (bufSize < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetSynciv(pname=0x%x)\n", pname); } if (size > 0 && bufSize > 0) { const GLsizei copy_count = MIN2(size, bufSize); memcpy(values, v, sizeof(GLint) * copy_count); } if (length != NULL) { *length = size; } _mesa_unref_sync_object(ctx, syncObj, 1); }