[cogl/wip/wayland: 8/8] onscreen: Adds buffer age api
- From: Robert Bragg <rbragg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [cogl/wip/wayland: 8/8] onscreen: Adds buffer age api
- Date: Fri, 9 Mar 2012 17:40:28 +0000 (UTC)
commit 9e692a8a1b6e61822eadeaa3458b04f69bff9779
Author: Robert Bragg <robert linux intel com>
Date: Mon Feb 13 14:37:27 2012 +0000
onscreen: Adds buffer age api
This adds a cogl_oncsreen_get_back_buffer_age() function that allows
applications to query how old the back buffer contents are at the start
of a new frame.
The intention of this api is to help optimize applications that
frequently only update small regions of the screen. Applications can
maintain a running record of the regions changed over the last three or
so frames and at the start of each frame they can check the age of the
back buffer contents and if its between 1 and 3 then they can use their
history of the last three frames to calculate how to repair the contents
of the re-used buffer instead of having to redraw everything.
A nice advantage this approach has is that it doesn't require a blit to
present the incremental updates to the front buffer, a flip can be used
which is more efficient.
cogl/cogl-framebuffer-private.h | 5 +++
cogl/cogl-framebuffer.c | 2 +
cogl/cogl-onscreen.c | 11 ++++++
cogl/cogl-onscreen.h | 40 +++++++++++++++++++++++
cogl/winsys/cogl-winsys-egl-feature-functions.h | 7 ++++
cogl/winsys/cogl-winsys-egl-private.h | 3 +-
cogl/winsys/cogl-winsys-egl.c | 22 ++++++++++++
7 files changed, 89 insertions(+), 1 deletions(-)
---
diff --git a/cogl/cogl-framebuffer-private.h b/cogl/cogl-framebuffer-private.h
index 0081a2f..f2cedf9 100644
--- a/cogl/cogl-framebuffer-private.h
+++ b/cogl/cogl-framebuffer-private.h
@@ -129,6 +129,11 @@ struct _CoglFramebuffer
int samples_per_pixel;
+ /* How old the contents of the current back buffer are.
+ * 0 = Uninitialized / Unknown buffer contents
+ */
+ int back_buffer_age;
+
/* We journal the textured rectangles we want to submit to OpenGL so
* we have an oppertunity to batch them together into less draw
* calls. */
diff --git a/cogl/cogl-framebuffer.c b/cogl/cogl-framebuffer.c
index f18abf1..da764eb 100644
--- a/cogl/cogl-framebuffer.c
+++ b/cogl/cogl-framebuffer.c
@@ -194,6 +194,8 @@ _cogl_framebuffer_init (CoglFramebuffer *framebuffer,
*/
framebuffer->clear_clip_dirty = TRUE;
+ framebuffer->back_buffer_age = 0;
+
/* XXX: We have to maintain a central list of all framebuffers
* because at times we need to be able to flush all known journals.
*
diff --git a/cogl/cogl-onscreen.c b/cogl/cogl-onscreen.c
index 7bbe529..39a2ad0 100644
--- a/cogl/cogl-onscreen.c
+++ b/cogl/cogl-onscreen.c
@@ -142,6 +142,7 @@ cogl_onscreen_swap_buffers (CoglOnscreen *onscreen)
COGL_BUFFER_BIT_COLOR |
COGL_BUFFER_BIT_DEPTH |
COGL_BUFFER_BIT_STENCIL);
+ framebuffer->back_buffer_age = 0;
}
void
@@ -167,6 +168,7 @@ cogl_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
COGL_BUFFER_BIT_COLOR |
COGL_BUFFER_BIT_DEPTH |
COGL_BUFFER_BIT_STENCIL);
+ framebuffer->back_buffer_age = 0;
}
void
@@ -196,6 +198,7 @@ cogl_onscreen_swap_region (CoglOnscreen *onscreen,
COGL_BUFFER_BIT_COLOR |
COGL_BUFFER_BIT_DEPTH |
COGL_BUFFER_BIT_STENCIL);
+ framebuffer->back_buffer_age = 0;
}
#ifdef COGL_HAS_X11_SUPPORT
@@ -406,3 +409,11 @@ cogl_onscreen_start_frame (CoglOnscreen *onscreen)
if (winsys->onscreen_start_frame)
winsys->onscreen_start_frame (onscreen);
}
+
+int
+cogl_onscreen_get_back_buffer_age (CoglOnscreen *onscreen)
+{
+ CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+
+ return framebuffer->back_buffer_age;
+}
diff --git a/cogl/cogl-onscreen.h b/cogl/cogl-onscreen.h
index 554f379..959dbd2 100644
--- a/cogl/cogl-onscreen.h
+++ b/cogl/cogl-onscreen.h
@@ -461,6 +461,46 @@ cogl_is_onscreen (void *object);
void
cogl_onscreen_start_frame (CoglOnscreen *onscreen);
+/**
+ * cogl_onscreen_get_back_buffer_age:
+ * @onscreen: A #CoglOnscreen framebuffer
+ *
+ * Queries how old the contents of the current back buffer are. If the back
+ * buffer has been newly allocated or otherwise has undefined contents then the
+ * age returned will be 0.
+ *
+ * For example if the @onscreen framebuffer is double buffered then you will
+ * typically see a buffer age of 2. If @onscreen is single buffered then you
+ * will typically see an age of 1. Since there can be system events such as
+ * power management events or the driver might have more complex ways of
+ * managing buffers than a simple ring you can't assume anything about the age
+ * based on previous values.
+ *
+ * The intention of providing this information is to help optimize applications
+ * that often update small regions of the screen. These applications can keep a
+ * running list of the regions they modify for the last 3 frames and at the
+ * start of each frame they can query the age of the back buffer and so long as
+ * the age is between 1 and 3 they can use the history of modified regions to
+ * determine how to repair the re-used back buffer instead of having to redraw
+ * everything.
+ *
+ * This mechanism can really help to improve application efficiency first by
+ * helping minimize redundant re-drawing of unchanging parts of a scene but
+ * also the final result can be presented by flipping the back and front buffer
+ * instead of having to copy the modified region.
+ *
+ * <note>Applications using this api should typically use
+ * cogl_onscreen_start_frame() to explicitly start a new frame without
+ * rendering before querying the age. The back buffer age is undefined after
+ * calling cogl_swap_buffers() (or similar apis) until a new frame has been
+ * started.</note>
+ *
+ * Since: 1.10
+ * Stability: unstable
+ */
+int
+cogl_onscreen_get_back_buffer_age (CoglOnscreen *onscreen);
+
G_END_DECLS
#endif /* __COGL_ONSCREEN_H */
diff --git a/cogl/winsys/cogl-winsys-egl-feature-functions.h b/cogl/winsys/cogl-winsys-egl-feature-functions.h
index ecd87be..4807e18 100644
--- a/cogl/winsys/cogl-winsys-egl-feature-functions.h
+++ b/cogl/winsys/cogl-winsys-egl-feature-functions.h
@@ -125,3 +125,10 @@ COGL_WINSYS_FEATURE_FUNCTION (EGLBoolean, eglStartFrame,
EGLSurface surface))
COGL_WINSYS_FEATURE_END ()
#endif
+#ifdef EGL_EXT_buffer_age
+COGL_WINSYS_FEATURE_BEGIN (buffer_age,
+ "EXT\0",
+ "buffer_age\0",
+ COGL_EGL_WINSYS_FEATURE_BUFFER_AGE)
+COGL_WINSYS_FEATURE_END ()
+#endif
diff --git a/cogl/winsys/cogl-winsys-egl-private.h b/cogl/winsys/cogl-winsys-egl-private.h
index 9f501ee..5e091bc 100644
--- a/cogl/winsys/cogl-winsys-egl-private.h
+++ b/cogl/winsys/cogl-winsys-egl-private.h
@@ -71,7 +71,8 @@ typedef enum _CoglEGLWinsysFeature
COGL_EGL_WINSYS_FEATURE_EGL_IMAGE_FROM_WAYLAND_BUFFER =1L<<2,
COGL_EGL_WINSYS_FEATURE_SURFACELESS_OPENGL =1L<<3,
COGL_EGL_WINSYS_FEATURE_SURFACELESS_GLES1 =1L<<4,
- COGL_EGL_WINSYS_FEATURE_SURFACELESS_GLES2 =1L<<5
+ COGL_EGL_WINSYS_FEATURE_SURFACELESS_GLES2 =1L<<5,
+ COGL_EGL_WINSYS_FEATURE_BUFFER_AGE =1L<<6
} CoglEGLWinsysFeature;
typedef struct _CoglRendererEGL
diff --git a/cogl/winsys/cogl-winsys-egl.c b/cogl/winsys/cogl-winsys-egl.c
index 0dc8dc3..21f807e 100644
--- a/cogl/winsys/cogl-winsys-egl.c
+++ b/cogl/winsys/cogl-winsys-egl.c
@@ -582,6 +582,9 @@ _cogl_winsys_onscreen_start_frame (CoglOnscreen *onscreen)
CoglRendererEGL *egl_renderer = renderer->winsys;
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
int width, height;
+#ifdef EGL_EXT_buffer_age
+ int age;
+#endif
/* NB: cogl_onscreen_start_frame() is documented to be a NOP if
* the COGL_FEATURE_ID_START_FRAME isn't available so we can't
@@ -605,6 +608,25 @@ _cogl_winsys_onscreen_start_frame (CoglOnscreen *onscreen)
}
else
g_warning ("Error reported by eglQuerySurface");
+
+#ifdef EGL_EXT_buffer_age
+ if (egl_renderer->private_features & COGL_EGL_WINSYS_FEATURE_BUFFER_AGE)
+ {
+ if (eglQuerySurface (egl_renderer->edpy, egl_onscreen->egl_surface,
+ EGL_BUFFER_AGE_EXT, &age) == EGL_TRUE)
+ {
+ fb->back_buffer_age = age;
+ }
+ else
+ {
+ g_warning ("Error reported by eglQuerySurface "
+ "when querying EGL_BUFFER_AGE_EXT");
+ fb->back_buffer_age = 0;
+ }
+ }
+ else
+#endif
+ fb->back_buffer_age = 0;
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]