GCC Code Coverage Report


Directory: src/gate/
File: src/gate/graphics/framebuffers.c
Date: 2026-02-03 22:06:38
Exec Total Coverage
Lines: 32 86 37.2%
Functions: 3 14 21.4%
Branches: 5 32 15.6%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright(c) 2018-2026, Stefan Meislinger |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28
29 #include "gate/graphics/framebuffers.h"
30 #include "gate/atomics.h"
31 #include "gate/results.h"
32 #include "gate/times.h"
33
34 #if defined(GATE_SYS_WINSTORE)
35 # define GATE_GRAPHICS_FRAMEBUFFERS_DIRECTX
36 #elif defined(GATE_SYS_WIN16)
37 # define GATE_GRAPHICS_FRAMEBUFFERS_WIN16
38 #elif defined(GATE_SYS_WIN)
39 # define GATE_GRAPHICS_FRAMEBUFFERS_WIN32
40 #elif defined(GATE_SYS_ANDROID)
41 # define GATE_GRAPHICS_FRAMEBUFFERS_GL
42 #elif defined(GATE_SYS_OPENBSD) || defined(GATE_SYS_BEOS)
43 # define GATE_GRAPHICS_FRAMEBUFFERS_NOIMPL
44 #elif defined(GATE_SYS_DARWIN)
45 # define GATE_GRAPHICS_FRAMEBUFFERS_NOIMPL
46 #elif defined(GATE_SYS_POSIX)
47 # if defined(GATE_GRAPHICS_WAYLAND)
48 # define GATE_GRAPHICS_FRAMEBUFFERS_WAYLAND 1
49 # else
50 # if defined(HAVE_X11_HEADERS)
51 # define GATE_GRAPHICS_FRAMEBUFFERS_XLIB 1
52 # else
53 # define GATE_GRAPHICS_FRAMEBUFFERS_NOIMPL
54 # endif
55 # endif
56 #elif defined(GATE_SYS_EFI)
57 # define GATE_GRAPHICS_FRAMEBUFFERS_UGA
58 #elif defined(GATE_SYS_DOS)
59 # define GATE_GRAPHICS_FRAMEBUFFERS_INT10
60 #elif defined(GATE_SYS_WASM)
61 # define GATE_GRAPHICS_FRAMEBUFFERS_WASM
62 #else
63 # define GATE_GRAPHICS_FRAMEBUFFERS_NOIMPL
64 #endif
65
66
67
68 /**************************************************
69 * generic rasterimage framebuffer implementation *
70 **************************************************/
71
72 typedef struct rasterfb_impl
73 {
74 GATE_INTERFACE_VTBL(gate_framebuffer) const* vtbl;
75
76 gate_atomic_int_t ref_counter;
77 gate_rasterimage_t image_header;
78 gate_uint8_t image_data[8];
79 } rasterfb_t;
80
81
82 static char const* rasterfb_get_interface_name(void* obj)
83 {
84 GATE_UNUSED_ARG(obj);
85 return GATE_INTERFACE_NAME_FRAMEBUFFER;
86 }
87 1 static void rasterfb_release(void* obj)
88 {
89 1 rasterfb_t* const impl = (rasterfb_t*)obj;
90
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if (0 == gate_atomic_int_dec(&impl->ref_counter))
91 {
92 1 gate_mem_clear(impl, sizeof(rasterfb_t));
93 1 gate_mem_dealloc(impl);
94 }
95 1 }
96 static int rasterfb_retain(void* obj)
97 {
98 rasterfb_t* const impl = (rasterfb_t*)obj;
99 return gate_atomic_int_inc(&impl->ref_counter);
100 }
101
102 static gate_result_t rasterfb_get_info(void* obj, gate_framebuffer_info_t* ptr_info)
103 {
104 rasterfb_t* const impl = (rasterfb_t*)obj;
105 gate_result_t ret = GATE_RESULT_INVALIDARG;
106 if (impl && ptr_info)
107 {
108 ptr_info->width = gate_rasterimage_width(&impl->image_header);
109 ptr_info->height = gate_rasterimage_height(&impl->image_header);
110 ptr_info->bits_per_pixel = 32;
111 ptr_info->format_id = 0;
112 ret = GATE_RESULT_OK;
113 }
114 return ret;
115 }
116
117 static gate_result_t rasterfb_get_property(void* obj, gate_string_t const* name, gate_property_t* prop)
118 {
119 GATE_UNUSED_ARG(obj);
120 GATE_UNUSED_ARG(name);
121 GATE_UNUSED_ARG(prop);
122 return GATE_RESULT_NOTSUPPORTED;
123 }
124
125 static gate_result_t rasterfb_set_property(void* obj, gate_string_t const* name, gate_property_t const* prop)
126 {
127 GATE_UNUSED_ARG(obj);
128 GATE_UNUSED_ARG(name);
129 GATE_UNUSED_ARG(prop);
130 return GATE_RESULT_NOTSUPPORTED;
131 }
132
133 static gate_result_t rasterfb_update(void* obj)
134 {
135 /* rasterimage framebuffer is always up-to-date */
136 GATE_UNUSED_ARG(obj);
137 return GATE_RESULT_OK;
138 }
139
140 static gate_result_t rasterfb_get_pixel(void* obj, gate_uint32_t x, gate_uint32_t y, gate_color_t* ptr_col)
141 {
142 rasterfb_t* const impl = (rasterfb_t*)obj;
143 return gate_rasterimage_get_pixel(&impl->image_header, x, y, ptr_col);
144 }
145
146 static gate_result_t rasterfb_set_pixel(void* obj, gate_uint32_t x, gate_uint32_t y, gate_color_t col)
147 {
148 rasterfb_t* const impl = (rasterfb_t*)obj;
149 return gate_rasterimage_set_pixel(&impl->image_header, x, y, &col);
150 }
151
152 static gate_result_t rasterfb_get_image(void* obj, gate_uint32_t src_x, gate_uint32_t src_y, gate_uint32_t width, gate_uint32_t height, gate_rasterimage_t* ptr_image)
153 {
154 rasterfb_t* const impl = (rasterfb_t*)obj;
155 gate_result_t ret = GATE_RESULT_FAILED;
156 gate_uint32_t fb_width = gate_rasterimage_width(&impl->image_header);
157 gate_uint32_t fb_height = gate_rasterimage_height(&impl->image_header);
158
159 if ((src_x == 0) && (src_y == 0) && (((width == 0) && (height == 0)) || ((width == fb_width) && (height == fb_height))))
160 {
161 if (gate_rasterimage_copy(ptr_image, &impl->image_header))
162 {
163 ret = GATE_RESULT_OK;
164 }
165 }
166 else
167 {
168 do
169 {
170 if (!gate_rasterimage_create(ptr_image, GATE_IMAGE_PIXELFORMAT_BGR32, width, height, NULL))
171 {
172 ret = GATE_RESULT_OUTOFMEMORY;
173 break;
174 }
175 ret = gate_rasterimage_paste_image(ptr_image, &impl->image_header, 0, 0, src_x, src_y, width, height, false);
176 if (GATE_FAILED(ret))
177 {
178 gate_rasterimage_release(ptr_image);
179 }
180 } while (0);
181 }
182 return ret;
183 }
184
185 static gate_result_t rasterfb_set_image(void* obj, gate_rasterimage_t const* ptr_image, gate_uint32_t dest_x, gate_uint32_t dest_y)
186 {
187 rasterfb_t* const impl = (rasterfb_t*)obj;
188 gate_result_t ret = GATE_RESULT_FAILED;
189 gate_uint32_t width = gate_rasterimage_width(ptr_image);
190 gate_uint32_t height = gate_rasterimage_height(ptr_image);
191
192 ret = gate_rasterimage_paste_image(&impl->image_header, ptr_image, dest_x, dest_y, 0, 0, width, height, false);
193 return ret;
194 }
195
196 static gate_result_t rasterfb_await_event(void* obj, gate_uint32_t timeout_ms, gate_framebuffer_event_t* ptr_received_evt)
197 {
198 GATE_UNUSED_ARG(obj);
199 GATE_UNUSED_ARG(timeout_ms);
200 GATE_UNUSED_ARG(ptr_received_evt);
201 return GATE_RESULT_NOTSUPPORTED;
202 }
203
204 static GATE_INTERFACE_VTBL(gate_framebuffer) gate_rasterfb_vtbl;
205 1 static void gate_init_rasterfb_vtbl()
206 {
207
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (!gate_rasterfb_vtbl.get_interface_name)
208 {
209 GATE_INTERFACE_VTBL(gate_framebuffer) const local_vtbl =
210 {
211 &rasterfb_get_interface_name,
212 &rasterfb_release,
213 &rasterfb_retain,
214
215 &rasterfb_get_info,
216 &rasterfb_get_property,
217 &rasterfb_set_property,
218
219 &rasterfb_update,
220
221 &rasterfb_get_pixel,
222 &rasterfb_set_pixel,
223
224 &rasterfb_get_image,
225 &rasterfb_set_image,
226
227 &rasterfb_await_event
228 };
229
230 1 gate_rasterfb_vtbl = local_vtbl;
231 }
232 1 }
233
234
235 1 gate_result_t gate_framebuffer_create_image(gate_uint32_t width, gate_uint32_t height, gate_framebuffer_t** ptr_framebuffer)
236 {
237 1 rasterfb_t* impl = NULL;
238 1 gate_result_t ret = GATE_RESULT_FAILED;
239 gate_size_t datasize;
240
241 do
242 {
243 1 datasize = sizeof(gate_color_t) * width * height;
244 1 impl = (rasterfb_t*)gate_mem_alloc(sizeof(rasterfb_t) + datasize);
245
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!impl)
246 {
247 ret = GATE_RESULT_OUTOFMEMORY;
248 break;
249 }
250 1 gate_init_rasterfb_vtbl();
251 1 impl->vtbl = &gate_rasterfb_vtbl;
252 1 gate_atomic_int_init(&impl->ref_counter, 1);
253
254 1 impl->image_header.width = width;
255 1 impl->image_header.height = height;
256 1 impl->image_header.line_padding = 0;
257 1 impl->image_header.bits_per_pixel = sizeof(gate_color_t) * 8;
258 1 impl->image_header.data = &impl->image_data[0];
259 1 impl->image_header.databuffer = NULL;
260
261 1 gate_mem_clear(&impl->image_data[0], datasize);
262
263
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (ptr_framebuffer)
264 {
265 1 *ptr_framebuffer = (gate_framebuffer_t*)impl;
266 1 impl = NULL;
267 }
268 1 ret = GATE_RESULT_OK;
269 } while (0);
270
271
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (impl)
272 {
273 gate_mem_dealloc(impl);
274 }
275 1 return ret;
276 }
277
278
279
280 #if defined(GATE_GRAPHICS_FRAMEBUFFERS_DIRECTX)
281 #include "gate/graphics/platform/framebuffers_impl_directx.h"
282 #endif /* GATE_GRAPHICS_FRAMEBUFFERS_DIRECTX */
283
284
285 #if defined(GATE_GRAPHICS_FRAMEBUFFERS_WIN16)
286 #include "gate/graphics/platform/framebuffers_impl_win16.h"
287 #endif /* GATE_GRAPHICS_FRAMEBUFFERS_WIN16 */
288
289
290 #if defined(GATE_GRAPHICS_FRAMEBUFFERS_WIN32)
291 #include "gate/graphics/platform/framebuffers_impl_win32.h"
292 #endif /* GATE_GRAPHICS_FRAMEBUFFERS_WIN32 */
293
294
295 #if defined(GATE_GRAPHICS_FRAMEBUFFERS_WAYLAND)
296 #include "gate/graphics/platform/framebuffers_impl_wayland.h"
297 #endif /* GATE_GRAPHICS_FRAMEBUFFERS_WAYLAND */
298
299 #if defined(GATE_GRAPHICS_FRAMEBUFFERS_XLIB)
300 #include "gate/graphics/platform/framebuffers_impl_xlib.h"
301 #endif /* GATE_GRAPHICS_FRAMEBUFFERS_XLIB */
302
303
304 #if defined(GATE_GRAPHICS_FRAMEBUFFERS_GL)
305 #include "gate/graphics/platform/framebuffers_impl_gl.h"
306 #endif /* GATE_GRAPHICS_FRAMEBUFFERS_GL */
307
308
309 #if defined(GATE_GRAPHICS_FRAMEBUFFERS_UGA)
310 #include "gate/graphics/platform/framebuffers_impl_efigop.h"
311 #endif /* GATE_GRAPHICS_FRAMEBUFFERS_UGA */
312
313
314 #if defined(GATE_GRAPHICS_FRAMEBUFFERS_INT10)
315 #include "gate/graphics/platform/framebuffers_impl_int10.h"
316 #endif /* GATE_GRAPHICS_FRAMEBUFFERS_INT10 */
317
318
319 #if defined(GATE_GRAPHICS_FRAMEBUFFERS_WASM)
320 #include "gate/graphics/platform/framebuffers_impl_wasm.h"
321 #endif /* GATE_GRAPHICS_FRAMEBUFFERS_WASM */
322
323 #if defined(GATE_GRAPHICS_FRAMEBUFFERS_NOIMPL)
324
325 gate_size_t gate_framebuffer_enum_displays(gate_framebuffer_info_t* ptr_infos, gate_size_t infos_capacity)
326 {
327 GATE_UNUSED_ARG(ptr_infos);
328 GATE_UNUSED_ARG(infos_capacity);
329 return 0;
330 }
331
332 gate_result_t gate_framebuffer_find_display(gate_uint32_t required_width, gate_uint32_t required_height, gate_framebuffer_info_t* ptr_found_display_info)
333 {
334 GATE_UNUSED_ARG(required_width);
335 GATE_UNUSED_ARG(required_height);
336 GATE_UNUSED_ARG(ptr_found_display_info);
337 return GATE_RESULT_NOMATCH;
338 }
339
340 gate_result_t gate_framebuffer_open_display(gate_framebuffer_info_t const* ptr_infos, gate_framebuffer_t** ptr_framebuffer)
341 {
342 GATE_UNUSED_ARG(ptr_infos);
343 GATE_UNUSED_ARG(ptr_framebuffer);
344 return GATE_RESULT_NOMATCH;
345 }
346
347
348 #endif /* GATE_GRAPHICS_FRAMEBUFFERS_NOIMPL */
349