<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>