cogl: Add support for partial update
Add support for a cogl function to set the damage_region on an onscreen framebuffer. The goal of this is to enable using the EGL_KHR_partial_update extension which can potentially reduce memory bandwidth usage by some GPUs, particularly on embedded GPUs that operate on a tiling rendering model. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2023>
This commit is contained in:
parent
331f08fc40
commit
87965b5ce2
@ -300,6 +300,19 @@ cogl_onscreen_bind (CoglOnscreen *onscreen)
|
||||
COGL_ONSCREEN_GET_CLASS (onscreen)->bind (onscreen);
|
||||
}
|
||||
|
||||
void
|
||||
cogl_onscreen_queue_damage_region (CoglOnscreen *onscreen,
|
||||
const int *rectangles,
|
||||
int n_rectangles)
|
||||
{
|
||||
CoglOnscreenClass *klass = COGL_ONSCREEN_GET_CLASS (onscreen);
|
||||
|
||||
if (!klass->queue_damage_region)
|
||||
return;
|
||||
|
||||
klass->queue_damage_region (onscreen, rectangles, n_rectangles);
|
||||
}
|
||||
|
||||
void
|
||||
cogl_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||
const int *rectangles,
|
||||
|
@ -74,6 +74,10 @@ struct _CoglOnscreenClass
|
||||
CoglFrameInfo *info,
|
||||
gpointer user_data);
|
||||
|
||||
void (* queue_damage_region) (CoglOnscreen *onscreen,
|
||||
const int *rectangles,
|
||||
int n_rectangles);
|
||||
|
||||
gboolean (* direct_scanout) (CoglOnscreen *onscreen,
|
||||
CoglScanout *scanout,
|
||||
CoglFrameInfo *info,
|
||||
@ -227,6 +231,23 @@ cogl_onscreen_swap_buffers (CoglOnscreen *onscreen,
|
||||
COGL_EXPORT int
|
||||
cogl_onscreen_get_buffer_age (CoglOnscreen *onscreen);
|
||||
|
||||
/**
|
||||
* cogl_onscreen_queue_damage_region:
|
||||
* @onscreen: A #CoglOnscreen framebuffer
|
||||
* @rectangles: An array of integer 4-tuples representing damaged
|
||||
* rectangles as (x, y, width, height) tuples.
|
||||
* @n_rectangles: The number of 4-tuples to be read from @rectangles
|
||||
*
|
||||
* Implementation for https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_partial_update.txt
|
||||
* This immediately queues state to OpenGL that will be used for the
|
||||
* next swap.
|
||||
* This needs to be called every frame.
|
||||
*/
|
||||
COGL_EXPORT void
|
||||
cogl_onscreen_queue_damage_region (CoglOnscreen *onscreen,
|
||||
const int *rectangles,
|
||||
int n_rectangles);
|
||||
|
||||
/**
|
||||
* cogl_onscreen_swap_buffers_with_damage:
|
||||
* @onscreen: A #CoglOnscreen framebuffer
|
||||
|
@ -242,6 +242,31 @@ cogl_onscreen_egl_swap_region (CoglOnscreen *onscreen,
|
||||
g_warning ("Error reported by eglSwapBuffersRegion");
|
||||
}
|
||||
|
||||
static void
|
||||
cogl_onscreen_egl_queue_damage_region (CoglOnscreen *onscreen,
|
||||
const int *rectangles,
|
||||
int n_rectangles)
|
||||
{
|
||||
CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (onscreen);
|
||||
CoglOnscreenEglPrivate *priv =
|
||||
cogl_onscreen_egl_get_instance_private (onscreen_egl);
|
||||
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||
CoglContext *context = cogl_framebuffer_get_context (framebuffer);
|
||||
CoglRenderer *renderer = context->display->renderer;
|
||||
CoglRendererEGL *egl_renderer = renderer->winsys;
|
||||
|
||||
g_return_if_fail (n_rectangles > 0);
|
||||
|
||||
if (!egl_renderer->pf_eglSetDamageRegion)
|
||||
return;
|
||||
|
||||
if (egl_renderer->pf_eglSetDamageRegion (egl_renderer->edpy,
|
||||
priv->egl_surface,
|
||||
rectangles,
|
||||
n_rectangles) == EGL_FALSE)
|
||||
g_warning ("Error reported by eglSetDamageRegion");
|
||||
}
|
||||
|
||||
static void
|
||||
cogl_onscreen_egl_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||
const int *rectangles,
|
||||
@ -345,6 +370,8 @@ cogl_onscreen_egl_class_init (CoglOnscreenEglClass *klass)
|
||||
object_class->dispose = cogl_onscreen_egl_dispose;
|
||||
|
||||
onscreen_class->bind = cogl_onscreen_egl_bind;
|
||||
onscreen_class->queue_damage_region =
|
||||
cogl_onscreen_egl_queue_damage_region;
|
||||
onscreen_class->swap_buffers_with_damage =
|
||||
cogl_onscreen_egl_swap_buffers_with_damage;
|
||||
onscreen_class->swap_region = cogl_onscreen_egl_swap_region;
|
||||
|
@ -116,6 +116,17 @@ COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglSwapBuffersWithDamage,
|
||||
EGLint n_rects))
|
||||
COGL_WINSYS_FEATURE_END ()
|
||||
|
||||
COGL_WINSYS_FEATURE_BEGIN (partial_update,
|
||||
"KHR\0",
|
||||
"partial_update\0",
|
||||
COGL_EGL_WINSYS_FEATURE_BUFFER_AGE)
|
||||
COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglSetDamageRegion,
|
||||
(EGLDisplay dpy,
|
||||
EGLSurface surface,
|
||||
const EGLint *rects,
|
||||
EGLint n_rects))
|
||||
COGL_WINSYS_FEATURE_END ()
|
||||
|
||||
#if defined(EGL_KHR_fence_sync) || defined(EGL_KHR_reusable_sync)
|
||||
COGL_WINSYS_FEATURE_BEGIN (fence_sync,
|
||||
"KHR\0",
|
||||
|
Loading…
Reference in New Issue
Block a user