cogl-onscreen: Add buffer_age support
Add a new BUFFER_AGE winsys feature and a get_buffer_age method to cogl-onscreen that allows to query the value. https://bugzilla.gnome.org/show_bug.cgi?id=669122 Reviewed-by: Neil Roberts <neil@linux.intel.com> Reviewed-by: Robert Bragg <robert@linux.intel.com> Note: When landing the patch I made some gtk-doc updates and changed _get_buffer_age to return an age of 0 always if the age feature isn't support instead of using _COGL_RETURN_VAL_IF_FAIL. -- Robert Bragg (cherry picked from commit 427b1038051e9b53a071d8c229b363b075bb1dc0)
This commit is contained in:
parent
9fb0cbd45d
commit
860fb00fdc
@ -69,6 +69,10 @@ typedef struct _CoglGLXRenderer
|
||||
void *
|
||||
(* glXGetProcAddress) (const GLubyte *procName);
|
||||
|
||||
int
|
||||
(* glXQueryDrawable) (Display *dpy, GLXDrawable drawable,
|
||||
int attribute, unsigned int *value);
|
||||
|
||||
/* Function pointers for GLX specific extensions */
|
||||
#define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d, e, f, g)
|
||||
|
||||
|
@ -188,6 +188,22 @@ cogl_onscreen_swap_region (CoglOnscreen *onscreen,
|
||||
COGL_BUFFER_BIT_STENCIL);
|
||||
}
|
||||
|
||||
int
|
||||
cogl_onscreen_get_buffer_age (CoglOnscreen *onscreen)
|
||||
{
|
||||
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||
const CoglWinsysVtable *winsys;
|
||||
|
||||
_COGL_RETURN_VAL_IF_FAIL (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN, 0);
|
||||
|
||||
winsys = _cogl_framebuffer_get_winsys (framebuffer);
|
||||
|
||||
if (!winsys->onscreen_get_buffer_age)
|
||||
return 0;
|
||||
|
||||
return winsys->onscreen_get_buffer_age (onscreen);
|
||||
}
|
||||
|
||||
#ifdef COGL_HAS_X11_SUPPORT
|
||||
void
|
||||
cogl_x11_onscreen_set_foreign_window_xid (CoglOnscreen *onscreen,
|
||||
|
@ -307,6 +307,54 @@ cogl_onscreen_hide (CoglOnscreen *onscreen);
|
||||
void
|
||||
cogl_onscreen_swap_buffers (CoglOnscreen *onscreen);
|
||||
|
||||
|
||||
/**
|
||||
* cogl_onscreen_get_buffer_age:
|
||||
* @onscreen: A #CoglOnscreen framebuffer
|
||||
*
|
||||
* Gets the current age of the buffer contents.
|
||||
*
|
||||
* This function allows applications to query the age of the current
|
||||
* back buffer contents for a #CoglOnscreen as the number of frames
|
||||
* elapsed since the contents were most recently defined.
|
||||
*
|
||||
* These age values exposes enough information to applications about
|
||||
* how Cogl internally manages back buffers to allow applications to
|
||||
* re-use the contents of old frames and minimize how much must be
|
||||
* redrawn for the next frame.
|
||||
*
|
||||
* The back buffer contents can either be reported as invalid (has an
|
||||
* age of 0) or it may be reported to be the same contents as from n
|
||||
* frames prior to the current frame.
|
||||
*
|
||||
* The queried value remains valid until the next buffer swap.
|
||||
*
|
||||
* <note>One caveat is that under X11 the buffer age does not reflect
|
||||
* changes to buffer contents caused by the window systems. X11
|
||||
* applications must track Expose events to determine what buffer
|
||||
* regions need to additionally be repaired each frame.</note>
|
||||
*
|
||||
* The recommended way to take advantage of this buffer age api is to
|
||||
* build up a circular buffer of length 3 for tracking damage regions
|
||||
* over the last 3 frames and when starting a new frame look at the
|
||||
* age of the buffer and combine the damage regions for the current
|
||||
* frame with the damage regions of previous @age frames so you know
|
||||
* everything that must be redrawn to update the old contents for the
|
||||
* new frame.
|
||||
*
|
||||
* <note>If the system doesn't not support being able to track the age
|
||||
* of back buffers then this function will always return 0 which
|
||||
* implies that the contents are undefined.</note>
|
||||
*
|
||||
* Return value: The age of the buffer contents or 0 when the buffer
|
||||
* contents are undefined.
|
||||
*
|
||||
* Since: 1.14
|
||||
* Stability: stable
|
||||
*/
|
||||
int
|
||||
cogl_onscreen_get_buffer_age (CoglOnscreen *onscreen);
|
||||
|
||||
/**
|
||||
* cogl_onscreen_swap_region:
|
||||
* @onscreen: A #CoglOnscreen framebuffer
|
||||
|
@ -829,6 +829,9 @@ typedef enum _CoglWinsysFeature
|
||||
* only needs to be throttled to the framerate */
|
||||
COGL_WINSYS_FEATURE_SWAP_REGION_SYNCHRONIZED,
|
||||
|
||||
/* Avaiable if the age of the back buffer can be queried */
|
||||
COGL_WINSYS_FEATURE_BUFFER_AGE,
|
||||
|
||||
COGL_WINSYS_FEATURE_N_FEATURES
|
||||
} CoglWinsysFeature;
|
||||
|
||||
|
@ -170,3 +170,11 @@ COGL_WINSYS_FEATURE_FUNCTION (GLXContext, glXCreateContextAttribs,
|
||||
Bool direct,
|
||||
const int *attrib_list))
|
||||
COGL_WINSYS_FEATURE_END ()
|
||||
|
||||
COGL_WINSYS_FEATURE_BEGIN (255, 255,
|
||||
buffer_age,
|
||||
"EXT\0",
|
||||
"buffer_age\0",
|
||||
0,
|
||||
COGL_WINSYS_FEATURE_BUFFER_AGE)
|
||||
COGL_WINSYS_FEATURE_END ()
|
||||
|
@ -280,7 +280,9 @@ resolve_core_glx_functions (CoglRenderer *renderer,
|
||||
(!g_module_symbol (glx_renderer->libgl_module, "glXGetProcAddress",
|
||||
(void **) &glx_renderer->glXGetProcAddress) &&
|
||||
!g_module_symbol (glx_renderer->libgl_module, "glXGetProcAddressARB",
|
||||
(void **) &glx_renderer->glXGetProcAddress)))
|
||||
(void **) &glx_renderer->glXGetProcAddress)) ||
|
||||
!g_module_symbol (glx_renderer->libgl_module, "glXQueryDrawable",
|
||||
(void **) &glx_renderer->glXQueryDrawable))
|
||||
{
|
||||
_cogl_set_error (error, COGL_WINSYS_ERROR,
|
||||
COGL_WINSYS_ERROR_INIT,
|
||||
@ -1189,6 +1191,30 @@ _cogl_winsys_get_vsync_counter (CoglContext *ctx)
|
||||
return video_sync_count;
|
||||
}
|
||||
|
||||
#ifndef GLX_BACK_BUFFER_AGE_EXT
|
||||
#define GLX_BACK_BUFFER_AGE_EXT 0x20F4
|
||||
#endif
|
||||
|
||||
static int
|
||||
_cogl_winsys_onscreen_get_buffer_age (CoglOnscreen *onscreen)
|
||||
{
|
||||
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||
CoglContext *context = framebuffer->context;
|
||||
CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (context->display->renderer);
|
||||
CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
|
||||
CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
|
||||
CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
|
||||
GLXDrawable drawable = glx_onscreen->glxwin ? glx_onscreen->glxwin : xlib_onscreen->xwin;
|
||||
unsigned int age;
|
||||
|
||||
if (!_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_BUFFER_AGE))
|
||||
return 0;
|
||||
|
||||
glx_renderer->glXQueryDrawable (xlib_renderer->xdpy, drawable, GLX_BACK_BUFFER_AGE_EXT, &age);
|
||||
|
||||
return age;
|
||||
}
|
||||
|
||||
static void
|
||||
_cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
|
||||
const int *user_rectangles,
|
||||
@ -2165,6 +2191,7 @@ static CoglWinsysVtable _cogl_winsys_vtable =
|
||||
.onscreen_bind = _cogl_winsys_onscreen_bind,
|
||||
.onscreen_swap_buffers = _cogl_winsys_onscreen_swap_buffers,
|
||||
.onscreen_swap_region = _cogl_winsys_onscreen_swap_region,
|
||||
.onscreen_get_buffer_age = _cogl_winsys_onscreen_get_buffer_age,
|
||||
.onscreen_update_swap_throttled =
|
||||
_cogl_winsys_onscreen_update_swap_throttled,
|
||||
.onscreen_x11_get_window_xid =
|
||||
|
@ -127,6 +127,9 @@ typedef struct _CoglWinsysVtable
|
||||
void
|
||||
(*onscreen_set_resizable) (CoglOnscreen *onscreen, CoglBool resizable);
|
||||
|
||||
int
|
||||
(*onscreen_get_buffer_age) (CoglOnscreen *onscreen);
|
||||
|
||||
#ifdef COGL_HAS_EGL_SUPPORT
|
||||
EGLDisplay
|
||||
(*context_egl_get_egl_display) (CoglContext *context);
|
||||
|
Loading…
Reference in New Issue
Block a user