mirror of
https://github.com/brl/mutter.git
synced 2025-02-22 07:54:09 +00:00
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 *
|
void *
|
||||||
(* glXGetProcAddress) (const GLubyte *procName);
|
(* glXGetProcAddress) (const GLubyte *procName);
|
||||||
|
|
||||||
|
int
|
||||||
|
(* glXQueryDrawable) (Display *dpy, GLXDrawable drawable,
|
||||||
|
int attribute, unsigned int *value);
|
||||||
|
|
||||||
/* Function pointers for GLX specific extensions */
|
/* Function pointers for GLX specific extensions */
|
||||||
#define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d, e, f, g)
|
#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);
|
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
|
#ifdef COGL_HAS_X11_SUPPORT
|
||||||
void
|
void
|
||||||
cogl_x11_onscreen_set_foreign_window_xid (CoglOnscreen *onscreen,
|
cogl_x11_onscreen_set_foreign_window_xid (CoglOnscreen *onscreen,
|
||||||
|
@ -307,6 +307,54 @@ cogl_onscreen_hide (CoglOnscreen *onscreen);
|
|||||||
void
|
void
|
||||||
cogl_onscreen_swap_buffers (CoglOnscreen *onscreen);
|
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:
|
* cogl_onscreen_swap_region:
|
||||||
* @onscreen: A #CoglOnscreen framebuffer
|
* @onscreen: A #CoglOnscreen framebuffer
|
||||||
|
@ -829,6 +829,9 @@ typedef enum _CoglWinsysFeature
|
|||||||
* only needs to be throttled to the framerate */
|
* only needs to be throttled to the framerate */
|
||||||
COGL_WINSYS_FEATURE_SWAP_REGION_SYNCHRONIZED,
|
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
|
COGL_WINSYS_FEATURE_N_FEATURES
|
||||||
} CoglWinsysFeature;
|
} CoglWinsysFeature;
|
||||||
|
|
||||||
|
@ -170,3 +170,11 @@ COGL_WINSYS_FEATURE_FUNCTION (GLXContext, glXCreateContextAttribs,
|
|||||||
Bool direct,
|
Bool direct,
|
||||||
const int *attrib_list))
|
const int *attrib_list))
|
||||||
COGL_WINSYS_FEATURE_END ()
|
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",
|
(!g_module_symbol (glx_renderer->libgl_module, "glXGetProcAddress",
|
||||||
(void **) &glx_renderer->glXGetProcAddress) &&
|
(void **) &glx_renderer->glXGetProcAddress) &&
|
||||||
!g_module_symbol (glx_renderer->libgl_module, "glXGetProcAddressARB",
|
!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_set_error (error, COGL_WINSYS_ERROR,
|
||||||
COGL_WINSYS_ERROR_INIT,
|
COGL_WINSYS_ERROR_INIT,
|
||||||
@ -1189,6 +1191,30 @@ _cogl_winsys_get_vsync_counter (CoglContext *ctx)
|
|||||||
return video_sync_count;
|
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
|
static void
|
||||||
_cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
|
_cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
|
||||||
const int *user_rectangles,
|
const int *user_rectangles,
|
||||||
@ -2165,6 +2191,7 @@ static CoglWinsysVtable _cogl_winsys_vtable =
|
|||||||
.onscreen_bind = _cogl_winsys_onscreen_bind,
|
.onscreen_bind = _cogl_winsys_onscreen_bind,
|
||||||
.onscreen_swap_buffers = _cogl_winsys_onscreen_swap_buffers,
|
.onscreen_swap_buffers = _cogl_winsys_onscreen_swap_buffers,
|
||||||
.onscreen_swap_region = _cogl_winsys_onscreen_swap_region,
|
.onscreen_swap_region = _cogl_winsys_onscreen_swap_region,
|
||||||
|
.onscreen_get_buffer_age = _cogl_winsys_onscreen_get_buffer_age,
|
||||||
.onscreen_update_swap_throttled =
|
.onscreen_update_swap_throttled =
|
||||||
_cogl_winsys_onscreen_update_swap_throttled,
|
_cogl_winsys_onscreen_update_swap_throttled,
|
||||||
.onscreen_x11_get_window_xid =
|
.onscreen_x11_get_window_xid =
|
||||||
|
@ -127,6 +127,9 @@ typedef struct _CoglWinsysVtable
|
|||||||
void
|
void
|
||||||
(*onscreen_set_resizable) (CoglOnscreen *onscreen, CoglBool resizable);
|
(*onscreen_set_resizable) (CoglOnscreen *onscreen, CoglBool resizable);
|
||||||
|
|
||||||
|
int
|
||||||
|
(*onscreen_get_buffer_age) (CoglOnscreen *onscreen);
|
||||||
|
|
||||||
#ifdef COGL_HAS_EGL_SUPPORT
|
#ifdef COGL_HAS_EGL_SUPPORT
|
||||||
EGLDisplay
|
EGLDisplay
|
||||||
(*context_egl_get_egl_display) (CoglContext *context);
|
(*context_egl_get_egl_display) (CoglContext *context);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user