Add fence API
cogl_framebuffer_add_fence creates a synchronisation fence, which will invoke a user-specified callback when the GPU has finished executing all commands provided to it up to that point in time. Support is currently provided for GL 3.x's GL_ARB_sync extension, and EGL's EGL_KHR_fence_sync (when used with OpenGL ES). Signed-off-by: Daniel Stone <daniel@fooishbar.org> Reviewed-by: Neil Roberts <neil@linux.intel.com> Reviewed-by: Robert Bragg <robert@linux.intel.com> https://bugzilla.gnome.org/show_bug.cgi?id=691752 (cherry picked from commit e6d37470da9294adc1554c0a8c91aa2af560ed9f)
This commit is contained in:
parent
7b14b5e3da
commit
ea7d3b8476
@ -133,6 +133,7 @@ cogl_experimental_h = \
|
|||||||
$(srcdir)/cogl2-experimental.h \
|
$(srcdir)/cogl2-experimental.h \
|
||||||
$(srcdir)/cogl2-compatibility.h \
|
$(srcdir)/cogl2-compatibility.h \
|
||||||
$(srcdir)/cogl-macros.h \
|
$(srcdir)/cogl-macros.h \
|
||||||
|
$(srcdir)/cogl-fence.h \
|
||||||
$(srcdir)/cogl-version.h \
|
$(srcdir)/cogl-version.h \
|
||||||
$(srcdir)/cogl-error.h \
|
$(srcdir)/cogl-error.h \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
@ -437,6 +438,8 @@ cogl_sources_c = \
|
|||||||
$(srcdir)/cogl-error.c \
|
$(srcdir)/cogl-error.c \
|
||||||
$(srcdir)/cogl-closure-list-private.h \
|
$(srcdir)/cogl-closure-list-private.h \
|
||||||
$(srcdir)/cogl-closure-list.c \
|
$(srcdir)/cogl-closure-list.c \
|
||||||
|
$(srcdir)/cogl-fence.c \
|
||||||
|
$(srcdir)/cogl-fence-private.h \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
if USE_GLIB
|
if USE_GLIB
|
||||||
|
@ -51,6 +51,8 @@
|
|||||||
#include "cogl-gl-header.h"
|
#include "cogl-gl-header.h"
|
||||||
#include "cogl-framebuffer-private.h"
|
#include "cogl-framebuffer-private.h"
|
||||||
#include "cogl-onscreen-private.h"
|
#include "cogl-onscreen-private.h"
|
||||||
|
#include "cogl-fence-private.h"
|
||||||
|
#include "cogl-poll-private.h"
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -306,6 +308,9 @@ struct _CoglContext
|
|||||||
GHashTable *uniform_name_hash;
|
GHashTable *uniform_name_hash;
|
||||||
int n_uniform_names;
|
int n_uniform_names;
|
||||||
|
|
||||||
|
CoglPollSource *fences_poll_source;
|
||||||
|
CoglFenceList fences;
|
||||||
|
|
||||||
/* This defines a list of function pointers that Cogl uses from
|
/* This defines a list of function pointers that Cogl uses from
|
||||||
either GL or GLES. All functions are accessed indirectly through
|
either GL or GLES. All functions are accessed indirectly through
|
||||||
these pointers rather than linking to them directly */
|
these pointers rather than linking to them directly */
|
||||||
|
@ -477,6 +477,8 @@ cogl_context_new (CoglDisplay *display,
|
|||||||
cogl_has_feature (context, COGL_FEATURE_ID_POINT_SPRITE))
|
cogl_has_feature (context, COGL_FEATURE_ID_POINT_SPRITE))
|
||||||
GE (context, glEnable (GL_POINT_SPRITE));
|
GE (context, glEnable (GL_POINT_SPRITE));
|
||||||
|
|
||||||
|
COGL_TAILQ_INIT (&context->fences);
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,6 +259,7 @@ typedef enum _CoglFeatureID
|
|||||||
COGL_FEATURE_ID_GLES2_CONTEXT,
|
COGL_FEATURE_ID_GLES2_CONTEXT,
|
||||||
COGL_FEATURE_ID_DEPTH_TEXTURE,
|
COGL_FEATURE_ID_DEPTH_TEXTURE,
|
||||||
COGL_FEATURE_ID_PRESENTATION_TIME,
|
COGL_FEATURE_ID_PRESENTATION_TIME,
|
||||||
|
COGL_FEATURE_ID_FENCE,
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
_COGL_N_FEATURE_IDS /*< skip >*/
|
_COGL_N_FEATURE_IDS /*< skip >*/
|
||||||
|
61
cogl/cogl-fence-private.h
Normal file
61
cogl/cogl-fence-private.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Cogl
|
||||||
|
*
|
||||||
|
* An object oriented GL/GLES Abstraction/Utility Layer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Collabora Ltd.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __COGL_FENCE_PRIVATE_H__
|
||||||
|
#define __COGL_FENCE_PRIVATE_H__
|
||||||
|
|
||||||
|
#include "cogl-fence.h"
|
||||||
|
#include "cogl-queue.h"
|
||||||
|
#include "cogl-winsys-private.h"
|
||||||
|
|
||||||
|
COGL_TAILQ_HEAD (CoglFenceList, CoglFenceClosure);
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
FENCE_TYPE_PENDING,
|
||||||
|
#ifdef GL_ARB_sync
|
||||||
|
FENCE_TYPE_GL_ARB,
|
||||||
|
#endif
|
||||||
|
FENCE_TYPE_WINSYS,
|
||||||
|
FENCE_TYPE_ERROR
|
||||||
|
} CoglFenceType;
|
||||||
|
|
||||||
|
struct _CoglFenceClosure
|
||||||
|
{
|
||||||
|
COGL_TAILQ_ENTRY (CoglFenceClosure) list;
|
||||||
|
CoglFramebuffer *framebuffer;
|
||||||
|
|
||||||
|
CoglFenceType type;
|
||||||
|
void *fence_obj;
|
||||||
|
|
||||||
|
CoglFenceCallback callback;
|
||||||
|
void *user_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_fence_submit (CoglFenceClosure *fence);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_fence_cancel_fences_for_framebuffer (CoglFramebuffer *framebuffer);
|
||||||
|
|
||||||
|
#endif /* __COGL_FENCE_PRIVATE_H__ */
|
228
cogl/cogl-fence.c
Normal file
228
cogl/cogl-fence.c
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
/*
|
||||||
|
* Cogl
|
||||||
|
*
|
||||||
|
* An object oriented GL/GLES Abstraction/Utility Layer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Collabora Ltd.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "cogl-fence.h"
|
||||||
|
#include "cogl-fence-private.h"
|
||||||
|
#include "cogl-context-private.h"
|
||||||
|
#include "cogl-winsys-private.h"
|
||||||
|
|
||||||
|
#define FENCE_CHECK_TIMEOUT 5000 /* microseconds */
|
||||||
|
|
||||||
|
void *
|
||||||
|
cogl_fence_closure_get_user_data (CoglFenceClosure *closure)
|
||||||
|
{
|
||||||
|
return closure->user_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cogl_fence_check (CoglFenceClosure *fence)
|
||||||
|
{
|
||||||
|
CoglContext *context = fence->framebuffer->context;
|
||||||
|
|
||||||
|
if (fence->type == FENCE_TYPE_WINSYS)
|
||||||
|
{
|
||||||
|
const CoglWinsysVtable *winsys = _cogl_context_get_winsys (context);
|
||||||
|
CoglBool ret;
|
||||||
|
|
||||||
|
ret = winsys->fence_is_complete (context, fence->fence_obj);
|
||||||
|
if (!ret)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#ifdef GL_ARB_sync
|
||||||
|
else if (fence->type == FENCE_TYPE_GL_ARB)
|
||||||
|
{
|
||||||
|
GLenum arb;
|
||||||
|
|
||||||
|
arb = context->glClientWaitSync (fence->fence_obj,
|
||||||
|
GL_SYNC_FLUSH_COMMANDS_BIT,
|
||||||
|
0);
|
||||||
|
if (arb != GL_ALREADY_SIGNALED && arb != GL_CONDITION_SATISFIED)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fence->callback (NULL, /* dummy CoglFence object */
|
||||||
|
fence->user_data);
|
||||||
|
cogl_framebuffer_cancel_fence_callback (fence->framebuffer, fence);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cogl_fence_poll_dispatch (void *source, int revents)
|
||||||
|
{
|
||||||
|
CoglContext *context = source;
|
||||||
|
CoglFenceClosure *fence, *next;
|
||||||
|
|
||||||
|
COGL_TAILQ_FOREACH_SAFE (fence, &context->fences, list, next)
|
||||||
|
_cogl_fence_check (fence);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64_t
|
||||||
|
_cogl_fence_poll_prepare (void *source)
|
||||||
|
{
|
||||||
|
CoglContext *context = source;
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
/* If there are any pending fences in any of the journals then we
|
||||||
|
* need to flush the journal otherwise the fence will never be
|
||||||
|
* hit and the main loop might block forever */
|
||||||
|
for (l = context->framebuffers; l; l = l->next)
|
||||||
|
{
|
||||||
|
CoglFramebuffer *fb = l->data;
|
||||||
|
|
||||||
|
if (!COGL_TAILQ_EMPTY (&fb->journal->pending_fences))
|
||||||
|
_cogl_framebuffer_flush_journal (fb);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!COGL_TAILQ_EMPTY (&context->fences))
|
||||||
|
return FENCE_CHECK_TIMEOUT;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_fence_submit (CoglFenceClosure *fence)
|
||||||
|
{
|
||||||
|
CoglContext *context = fence->framebuffer->context;
|
||||||
|
const CoglWinsysVtable *winsys = _cogl_context_get_winsys (context);
|
||||||
|
|
||||||
|
fence->type = FENCE_TYPE_ERROR;
|
||||||
|
|
||||||
|
if (winsys->fence_add)
|
||||||
|
{
|
||||||
|
fence->fence_obj = winsys->fence_add (context);
|
||||||
|
if (fence->fence_obj)
|
||||||
|
{
|
||||||
|
fence->type = FENCE_TYPE_WINSYS;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef GL_ARB_sync
|
||||||
|
if (context->glFenceSync)
|
||||||
|
{
|
||||||
|
fence->fence_obj = context->glFenceSync (GL_SYNC_GPU_COMMANDS_COMPLETE,
|
||||||
|
0);
|
||||||
|
if (fence->fence_obj)
|
||||||
|
{
|
||||||
|
fence->type = FENCE_TYPE_GL_ARB;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
done:
|
||||||
|
COGL_TAILQ_INSERT_TAIL (&context->fences, fence, list);
|
||||||
|
|
||||||
|
if (!context->fences_poll_source)
|
||||||
|
{
|
||||||
|
context->fences_poll_source =
|
||||||
|
_cogl_poll_renderer_add_source (context->display->renderer,
|
||||||
|
_cogl_fence_poll_prepare,
|
||||||
|
_cogl_fence_poll_dispatch,
|
||||||
|
context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CoglFenceClosure *
|
||||||
|
cogl_framebuffer_add_fence_callback (CoglFramebuffer *framebuffer,
|
||||||
|
CoglFenceCallback callback,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
CoglContext *context = framebuffer->context;
|
||||||
|
CoglJournal *journal = framebuffer->journal;
|
||||||
|
CoglFenceClosure *fence;
|
||||||
|
|
||||||
|
if (!COGL_FLAGS_GET (context->features, COGL_FEATURE_ID_FENCE))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
fence = g_slice_new (CoglFenceClosure);
|
||||||
|
fence->framebuffer = framebuffer;
|
||||||
|
fence->callback = callback;
|
||||||
|
fence->user_data = user_data;
|
||||||
|
fence->fence_obj = NULL;
|
||||||
|
|
||||||
|
if (journal->entries->len)
|
||||||
|
{
|
||||||
|
COGL_TAILQ_INSERT_TAIL (&journal->pending_fences, fence, list);
|
||||||
|
fence->type = FENCE_TYPE_PENDING;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_cogl_fence_submit (fence);
|
||||||
|
|
||||||
|
return fence;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_framebuffer_cancel_fence_callback (CoglFramebuffer *framebuffer,
|
||||||
|
CoglFenceClosure *fence)
|
||||||
|
{
|
||||||
|
CoglJournal *journal = framebuffer->journal;
|
||||||
|
CoglContext *context = framebuffer->context;
|
||||||
|
|
||||||
|
if (fence->type == FENCE_TYPE_PENDING)
|
||||||
|
{
|
||||||
|
COGL_TAILQ_REMOVE (&journal->pending_fences, fence, list);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
COGL_TAILQ_REMOVE (&context->fences, fence, list);
|
||||||
|
|
||||||
|
if (fence->type == FENCE_TYPE_WINSYS)
|
||||||
|
{
|
||||||
|
const CoglWinsysVtable *winsys = _cogl_context_get_winsys (context);
|
||||||
|
|
||||||
|
winsys->fence_destroy (context, fence->fence_obj);
|
||||||
|
}
|
||||||
|
#ifdef GL_ARB_sync
|
||||||
|
else if (fence->type == FENCE_TYPE_GL_ARB)
|
||||||
|
{
|
||||||
|
context->glDeleteSync (fence->fence_obj);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
g_slice_free (CoglFenceClosure, fence);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_fence_cancel_fences_for_framebuffer (CoglFramebuffer *framebuffer)
|
||||||
|
{
|
||||||
|
CoglJournal *journal = framebuffer->journal;
|
||||||
|
CoglContext *context = framebuffer->context;
|
||||||
|
CoglFenceClosure *fence, *next;
|
||||||
|
|
||||||
|
while (!COGL_TAILQ_EMPTY (&journal->pending_fences))
|
||||||
|
{
|
||||||
|
fence = COGL_TAILQ_FIRST (&journal->pending_fences);
|
||||||
|
cogl_framebuffer_cancel_fence_callback (framebuffer, fence);
|
||||||
|
}
|
||||||
|
|
||||||
|
COGL_TAILQ_FOREACH_SAFE (fence, &context->fences, list, next)
|
||||||
|
{
|
||||||
|
if (fence->framebuffer == framebuffer)
|
||||||
|
cogl_framebuffer_cancel_fence_callback (framebuffer, fence);
|
||||||
|
}
|
||||||
|
}
|
136
cogl/cogl-fence.h
Normal file
136
cogl/cogl-fence.h
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
/*
|
||||||
|
* Cogl
|
||||||
|
*
|
||||||
|
* An object oriented GL/GLES Abstraction/Utility Layer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Collabora Ltd.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION)
|
||||||
|
#error "Only <cogl/cogl.h> can be included directly."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __COGL_FENCE_H__
|
||||||
|
#define __COGL_FENCE_H__
|
||||||
|
|
||||||
|
#include <cogl/cogl-types.h>
|
||||||
|
#include <cogl/cogl-framebuffer.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION:cogl-fence
|
||||||
|
* @short_description: Functions for notification of command completion
|
||||||
|
*
|
||||||
|
* Cogl allows notification of GPU command completion; users may mark
|
||||||
|
* points in the GPU command stream and receive notification when the GPU
|
||||||
|
* has executed to that point.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CoglFence:
|
||||||
|
*
|
||||||
|
* An opaque object representing a fence. This type is currently
|
||||||
|
* unused but in the future may be used to pass extra information
|
||||||
|
* about the fence completion.
|
||||||
|
*
|
||||||
|
* Since: 2.0
|
||||||
|
* Stability: Unstable
|
||||||
|
*/
|
||||||
|
typedef struct _CoglFence CoglFence;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CoglFenceCallback:
|
||||||
|
* @fence: Unused. In the future this parameter may be used to pass
|
||||||
|
* extra information about the fence completion but for now it
|
||||||
|
* should be ignored.
|
||||||
|
* @user_data: The private data passed to cogl_framebuffer_add_fence_callback()
|
||||||
|
*
|
||||||
|
* The callback prototype used with
|
||||||
|
* cogl_framebuffer_add_fence_callback() for notification of GPU
|
||||||
|
* command completion.
|
||||||
|
*
|
||||||
|
* Since: 2.0
|
||||||
|
* Stability: Unstable
|
||||||
|
*/
|
||||||
|
typedef void (* CoglFenceCallback) (CoglFence *fence,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CoglFenceClosure:
|
||||||
|
*
|
||||||
|
* An opaque type representing one future callback to be made when the
|
||||||
|
* GPU command stream has passed a certain point.
|
||||||
|
*
|
||||||
|
* Since: 2.0
|
||||||
|
* Stability: Unstable
|
||||||
|
*/
|
||||||
|
typedef struct _CoglFenceClosure CoglFenceClosure;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_frame_closure_get_user_data:
|
||||||
|
* @closure: A #CoglFenceClosure returned from cogl_framebuffer_add_fence()
|
||||||
|
*
|
||||||
|
* Returns the user_data submitted to cogl_framebuffer_add_fence() which
|
||||||
|
* returned a given #CoglFenceClosure.
|
||||||
|
*
|
||||||
|
* Since: 2.0
|
||||||
|
* Stability: Unstable
|
||||||
|
*/
|
||||||
|
void *
|
||||||
|
cogl_fence_closure_get_user_data (CoglFenceClosure *closure);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_framebuffer_add_fence_callback:
|
||||||
|
* @framebuffer: The #CoglFramebuffer the commands have been submitted to
|
||||||
|
* @callback: A #CoglFenceCallback to be called when all commands submitted
|
||||||
|
* to Cogl have been executed
|
||||||
|
* @user_data: Private data that will be passed to the callback
|
||||||
|
*
|
||||||
|
* Calls the provided callback when all previously-submitted commands have
|
||||||
|
* been executed by the GPU.
|
||||||
|
*
|
||||||
|
* Returns non-NULL if the fence succeeded, or %NULL if it was unable to
|
||||||
|
* be inserted and the callback will never be called. The user does not
|
||||||
|
* need to free the closure; it will be freed automatically when the
|
||||||
|
* callback is called, or cancelled.
|
||||||
|
*
|
||||||
|
* Since: 2.0
|
||||||
|
* Stability: Unstable
|
||||||
|
*/
|
||||||
|
CoglFenceClosure *
|
||||||
|
cogl_framebuffer_add_fence_callback (CoglFramebuffer *framebuffer,
|
||||||
|
CoglFenceCallback callback,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_framebuffer_cancel_fence_callback:
|
||||||
|
* @framebuffer: The #CoglFramebuffer the commands were submitted to
|
||||||
|
* @closure: The #CoglFenceClosure returned from
|
||||||
|
* cogl_framebuffer_add_fence_callback()
|
||||||
|
*
|
||||||
|
* Removes a fence previously submitted with
|
||||||
|
* cogl_framebuffer_add_fence_callback(); the callback will not be
|
||||||
|
* called.
|
||||||
|
*
|
||||||
|
* Since: 2.0
|
||||||
|
* Stability: Unstable
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
cogl_framebuffer_cancel_fence_callback (CoglFramebuffer *framebuffer,
|
||||||
|
CoglFenceClosure *closure);
|
||||||
|
|
||||||
|
#endif /* __COGL_FENCE_H__ */
|
@ -171,6 +171,8 @@ _cogl_framebuffer_free (CoglFramebuffer *framebuffer)
|
|||||||
{
|
{
|
||||||
CoglContext *ctx = framebuffer->context;
|
CoglContext *ctx = framebuffer->context;
|
||||||
|
|
||||||
|
_cogl_fence_cancel_fences_for_framebuffer (framebuffer);
|
||||||
|
|
||||||
_cogl_clip_state_destroy (&framebuffer->clip_state);
|
_cogl_clip_state_destroy (&framebuffer->clip_state);
|
||||||
|
|
||||||
cogl_object_unref (framebuffer->modelview_stack);
|
cogl_object_unref (framebuffer->modelview_stack);
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "cogl-texture.h"
|
#include "cogl-texture.h"
|
||||||
#include "cogl-object-private.h"
|
#include "cogl-object-private.h"
|
||||||
#include "cogl-clip-stack.h"
|
#include "cogl-clip-stack.h"
|
||||||
|
#include "cogl-fence-private.h"
|
||||||
|
|
||||||
#define COGL_JOURNAL_VBO_POOL_SIZE 8
|
#define COGL_JOURNAL_VBO_POOL_SIZE 8
|
||||||
|
|
||||||
@ -58,6 +59,8 @@ typedef struct _CoglJournal
|
|||||||
|
|
||||||
int fast_read_pixel_count;
|
int fast_read_pixel_count;
|
||||||
|
|
||||||
|
CoglFenceList pending_fences;
|
||||||
|
|
||||||
} CoglJournal;
|
} CoglJournal;
|
||||||
|
|
||||||
/* To improve batching of geometry when submitting vertices to OpenGL we
|
/* To improve batching of geometry when submitting vertices to OpenGL we
|
||||||
|
@ -154,6 +154,8 @@ _cogl_journal_new (CoglFramebuffer *framebuffer)
|
|||||||
journal->entries = g_array_new (FALSE, FALSE, sizeof (CoglJournalEntry));
|
journal->entries = g_array_new (FALSE, FALSE, sizeof (CoglJournalEntry));
|
||||||
journal->vertices = g_array_new (FALSE, FALSE, sizeof (float));
|
journal->vertices = g_array_new (FALSE, FALSE, sizeof (float));
|
||||||
|
|
||||||
|
COGL_TAILQ_INIT (&journal->pending_fences);
|
||||||
|
|
||||||
return _cogl_journal_object_new (journal);
|
return _cogl_journal_object_new (journal);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1267,6 +1269,18 @@ _cogl_journal_all_entries_within_bounds (CoglJournal *journal,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
post_fences (CoglJournal *journal)
|
||||||
|
{
|
||||||
|
CoglFenceClosure *fence, *next;
|
||||||
|
|
||||||
|
COGL_TAILQ_FOREACH_SAFE (fence, &journal->pending_fences, list, next)
|
||||||
|
{
|
||||||
|
COGL_TAILQ_REMOVE (&journal->pending_fences, fence, list);
|
||||||
|
_cogl_fence_submit (fence);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* XXX NB: When _cogl_journal_flush() returns all state relating
|
/* XXX NB: When _cogl_journal_flush() returns all state relating
|
||||||
* to pipelines, all glEnable flags and current matrix state
|
* to pipelines, all glEnable flags and current matrix state
|
||||||
* is undefined.
|
* is undefined.
|
||||||
@ -1290,7 +1304,10 @@ _cogl_journal_flush (CoglJournal *journal)
|
|||||||
0 /* no application private data */);
|
0 /* no application private data */);
|
||||||
|
|
||||||
if (journal->entries->len == 0)
|
if (journal->entries->len == 0)
|
||||||
|
{
|
||||||
|
post_fences (journal);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
framebuffer = journal->framebuffer;
|
framebuffer = journal->framebuffer;
|
||||||
ctx = framebuffer->context;
|
ctx = framebuffer->context;
|
||||||
@ -1388,6 +1405,8 @@ _cogl_journal_flush (CoglJournal *journal)
|
|||||||
_cogl_journal_discard (journal);
|
_cogl_journal_discard (journal);
|
||||||
COGL_TIMER_STOP (_cogl_uprof_context, discard_timer);
|
COGL_TIMER_STOP (_cogl_uprof_context, discard_timer);
|
||||||
|
|
||||||
|
post_fences (journal);
|
||||||
|
|
||||||
COGL_TIMER_STOP (_cogl_uprof_context, flush_timer);
|
COGL_TIMER_STOP (_cogl_uprof_context, flush_timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +56,8 @@ typedef enum
|
|||||||
COGL_PRIVATE_FEATURE_QUERY_TEXTURE_PARAMETERS = 1L<<20,
|
COGL_PRIVATE_FEATURE_QUERY_TEXTURE_PARAMETERS = 1L<<20,
|
||||||
COGL_PRIVATE_FEATURE_ALPHA_TEXTURES = 1L<<21,
|
COGL_PRIVATE_FEATURE_ALPHA_TEXTURES = 1L<<21,
|
||||||
COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE = 1L<<22,
|
COGL_PRIVATE_FEATURE_TEXTURE_SWIZZLE = 1L<<22,
|
||||||
COGL_PRIVATE_FEATURE_TEXTURE_MAX_LEVEL = 1L<<23
|
COGL_PRIVATE_FEATURE_TEXTURE_MAX_LEVEL = 1L<<23,
|
||||||
|
COGL_PRIVATE_FEATURE_OES_EGL_SYNC = 1L<<24
|
||||||
} CoglPrivateFeatureFlags;
|
} CoglPrivateFeatureFlags;
|
||||||
|
|
||||||
/* Sometimes when evaluating pipelines, either during comparisons or
|
/* Sometimes when evaluating pipelines, either during comparisons or
|
||||||
|
@ -109,6 +109,7 @@
|
|||||||
#include <cogl/cogl-onscreen.h>
|
#include <cogl/cogl-onscreen.h>
|
||||||
#include <cogl/cogl-frame-info.h>
|
#include <cogl/cogl-frame-info.h>
|
||||||
#include <cogl/cogl-poll.h>
|
#include <cogl/cogl-poll.h>
|
||||||
|
#include <cogl/cogl-fence.h>
|
||||||
#if defined (COGL_HAS_EGL_PLATFORM_KMS_SUPPORT)
|
#if defined (COGL_HAS_EGL_PLATFORM_KMS_SUPPORT)
|
||||||
#include <cogl/cogl-kms-renderer.h>
|
#include <cogl/cogl-kms-renderer.h>
|
||||||
#include <cogl/cogl-kms-display.h>
|
#include <cogl/cogl-kms-display.h>
|
||||||
|
@ -981,3 +981,7 @@ _cogl_atlas_texture_new_with_size
|
|||||||
_cogl_atlas_texture_remove_reorganize_callback
|
_cogl_atlas_texture_remove_reorganize_callback
|
||||||
_cogl_context_get_default
|
_cogl_context_get_default
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
cogl_fence_closure_get_user_data
|
||||||
|
cogl_framebuffer_add_fence_callback
|
||||||
|
cogl_framebuffer_cancel_fence_callback
|
||||||
|
@ -597,6 +597,9 @@ _cogl_driver_update_features (CoglContext *ctx,
|
|||||||
COGL_PRIVATE_FEATURE_QUERY_TEXTURE_PARAMETERS |
|
COGL_PRIVATE_FEATURE_QUERY_TEXTURE_PARAMETERS |
|
||||||
COGL_PRIVATE_FEATURE_TEXTURE_MAX_LEVEL);
|
COGL_PRIVATE_FEATURE_TEXTURE_MAX_LEVEL);
|
||||||
|
|
||||||
|
if (ctx->glFenceSync)
|
||||||
|
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_FENCE, TRUE);
|
||||||
|
|
||||||
/* Cache features */
|
/* Cache features */
|
||||||
ctx->private_feature_flags |= private_flags;
|
ctx->private_feature_flags |= private_flags;
|
||||||
ctx->feature_flags |= flags;
|
ctx->feature_flags |= flags;
|
||||||
|
@ -346,6 +346,12 @@ _cogl_driver_update_features (CoglContext *context,
|
|||||||
if (_cogl_check_extension ("GL_EXT_unpack_subimage", gl_extensions))
|
if (_cogl_check_extension ("GL_EXT_unpack_subimage", gl_extensions))
|
||||||
private_flags |= COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE;
|
private_flags |= COGL_PRIVATE_FEATURE_UNPACK_SUBIMAGE;
|
||||||
|
|
||||||
|
/* A nameless vendor implemented the extension, but got the case wrong
|
||||||
|
* per the spec. */
|
||||||
|
if (_cogl_check_extension ("GL_OES_EGL_sync", gl_extensions) ||
|
||||||
|
_cogl_check_extension ("GL_OES_egl_sync", gl_extensions))
|
||||||
|
private_flags |= COGL_PRIVATE_FEATURE_OES_EGL_SYNC;
|
||||||
|
|
||||||
/* Cache features */
|
/* Cache features */
|
||||||
context->private_feature_flags |= private_flags;
|
context->private_feature_flags |= private_flags;
|
||||||
context->feature_flags |= flags;
|
context->feature_flags |= flags;
|
||||||
|
@ -297,3 +297,15 @@ COGL_EXT_FUNCTION (GLvoid *, glMapBufferRange,
|
|||||||
GLsizeiptr length,
|
GLsizeiptr length,
|
||||||
GLbitfield access))
|
GLbitfield access))
|
||||||
COGL_EXT_END ()
|
COGL_EXT_END ()
|
||||||
|
|
||||||
|
COGL_EXT_BEGIN (sync, 3, 2,
|
||||||
|
0, /* not in either GLES */
|
||||||
|
"ARB:\0",
|
||||||
|
"sync\0")
|
||||||
|
COGL_EXT_FUNCTION (GLsync, glFenceSync,
|
||||||
|
(GLenum condition, GLbitfield flags))
|
||||||
|
COGL_EXT_FUNCTION (GLenum, glClientWaitSync,
|
||||||
|
(GLsync sync, GLbitfield flags, GLuint64 timeout))
|
||||||
|
COGL_EXT_FUNCTION (void, glDeleteSync,
|
||||||
|
(GLsync sync))
|
||||||
|
COGL_EXT_END ()
|
||||||
|
@ -112,3 +112,23 @@ COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglSwapBuffersWithDamage,
|
|||||||
const EGLint *rects,
|
const EGLint *rects,
|
||||||
EGLint n_rects))
|
EGLint n_rects))
|
||||||
COGL_WINSYS_FEATURE_END ()
|
COGL_WINSYS_FEATURE_END ()
|
||||||
|
|
||||||
|
#if defined(EGL_KHR_fence_sync) || defined(EGL_KHR_reusable_sync)
|
||||||
|
COGL_WINSYS_FEATURE_BEGIN (fence_sync,
|
||||||
|
"KHR\0",
|
||||||
|
"fence_sync\0",
|
||||||
|
COGL_EGL_WINSYS_FEATURE_FENCE_SYNC)
|
||||||
|
COGL_WINSYS_FEATURE_FUNCTION (EGLSyncKHR, eglCreateSync,
|
||||||
|
(EGLDisplay dpy,
|
||||||
|
EGLenum type,
|
||||||
|
const EGLint *attrib_list))
|
||||||
|
COGL_WINSYS_FEATURE_FUNCTION (EGLint, eglClientWaitSync,
|
||||||
|
(EGLDisplay dpy,
|
||||||
|
EGLSyncKHR sync,
|
||||||
|
EGLint flags,
|
||||||
|
EGLTimeKHR timeout))
|
||||||
|
COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglDestroySync,
|
||||||
|
(EGLDisplay dpy,
|
||||||
|
EGLSyncKHR sync))
|
||||||
|
COGL_WINSYS_FEATURE_END ()
|
||||||
|
#endif
|
||||||
|
@ -70,7 +70,8 @@ typedef enum _CoglEGLWinsysFeature
|
|||||||
COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_X11_PIXMAP =1L<<1,
|
COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_X11_PIXMAP =1L<<1,
|
||||||
COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_WAYLAND_BUFFER =1L<<2,
|
COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_WAYLAND_BUFFER =1L<<2,
|
||||||
COGL_EGL_WINSYS_FEATURE_CREATE_CONTEXT =1L<<3,
|
COGL_EGL_WINSYS_FEATURE_CREATE_CONTEXT =1L<<3,
|
||||||
COGL_EGL_WINSYS_FEATURE_BUFFER_AGE =1L<<4
|
COGL_EGL_WINSYS_FEATURE_BUFFER_AGE =1L<<4,
|
||||||
|
COGL_EGL_WINSYS_FEATURE_FENCE_SYNC =1L<<5
|
||||||
} CoglEGLWinsysFeature;
|
} CoglEGLWinsysFeature;
|
||||||
|
|
||||||
typedef struct _CoglRendererEGL
|
typedef struct _CoglRendererEGL
|
||||||
|
@ -504,6 +504,10 @@ _cogl_winsys_context_init (CoglContext *context, CoglError **error)
|
|||||||
COGL_WINSYS_FEATURE_SWAP_REGION_THROTTLE, TRUE);
|
COGL_WINSYS_FEATURE_SWAP_REGION_THROTTLE, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((egl_renderer->private_features & COGL_EGL_WINSYS_FEATURE_FENCE_SYNC) &&
|
||||||
|
(context->private_feature_flags & COGL_PRIVATE_FEATURE_OES_EGL_SYNC))
|
||||||
|
COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_FENCE, TRUE);
|
||||||
|
|
||||||
/* NB: We currently only support creating standalone GLES2 contexts
|
/* NB: We currently only support creating standalone GLES2 contexts
|
||||||
* for offscreen rendering and so we need a dummy (non-visible)
|
* for offscreen rendering and so we need a dummy (non-visible)
|
||||||
* surface to be able to bind those contexts */
|
* surface to be able to bind those contexts */
|
||||||
@ -902,6 +906,45 @@ _cogl_winsys_restore_context (CoglContext *ctx)
|
|||||||
egl_display->egl_context);
|
egl_display->egl_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(EGL_KHR_fence_sync) || defined(EGL_KHR_reusable_sync)
|
||||||
|
static void *
|
||||||
|
_cogl_winsys_fence_add (CoglContext *context)
|
||||||
|
{
|
||||||
|
CoglRendererEGL *renderer = context->display->renderer->winsys;
|
||||||
|
void *ret;
|
||||||
|
|
||||||
|
if (renderer->pf_eglCreateSync)
|
||||||
|
ret = renderer->pf_eglCreateSync (renderer->edpy,
|
||||||
|
EGL_SYNC_FENCE_KHR,
|
||||||
|
NULL);
|
||||||
|
else
|
||||||
|
ret = NULL;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CoglBool
|
||||||
|
_cogl_winsys_fence_is_complete (CoglContext *context, void *fence)
|
||||||
|
{
|
||||||
|
CoglRendererEGL *renderer = context->display->renderer->winsys;
|
||||||
|
EGLint ret;
|
||||||
|
|
||||||
|
ret = renderer->pf_eglClientWaitSync (renderer->edpy,
|
||||||
|
fence,
|
||||||
|
EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
|
||||||
|
0);
|
||||||
|
return (ret == EGL_CONDITION_SATISFIED_KHR);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cogl_winsys_fence_destroy (CoglContext *context, void *fence)
|
||||||
|
{
|
||||||
|
CoglRendererEGL *renderer = context->display->renderer->winsys;
|
||||||
|
|
||||||
|
renderer->pf_eglDestroySync (renderer->edpy, fence);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static CoglWinsysVtable _cogl_winsys_vtable =
|
static CoglWinsysVtable _cogl_winsys_vtable =
|
||||||
{
|
{
|
||||||
.constraints = COGL_RENDERER_CONSTRAINT_USES_EGL |
|
.constraints = COGL_RENDERER_CONSTRAINT_USES_EGL |
|
||||||
@ -936,6 +979,12 @@ static CoglWinsysVtable _cogl_winsys_vtable =
|
|||||||
.save_context = _cogl_winsys_save_context,
|
.save_context = _cogl_winsys_save_context,
|
||||||
.set_gles2_context = _cogl_winsys_set_gles2_context,
|
.set_gles2_context = _cogl_winsys_set_gles2_context,
|
||||||
.restore_context = _cogl_winsys_restore_context,
|
.restore_context = _cogl_winsys_restore_context,
|
||||||
|
|
||||||
|
#if defined(EGL_KHR_fence_sync) || defined(EGL_KHR_reusable_sync)
|
||||||
|
.fence_add = _cogl_winsys_fence_add,
|
||||||
|
.fence_is_complete = _cogl_winsys_fence_is_complete,
|
||||||
|
.fence_destroy = _cogl_winsys_fence_destroy,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/* XXX: we use a function because no doubt someone will complain
|
/* XXX: we use a function because no doubt someone will complain
|
||||||
|
@ -185,6 +185,15 @@ typedef struct _CoglWinsysVtable
|
|||||||
void
|
void
|
||||||
(*destroy_gles2_context) (CoglGLES2Context *gles2_ctx);
|
(*destroy_gles2_context) (CoglGLES2Context *gles2_ctx);
|
||||||
|
|
||||||
|
void *
|
||||||
|
(*fence_add) (CoglContext *ctx);
|
||||||
|
|
||||||
|
CoglBool
|
||||||
|
(*fence_is_complete) (CoglContext *ctx, void *fence);
|
||||||
|
|
||||||
|
void
|
||||||
|
(*fence_destroy) (CoglContext *ctx, void *fence);
|
||||||
|
|
||||||
} CoglWinsysVtable;
|
} CoglWinsysVtable;
|
||||||
|
|
||||||
CoglBool
|
CoglBool
|
||||||
|
@ -143,6 +143,7 @@
|
|||||||
<xi:include href="xml/cogl-vector.xml"/>
|
<xi:include href="xml/cogl-vector.xml"/>
|
||||||
<xi:include href="xml/cogl-euler.xml"/>
|
<xi:include href="xml/cogl-euler.xml"/>
|
||||||
<xi:include href="xml/cogl-quaternion.xml"/>
|
<xi:include href="xml/cogl-quaternion.xml"/>
|
||||||
|
<xi:include href="xml/cogl-fence.xml"/>
|
||||||
<xi:include href="xml/cogl-version.xml"/>
|
<xi:include href="xml/cogl-version.xml"/>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
@ -961,6 +961,17 @@ cogl_vector3_dot_product
|
|||||||
cogl_vector3_distance
|
cogl_vector3_distance
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
|
<SECTION>
|
||||||
|
<FILE>cogl-fence</FILE>
|
||||||
|
<TITLE>GPU synchronisation fences</TITLE>
|
||||||
|
CoglFence
|
||||||
|
CoglFenceCallback
|
||||||
|
CoglFenceClosure
|
||||||
|
cogl_fence_closure_get_user_data
|
||||||
|
cogl_framebuffer_add_fence_callback
|
||||||
|
cogl_framebuffer_cancel_fence_callback
|
||||||
|
</SECTION>
|
||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
<FILE>cogl-version</FILE>
|
<FILE>cogl-version</FILE>
|
||||||
<TITLE>Versioning utility macros</TITLE>
|
<TITLE>Versioning utility macros</TITLE>
|
||||||
|
@ -66,6 +66,7 @@ test_sources = \
|
|||||||
test-primitive-and-journal.c \
|
test-primitive-and-journal.c \
|
||||||
test-copy-replace-texture.c \
|
test-copy-replace-texture.c \
|
||||||
test-pipeline-cache-unrefs-texture.c \
|
test-pipeline-cache-unrefs-texture.c \
|
||||||
|
test-fence.c \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
test_conformance_SOURCES = $(common_sources) $(test_sources)
|
test_conformance_SOURCES = $(common_sources) $(test_sources)
|
||||||
|
@ -132,6 +132,8 @@ main (int argc, char **argv)
|
|||||||
|
|
||||||
ADD_TEST (test_euler_quaternion, 0, 0);
|
ADD_TEST (test_euler_quaternion, 0, 0);
|
||||||
|
|
||||||
|
ADD_TEST (test_fence, TEST_REQUIREMENT_FENCE, 0);
|
||||||
|
|
||||||
g_printerr ("Unknown test name \"%s\"\n", argv[1]);
|
g_printerr ("Unknown test name \"%s\"\n", argv[1]);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
64
tests/conform/test-fence.c
Normal file
64
tests/conform/test-fence.c
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#include <cogl/cogl.h>
|
||||||
|
|
||||||
|
/* These will be redefined in config.h */
|
||||||
|
#undef COGL_ENABLE_EXPERIMENTAL_2_0_API
|
||||||
|
#undef COGL_ENABLE_EXPERIMENTAL_API
|
||||||
|
|
||||||
|
#include "test-utils.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include <cogl/cogl-util.h>
|
||||||
|
|
||||||
|
/* I'm writing this on the train after having dinner at a churrascuria. */
|
||||||
|
#define MAGIC_CHUNK_O_DATA ((void *) 0xdeadbeef)
|
||||||
|
|
||||||
|
static GMainLoop *loop;
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
timeout (void *user_data)
|
||||||
|
{
|
||||||
|
g_assert (!"timeout not reached");
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
callback (CoglFence *fence,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
int fb_width = cogl_framebuffer_get_width (test_fb);
|
||||||
|
int fb_height = cogl_framebuffer_get_height (test_fb);
|
||||||
|
|
||||||
|
test_utils_check_pixel (test_fb, fb_width - 1, fb_height - 1, 0x00ff0000);
|
||||||
|
g_assert (user_data == MAGIC_CHUNK_O_DATA && "callback data not mangled");
|
||||||
|
|
||||||
|
g_main_loop_quit (loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test_fence (void)
|
||||||
|
{
|
||||||
|
GSource *cogl_source;
|
||||||
|
int fb_width = cogl_framebuffer_get_width (test_fb);
|
||||||
|
int fb_height = cogl_framebuffer_get_height (test_fb);
|
||||||
|
CoglFenceClosure *closure;
|
||||||
|
|
||||||
|
cogl_source = cogl_glib_source_new (test_ctx, G_PRIORITY_DEFAULT);
|
||||||
|
g_source_attach (cogl_source, NULL);
|
||||||
|
loop = g_main_loop_new (NULL, TRUE);
|
||||||
|
|
||||||
|
cogl_framebuffer_orthographic (test_fb, 0, 0, fb_width, fb_height, -1, 100);
|
||||||
|
cogl_framebuffer_clear4f (test_fb, COGL_BUFFER_BIT_COLOR,
|
||||||
|
0.0f, 1.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
closure = cogl_framebuffer_add_fence_callback (test_fb,
|
||||||
|
callback,
|
||||||
|
MAGIC_CHUNK_O_DATA);
|
||||||
|
g_assert (closure != NULL);
|
||||||
|
|
||||||
|
g_timeout_add_seconds (5, timeout, NULL);
|
||||||
|
|
||||||
|
g_main_loop_run (loop);
|
||||||
|
|
||||||
|
if (cogl_test_verbose ())
|
||||||
|
g_print ("OK\n");
|
||||||
|
}
|
@ -71,6 +71,12 @@ check_flags (TestFlags flags,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flags & TEST_REQUIREMENT_FENCE &&
|
||||||
|
!cogl_has_feature (test_ctx, COGL_FEATURE_ID_FENCE))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (flags & TEST_KNOWN_FAILURE)
|
if (flags & TEST_KNOWN_FAILURE)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -20,7 +20,8 @@ typedef enum _TestFlags
|
|||||||
TEST_REQUIREMENT_GLES2_CONTEXT = 1<<6,
|
TEST_REQUIREMENT_GLES2_CONTEXT = 1<<6,
|
||||||
TEST_REQUIREMENT_MAP_WRITE = 1<<7,
|
TEST_REQUIREMENT_MAP_WRITE = 1<<7,
|
||||||
TEST_REQUIREMENT_GLSL = 1<<8,
|
TEST_REQUIREMENT_GLSL = 1<<8,
|
||||||
TEST_REQUIREMENT_OFFSCREEN = 1<<9
|
TEST_REQUIREMENT_OFFSCREEN = 1<<9,
|
||||||
|
TEST_REQUIREMENT_FENCE = 1<<10
|
||||||
} TestFlags;
|
} TestFlags;
|
||||||
|
|
||||||
extern CoglContext *test_ctx;
|
extern CoglContext *test_ctx;
|
||||||
|
Loading…
Reference in New Issue
Block a user