gl-renderer: Use EXT_buffer_age and don't assume double buffering
Now that we have EXT_buffer_age in mesa, we should stop assuming double buffering and use the buffer age instead. Note: this will cause system without the extension to repaint the whole screen every frame.
This commit is contained in:
committed by
Kristian Høgsberg
parent
e1bd5a02a0
commit
1c169ffdec
+66
-20
@@ -46,10 +46,11 @@ struct gl_shader {
|
|||||||
GLint color_uniform;
|
GLint color_uniform;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define BUFFER_DAMAGE_COUNT 2
|
||||||
|
|
||||||
struct gl_output_state {
|
struct gl_output_state {
|
||||||
EGLSurface egl_surface;
|
EGLSurface egl_surface;
|
||||||
int current_buffer;
|
pixman_region32_t buffer_damage[BUFFER_DAMAGE_COUNT];
|
||||||
pixman_region32_t buffer_damage[2];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gl_surface_state {
|
struct gl_surface_state {
|
||||||
@@ -95,6 +96,8 @@ struct gl_renderer {
|
|||||||
|
|
||||||
int has_egl_image_external;
|
int has_egl_image_external;
|
||||||
|
|
||||||
|
int has_egl_buffer_age;
|
||||||
|
|
||||||
struct gl_shader texture_shader_rgba;
|
struct gl_shader texture_shader_rgba;
|
||||||
struct gl_shader texture_shader_rgbx;
|
struct gl_shader texture_shader_rgbx;
|
||||||
struct gl_shader texture_shader_egl_external;
|
struct gl_shader texture_shader_egl_external;
|
||||||
@@ -742,12 +745,10 @@ draw_surface(struct weston_surface *es, struct weston_output *output,
|
|||||||
struct weston_compositor *ec = es->compositor;
|
struct weston_compositor *ec = es->compositor;
|
||||||
struct gl_renderer *gr = get_renderer(ec);
|
struct gl_renderer *gr = get_renderer(ec);
|
||||||
struct gl_surface_state *gs = get_surface_state(es);
|
struct gl_surface_state *gs = get_surface_state(es);
|
||||||
struct gl_output_state *go = get_output_state(output);
|
|
||||||
/* repaint bounding region in global coordinates: */
|
/* repaint bounding region in global coordinates: */
|
||||||
pixman_region32_t repaint;
|
pixman_region32_t repaint;
|
||||||
/* non-opaque region in surface coordinates: */
|
/* non-opaque region in surface coordinates: */
|
||||||
pixman_region32_t surface_blend;
|
pixman_region32_t surface_blend;
|
||||||
pixman_region32_t *buffer_damage;
|
|
||||||
GLint filter;
|
GLint filter;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -759,9 +760,6 @@ draw_surface(struct weston_surface *es, struct weston_output *output,
|
|||||||
if (!pixman_region32_not_empty(&repaint))
|
if (!pixman_region32_not_empty(&repaint))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
buffer_damage = &go->buffer_damage[go->current_buffer];
|
|
||||||
pixman_region32_subtract(buffer_damage, buffer_damage, &repaint);
|
|
||||||
|
|
||||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
if (ec->fan_debug) {
|
if (ec->fan_debug) {
|
||||||
@@ -947,6 +945,51 @@ draw_border(struct weston_output *output)
|
|||||||
ec->indices.size = 0;
|
ec->indices.size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
output_get_buffer_damage(struct weston_output *output,
|
||||||
|
pixman_region32_t *buffer_damage)
|
||||||
|
{
|
||||||
|
struct gl_output_state *go = get_output_state(output);
|
||||||
|
struct gl_renderer *gr = get_renderer(output->compositor);
|
||||||
|
EGLint buffer_age = 0;
|
||||||
|
EGLBoolean ret;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (gr->has_egl_buffer_age) {
|
||||||
|
ret = eglQuerySurface(gr->egl_display, go->egl_surface,
|
||||||
|
EGL_BUFFER_AGE_EXT, &buffer_age);
|
||||||
|
if (ret == EGL_FALSE) {
|
||||||
|
weston_log("buffer age query failed.\n");
|
||||||
|
gl_renderer_print_egl_error_state();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffer_age == 0 || buffer_age - 1 > BUFFER_DAMAGE_COUNT)
|
||||||
|
pixman_region32_copy(buffer_damage, &output->region);
|
||||||
|
else
|
||||||
|
for (i = 0; i < buffer_age - 1; i++)
|
||||||
|
pixman_region32_union(buffer_damage, buffer_damage,
|
||||||
|
&go->buffer_damage[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
output_rotate_damage(struct weston_output *output,
|
||||||
|
pixman_region32_t *output_damage)
|
||||||
|
{
|
||||||
|
struct gl_output_state *go = get_output_state(output);
|
||||||
|
struct gl_renderer *gr = get_renderer(output->compositor);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!gr->has_egl_buffer_age)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = BUFFER_DAMAGE_COUNT - 1; i >= 1; i--)
|
||||||
|
pixman_region32_copy(&go->buffer_damage[i],
|
||||||
|
&go->buffer_damage[i - 1]);
|
||||||
|
|
||||||
|
pixman_region32_copy(&go->buffer_damage[0], output_damage);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gl_renderer_repaint_output(struct weston_output *output,
|
gl_renderer_repaint_output(struct weston_output *output,
|
||||||
pixman_region32_t *output_damage)
|
pixman_region32_t *output_damage)
|
||||||
@@ -956,8 +999,8 @@ gl_renderer_repaint_output(struct weston_output *output,
|
|||||||
struct gl_renderer *gr = get_renderer(compositor);
|
struct gl_renderer *gr = get_renderer(compositor);
|
||||||
EGLBoolean ret;
|
EGLBoolean ret;
|
||||||
static int errored;
|
static int errored;
|
||||||
int32_t width, height, i;
|
int32_t width, height;
|
||||||
pixman_region32_t total_damage;
|
pixman_region32_t buffer_damage, total_damage;
|
||||||
|
|
||||||
width = output->current->width +
|
width = output->current->width +
|
||||||
output->border.left + output->border.right;
|
output->border.left + output->border.right;
|
||||||
@@ -983,18 +1026,18 @@ gl_renderer_repaint_output(struct weston_output *output,
|
|||||||
pixman_region32_fini(&undamaged);
|
pixman_region32_fini(&undamaged);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < 2; i++)
|
|
||||||
pixman_region32_union(&go->buffer_damage[i],
|
|
||||||
&go->buffer_damage[i],
|
|
||||||
output_damage);
|
|
||||||
|
|
||||||
pixman_region32_init(&total_damage);
|
pixman_region32_init(&total_damage);
|
||||||
pixman_region32_copy(&total_damage,
|
pixman_region32_init(&buffer_damage);
|
||||||
&go->buffer_damage[go->current_buffer]);
|
|
||||||
|
output_get_buffer_damage(output, &buffer_damage);
|
||||||
|
output_rotate_damage(output, output_damage);
|
||||||
|
|
||||||
|
pixman_region32_union(&total_damage, &buffer_damage, output_damage);
|
||||||
|
|
||||||
repaint_surfaces(output, &total_damage);
|
repaint_surfaces(output, &total_damage);
|
||||||
|
|
||||||
pixman_region32_fini(&total_damage);
|
pixman_region32_fini(&total_damage);
|
||||||
|
pixman_region32_fini(&buffer_damage);
|
||||||
|
|
||||||
if (gr->border.texture)
|
if (gr->border.texture)
|
||||||
draw_border(output);
|
draw_border(output);
|
||||||
@@ -1009,8 +1052,6 @@ gl_renderer_repaint_output(struct weston_output *output,
|
|||||||
gl_renderer_print_egl_error_state();
|
gl_renderer_print_egl_error_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
go->current_buffer ^= 1;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -1620,8 +1661,7 @@ gl_renderer_output_create(struct weston_output *output,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
go->current_buffer = 0;
|
for (i = 0; i < BUFFER_DAMAGE_COUNT; i++)
|
||||||
for (i = 0; i < 2; i++)
|
|
||||||
pixman_region32_init(&go->buffer_damage[i]);
|
pixman_region32_init(&go->buffer_damage[i]);
|
||||||
|
|
||||||
output->renderer_state = go;
|
output->renderer_state = go;
|
||||||
@@ -1931,6 +1971,12 @@ gl_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface)
|
|||||||
gr->has_bind_display = 0;
|
gr->has_bind_display = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strstr(extensions, "EGL_EXT_buffer_age"))
|
||||||
|
gr->has_egl_buffer_age = 1;
|
||||||
|
else
|
||||||
|
weston_log("warning: EGL_EXT_buffer_age not supported. "
|
||||||
|
"Performance could be affected.\n");
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
if (compile_shaders(ec))
|
if (compile_shaders(ec))
|
||||||
|
|||||||
Reference in New Issue
Block a user