output: fullscreen surface damage tracking
This commit is contained in:
parent
977a401fa1
commit
443bd4cd89
|
@ -53,7 +53,7 @@ struct wlr_output {
|
||||||
enum wl_output_subpixel subpixel;
|
enum wl_output_subpixel subpixel;
|
||||||
enum wl_output_transform transform;
|
enum wl_output_transform transform;
|
||||||
|
|
||||||
pixman_region32_t damage;
|
pixman_region32_t damage, previous_damage;
|
||||||
float transform_matrix[16];
|
float transform_matrix[16];
|
||||||
|
|
||||||
// Note: some backends may have zero modes
|
// Note: some backends may have zero modes
|
||||||
|
|
|
@ -280,6 +280,7 @@ void wlr_output_init(struct wlr_output *output, struct wlr_backend *backend,
|
||||||
wl_signal_init(&output->events.transform);
|
wl_signal_init(&output->events.transform);
|
||||||
wl_signal_init(&output->events.destroy);
|
wl_signal_init(&output->events.destroy);
|
||||||
pixman_region32_init(&output->damage);
|
pixman_region32_init(&output->damage);
|
||||||
|
pixman_region32_init(&output->previous_damage);
|
||||||
|
|
||||||
output->display_destroy.notify = handle_display_destroy;
|
output->display_destroy.notify = handle_display_destroy;
|
||||||
wl_display_add_destroy_listener(display, &output->display_destroy);
|
wl_display_add_destroy_listener(display, &output->display_destroy);
|
||||||
|
@ -293,7 +294,6 @@ void wlr_output_destroy(struct wlr_output *output) {
|
||||||
wl_list_remove(&output->display_destroy.link);
|
wl_list_remove(&output->display_destroy.link);
|
||||||
wlr_output_destroy_global(output);
|
wlr_output_destroy_global(output);
|
||||||
wlr_output_set_fullscreen_surface(output, NULL);
|
wlr_output_set_fullscreen_surface(output, NULL);
|
||||||
pixman_region32_fini(&output->damage);
|
|
||||||
|
|
||||||
wl_signal_emit(&output->events.destroy, output);
|
wl_signal_emit(&output->events.destroy, output);
|
||||||
|
|
||||||
|
@ -308,6 +308,9 @@ void wlr_output_destroy(struct wlr_output *output) {
|
||||||
wlr_output_cursor_destroy(cursor);
|
wlr_output_cursor_destroy(cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pixman_region32_fini(&output->damage);
|
||||||
|
pixman_region32_fini(&output->previous_damage);
|
||||||
|
|
||||||
if (output->impl && output->impl->destroy) {
|
if (output->impl && output->impl->destroy) {
|
||||||
output->impl->destroy(output);
|
output->impl->destroy(output);
|
||||||
} else {
|
} else {
|
||||||
|
@ -347,12 +350,15 @@ static void output_fullscreen_surface_get_box(struct wlr_output *output,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void output_fullscreen_surface_render(struct wlr_output *output,
|
static void output_fullscreen_surface_render(struct wlr_output *output,
|
||||||
struct wlr_surface *surface, const struct timespec *when) {
|
struct wlr_surface *surface, const struct timespec *when,
|
||||||
|
pixman_region32_t *damage) {
|
||||||
glViewport(0, 0, output->width, output->height);
|
glViewport(0, 0, output->width, output->height);
|
||||||
glClearColor(0, 0, 0, 0);
|
glEnable(GL_BLEND);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
if (!wlr_surface_has_buffer(surface)) {
|
if (!wlr_surface_has_buffer(surface)) {
|
||||||
|
glClearColor(0, 0, 0, 0);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,7 +375,17 @@ static void output_fullscreen_surface_render(struct wlr_output *output,
|
||||||
wlr_matrix_mul(&translate, &scale, &matrix);
|
wlr_matrix_mul(&translate, &scale, &matrix);
|
||||||
wlr_matrix_mul(&output->transform_matrix, &matrix, &matrix);
|
wlr_matrix_mul(&output->transform_matrix, &matrix, &matrix);
|
||||||
|
|
||||||
|
int nrects;
|
||||||
|
pixman_box32_t *rects = pixman_region32_rectangles(damage, &nrects);
|
||||||
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
for (int i = 0; i < nrects; ++i) {
|
||||||
|
glScissor(rects[i].x1, output->height - rects[i].y2,
|
||||||
|
rects[i].x2 - rects[i].x1, rects[i].y2 - rects[i].y1);
|
||||||
|
glClearColor(0, 0, 0, 0);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
wlr_render_with_matrix(surface->renderer, surface->texture, &matrix);
|
wlr_render_with_matrix(surface->renderer, surface->texture, &matrix);
|
||||||
|
}
|
||||||
|
glDisable(GL_SCISSOR_TEST);
|
||||||
|
|
||||||
wlr_surface_send_frame_done(surface, when);
|
wlr_surface_send_frame_done(surface, when);
|
||||||
}
|
}
|
||||||
|
@ -434,8 +450,17 @@ void wlr_output_swap_buffers(struct wlr_output *output) {
|
||||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
|
|
||||||
if (output->fullscreen_surface != NULL) {
|
if (output->fullscreen_surface != NULL) {
|
||||||
|
pixman_region32_t damage;
|
||||||
|
pixman_region32_init(&damage);
|
||||||
|
pixman_region32_copy(&damage, &output->damage);
|
||||||
|
pixman_region32_union(&damage, &damage, &output->previous_damage);
|
||||||
|
|
||||||
|
if (pixman_region32_not_empty(&damage)) {
|
||||||
output_fullscreen_surface_render(output, output->fullscreen_surface,
|
output_fullscreen_surface_render(output, output->fullscreen_surface,
|
||||||
&now);
|
&now, &damage);
|
||||||
|
}
|
||||||
|
|
||||||
|
pixman_region32_fini(&damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_output_cursor *cursor;
|
struct wlr_output_cursor *cursor;
|
||||||
|
@ -448,6 +473,7 @@ void wlr_output_swap_buffers(struct wlr_output *output) {
|
||||||
}
|
}
|
||||||
|
|
||||||
output->impl->swap_buffers(output);
|
output->impl->swap_buffers(output);
|
||||||
|
pixman_region32_copy(&output->previous_damage, &output->damage);
|
||||||
pixman_region32_clear(&output->damage);
|
pixman_region32_clear(&output->damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue