<p dir="ltr">Never mind, the first one was correct. I misunderstood buffer age.<br>
--Jason</p>
<div class="gmail_quote">On Jan 16, 2014 10:52 PM, "Jason Ekstrand" <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Signed-off-by: Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>><br>
---<br>
<br>
The second version properly sets the EGL_SWAP_BEHAVIOR surface attribute to<br>
EGL_BUFFER_PRESERVED.<br>
<br>
src/gl-renderer.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++-<br>
1 file changed, 103 insertions(+), 1 deletion(-)<br>
<br>
diff --git a/src/gl-renderer.c b/src/gl-renderer.c<br>
index c8dfa4b..eddf481 100644<br>
--- a/src/gl-renderer.c<br>
+++ b/src/gl-renderer.c<br>
@@ -124,6 +124,8 @@ struct gl_renderer {<br>
PFNEGLCREATEIMAGEKHRPROC create_image;<br>
PFNEGLDESTROYIMAGEKHRPROC destroy_image;<br>
<br>
+ PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC swap_buffers_with_damage;<br>
+<br>
int has_unpack_subimage;<br>
<br>
PFNEGLBINDWAYLANDDISPLAYWL bind_display;<br>
@@ -677,6 +679,17 @@ draw_output_border_texture(struct gl_output_state *go,<br>
glDisableVertexAttribArray(0);<br>
}<br>
<br>
+static int<br>
+output_has_borders(struct weston_output *output)<br>
+{<br>
+ struct gl_output_state *go = get_output_state(output);<br>
+<br>
+ return go->borders[GL_RENDERER_BORDER_TOP].data ||<br>
+ go->borders[GL_RENDERER_BORDER_RIGHT].data ||<br>
+ go->borders[GL_RENDERER_BORDER_BOTTOM].data ||<br>
+ go->borders[GL_RENDERER_BORDER_LEFT].data;<br>
+}<br>
+<br>
static void<br>
draw_output_borders(struct weston_output *output,<br>
enum gl_border_status border_status)<br>
@@ -732,6 +745,43 @@ draw_output_borders(struct weston_output *output,<br>
}<br>
<br>
static void<br>
+output_get_border_damage(struct weston_output *output,<br>
+ enum gl_border_status border_status,<br>
+ pixman_region32_t *damage)<br>
+{<br>
+ struct gl_output_state *go = get_output_state(output);<br>
+ struct gl_border_image *top, *bottom, *left, *right;<br>
+ int full_width, full_height;<br>
+<br>
+ if (border_status == BORDER_STATUS_CLEAN)<br>
+ return; /* Clean. Nothing to do. */<br>
+<br>
+ top = &go->borders[GL_RENDERER_BORDER_TOP];<br>
+ bottom = &go->borders[GL_RENDERER_BORDER_BOTTOM];<br>
+ left = &go->borders[GL_RENDERER_BORDER_LEFT];<br>
+ right = &go->borders[GL_RENDERER_BORDER_RIGHT];<br>
+<br>
+ full_width = output->current_mode->width + left->width + right->width;<br>
+ full_height = output->current_mode->height + top->height + bottom->height;<br>
+ if (border_status & BORDER_TOP_DIRTY)<br>
+ pixman_region32_union_rect(damage, damage,<br>
+ 0, 0,<br>
+ full_width, top->height);<br>
+ if (border_status & BORDER_LEFT_DIRTY)<br>
+ pixman_region32_union_rect(damage, damage,<br>
+ 0, top->height,<br>
+ left->width, output->current_mode->height);<br>
+ if (border_status & BORDER_RIGHT_DIRTY)<br>
+ pixman_region32_union_rect(damage, damage,<br>
+ full_width - right->width, top->height,<br>
+ right->width, output->current_mode->height);<br>
+ if (border_status & BORDER_BOTTOM_DIRTY)<br>
+ pixman_region32_union_rect(damage, damage,<br>
+ 0, full_height - bottom->height,<br>
+ full_width, bottom->height);<br>
+}<br>
+<br>
+static void<br>
output_get_damage(struct weston_output *output,<br>
pixman_region32_t *buffer_damage, uint32_t *border_damage)<br>
{<br>
@@ -802,6 +852,9 @@ gl_renderer_repaint_output(struct weston_output *output,<br>
struct gl_renderer *gr = get_renderer(compositor);<br>
EGLBoolean ret;<br>
static int errored;<br>
+ int i, nrects, buffer_height;<br>
+ EGLint *egl_damage, *d;<br>
+ pixman_box32_t *rects;<br>
pixman_region32_t buffer_damage, total_damage;<br>
enum gl_border_status border_damage = BORDER_STATUS_CLEAN;<br>
<br>
@@ -847,7 +900,44 @@ gl_renderer_repaint_output(struct weston_output *output,<br>
pixman_region32_copy(&output->previous_damage, output_damage);<br>
wl_signal_emit(&output->frame_signal, output);<br>
<br>
- ret = eglSwapBuffers(gr->egl_display, go->egl_surface);<br>
+ if (gr->swap_buffers_with_damage && gr->has_egl_buffer_age) {<br>
+ pixman_region32_init(&buffer_damage);<br>
+ weston_transformed_region(output->width, output->height,<br>
+ output->transform,<br>
+ output->current_scale,<br>
+ output_damage, &buffer_damage);<br>
+<br>
+ if (output_has_borders(output)) {<br>
+ pixman_region32_translate(&buffer_damage,<br>
+ go->borders[GL_RENDERER_BORDER_LEFT].width,<br>
+ go->borders[GL_RENDERER_BORDER_TOP].height);<br>
+ output_get_border_damage(output, go->border_status,<br>
+ &buffer_damage);<br>
+ }<br>
+<br>
+ rects = pixman_region32_rectangles(&buffer_damage, &nrects);<br>
+ egl_damage = malloc(nrects * 4 * sizeof(EGLint));<br>
+<br>
+ buffer_height = go->borders[GL_RENDERER_BORDER_TOP].height +<br>
+ output->current_mode->height +<br>
+ go->borders[GL_RENDERER_BORDER_BOTTOM].height;<br>
+<br>
+ d = egl_damage;<br>
+ for (i = 0; i < nrects; ++i) {<br>
+ *d++ = rects[i].x1;<br>
+ *d++ = buffer_height - rects[i].y2;<br>
+ *d++ = rects[i].x2 - rects[i].x1;<br>
+ *d++ = rects[i].y2 - rects[i].y1;<br>
+ }<br>
+ ret = gr->swap_buffers_with_damage(gr->egl_display,<br>
+ go->egl_surface,<br>
+ egl_damage, nrects);<br>
+ free(egl_damage);<br>
+ pixman_region32_fini(&buffer_damage);<br>
+ } else {<br>
+ ret = eglSwapBuffers(gr->egl_display, go->egl_surface);<br>
+ }<br>
+<br>
if (ret == EGL_FALSE && !errored) {<br>
errored = 1;<br>
weston_log("Failed in eglSwapBuffers.\n");<br>
@@ -1618,6 +1708,11 @@ gl_renderer_output_create(struct weston_output *output,<br>
return -1;<br>
}<br>
<br>
+ if (gr->swap_buffers_with_damage && gr->has_egl_buffer_age) {<br>
+ eglSurfaceAttrib(gr->egl_display, go->egl_surface,<br>
+ EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);<br>
+ }<br>
+<br>
for (i = 0; i < BUFFER_DAMAGE_COUNT; i++)<br>
pixman_region32_init(&go->buffer_damage[i]);<br>
<br>
@@ -1958,6 +2053,13 @@ gl_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface)<br>
weston_log("warning: EGL_EXT_buffer_age not supported. "<br>
"Performance could be affected.\n");<br>
<br>
+ if (strstr(extensions, "EGL_EXT_swap_buffers_with_damage"))<br>
+ gr->swap_buffers_with_damage =<br>
+ (void *) eglGetProcAddress("eglSwapBuffersWithDamageEXT");<br>
+ else<br>
+ weston_log("warning: EGL_EXT_swap_buffers_with_damage not "<br>
+ "supported. Performance could be affected.\n");<br>
+<br>
glActiveTexture(GL_TEXTURE0);<br>
<br>
if (compile_shaders(ec))<br>
--<br>
1.8.4.2<br>
<br>
</blockquote></div>