git.lucas.co / cce-compositor
Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git

scenefx/render/fx_renderer/fx_offscreen_buffers.c (2.5K)

 1 #include <stdlib.h>
 2 #include <wlr/types/wlr_output.h>
 3 #include <wlr/util/addon.h>
 4 #include <wlr/util/log.h>
 5 
 6 #include "render/fx_renderer/fx_renderer.h"
 7 #include "scenefx/render/fx_renderer/fx_renderer.h"
 8 #include "scenefx/render/fx_renderer/fx_offscreen_buffers.h"
 9 
10 static void addon_handle_destroy(struct wlr_addon *addon) {
11 	struct fx_offscreen_buffers *fbos = wl_container_of(addon, fbos, addon);
12 
13 	// Make sure to free the buffers
14 	if (fbos->optimized_blur_buffer != NULL) {
15 		wlr_buffer_drop(fbos->optimized_blur_buffer->buffer);
16 		fbos->optimized_blur_buffer = NULL;
17 	}
18 	if (fbos->optimized_no_blur_buffer != NULL) {
19 		wlr_buffer_drop(fbos->optimized_no_blur_buffer->buffer);
20 		fbos->optimized_no_blur_buffer = NULL;
21 	}
22 	if (fbos->blur_saved_pixels_buffer != NULL) {
23 		wlr_buffer_drop(fbos->blur_saved_pixels_buffer->buffer);
24 		fbos->blur_saved_pixels_buffer = NULL;
25 	}
26 	if (fbos->effects_buffer != NULL) {
27 		wlr_buffer_drop(fbos->effects_buffer->buffer);
28 		fbos->effects_buffer = NULL;
29 	}
30 	if (fbos->effects_buffer_swapped != NULL) {
31 		wlr_buffer_drop(fbos->effects_buffer_swapped->buffer);
32 		fbos->effects_buffer_swapped = NULL;
33 	}
34 
35 	wl_list_remove(&fbos->link);
36 	wlr_addon_finish(&fbos->addon);
37 	free(fbos);
38 }
39 
40 static const struct wlr_addon_interface fbos_addon_impl = {
41 	.name = "fx_offscreen_buffers",
42 	.destroy = addon_handle_destroy,
43 };
44 
45 static bool fx_offscreen_buffers_assign(struct wlr_output *output,
46 		struct fx_offscreen_buffers *fbos) {
47 	wlr_addon_init(&fbos->addon, &output->addons, output, &fbos_addon_impl);
48 	return true;
49 }
50 
51 void fx_offscreen_buffers_destroy(struct fx_offscreen_buffers *fbos) {
52 	addon_handle_destroy(&fbos->addon);
53 }
54 
55 struct fx_offscreen_buffers *fx_offscreen_buffers_try_get(struct wlr_output *output) {
56 	struct fx_offscreen_buffers *fbos = NULL;
57 	if (!output) {
58 		return NULL;
59 	}
60 
61 	struct wlr_addon *addon = wlr_addon_find(&output->addons, output,
62 			&fbos_addon_impl);
63 	if (!addon) {
64 		goto create_new;
65 	}
66 
67 	if (!(fbos = wl_container_of(addon, fbos, addon))) {
68 		goto create_new;
69 	}
70 	return fbos;
71 
72 create_new:;
73 	struct fx_renderer *renderer = fx_get_renderer(output->renderer);
74 	if (!renderer) {
75 		return NULL;
76 	}
77 
78 	fbos = calloc(1, sizeof(*fbos));
79 	if (!fbos) {
80 		wlr_log(WLR_ERROR, "Could not allocate a fx_offscreen_buffers");
81 		return NULL;
82 	}
83 
84 	if (!fx_offscreen_buffers_assign(output, fbos)) {
85 		wlr_log(WLR_ERROR, "Could not assign fx_offscreen_buffers to output: '%s'",
86 				output->name);
87 		free(fbos);
88 		return NULL;
89 	}
90 	wl_list_insert(&renderer->offscreen_buffers, &fbos->link);
91 	return fbos;
92 }