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 }