1
0
mirror of https://codeberg.org/vyivel/dulcepan/ synced 2025-03-12 18:59:15 +02:00

output: make swapchain lazy

This commit is contained in:
Kirill Primak 2024-08-09 15:57:45 +03:00
parent bdf8308c4e
commit e797e5a324
2 changed files with 22 additions and 17 deletions

View File

@ -71,6 +71,7 @@ struct dp_output {
void *frame_data; void *frame_data;
size_t frame_size; size_t frame_size;
// wl_buffer is NULL if uninitialized
struct dp_buffer swapchain[DP_SWAPCHAIN_LEN]; struct dp_buffer swapchain[DP_SWAPCHAIN_LEN];
struct wl_list link; struct wl_list link;

View File

@ -126,6 +126,19 @@ static const struct wl_buffer_listener buffer_listener = {
.release = buffer_handle_release, .release = buffer_handle_release,
}; };
static void init_buffer(struct dp_output *output, struct dp_buffer *buffer) {
int stride = output->transformed_width * 4;
buffer->wl_buffer =
dp_buffer_create(output->state, output->transformed_width, output->transformed_height,
stride, WL_SHM_FORMAT_ARGB8888, &buffer->data, &buffer->size);
buffer->cairo_surface = cairo_image_surface_create_for_data(buffer->data, CAIRO_FORMAT_ARGB32,
output->transformed_width, output->transformed_height, stride);
buffer->cairo = cairo_create(buffer->cairo_surface);
wl_buffer_add_listener(buffer->wl_buffer, &buffer_listener, buffer);
}
static void output_handle_geometry(void *data, struct wl_output *wl_output, int32_t x, int32_t y, static void output_handle_geometry(void *data, struct wl_output *wl_output, int32_t x, int32_t y,
int32_t phys_width, int32_t phys_height, int32_t subpixel, const char *make, int32_t phys_width, int32_t phys_height, int32_t subpixel, const char *make,
const char *model, int32_t transform) { const char *model, int32_t transform) {
@ -208,19 +221,6 @@ static void output_handle_done(void *data, struct wl_output *wl_output) {
wl_subsurface_set_desync(output->select_subsurface); wl_subsurface_set_desync(output->select_subsurface);
wl_surface_set_user_data(output->select_surface, output); wl_surface_set_user_data(output->select_surface, output);
for (size_t i = 0; i < DP_SWAPCHAIN_LEN; i++) {
struct dp_buffer *buffer = &output->swapchain[i];
int stride = output->transformed_width * 4;
buffer->wl_buffer =
dp_buffer_create(state, output->transformed_width, output->transformed_height,
stride, WL_SHM_FORMAT_ARGB8888, &buffer->data, &buffer->size);
buffer->cairo_surface = cairo_image_surface_create_for_data(buffer->data,
CAIRO_FORMAT_ARGB32, output->transformed_width, output->transformed_height, stride);
buffer->cairo = cairo_create(buffer->cairo_surface);
wl_buffer_add_listener(buffer->wl_buffer, &buffer_listener, buffer);
}
} }
static void output_handle_scale(void *data, struct wl_output *wl_output, int32_t scale) { static void output_handle_scale(void *data, struct wl_output *wl_output, int32_t scale) {
@ -330,6 +330,8 @@ static void redraw(struct dp_output *output) {
if (buffer == NULL) { if (buffer == NULL) {
dp_log_error("Output %s: no free buffers in a swapchain\n", output->name); dp_log_error("Output %s: no free buffers in a swapchain\n", output->name);
return; return;
} else if (buffer->wl_buffer == NULL) {
init_buffer(output, buffer);
} }
buffer->used = true; buffer->used = true;
@ -438,11 +440,13 @@ void dp_output_destroy(struct dp_output *output) {
for (size_t i = 0; i < DP_SWAPCHAIN_LEN; i++) { for (size_t i = 0; i < DP_SWAPCHAIN_LEN; i++) {
struct dp_buffer *buffer = &output->swapchain[i]; struct dp_buffer *buffer = &output->swapchain[i];
if (buffer->wl_buffer != NULL) {
wl_buffer_destroy(buffer->wl_buffer); wl_buffer_destroy(buffer->wl_buffer);
cairo_destroy(buffer->cairo); cairo_destroy(buffer->cairo);
cairo_surface_destroy(buffer->cairo_surface); cairo_surface_destroy(buffer->cairo_surface);
munmap(buffer->data, buffer->size); munmap(buffer->data, buffer->size);
} }
}
wl_subsurface_destroy(output->select_subsurface); wl_subsurface_destroy(output->select_subsurface);
wp_viewport_destroy(output->select_viewport); wp_viewport_destroy(output->select_viewport);