GCC Code Coverage Report


Directory: src/gate/
File: src/gate/graphics/framebuffers.c
Date: 2025-12-12 23:40:09
Exec Total Coverage
Lines: 0 86 0.0%
Functions: 0 14 0.0%
Branches: 0 32 0.0%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright(c) 2018-2025, 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 static void rasterfb_release(void* obj)
88 {
89 rasterfb_t* const impl = (rasterfb_t*)obj;
90 if (0 == gate_atomic_int_dec(&impl->ref_counter))
91 {
92 gate_mem_clear(impl, sizeof(rasterfb_t));
93 gate_mem_dealloc(impl);
94 }
95 }
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 static gate_result_t rasterfb_get_property(void* obj, gate_string_t const* name, gate_property_t* prop)
117 {
118 GATE_UNUSED_ARG(obj);
119 GATE_UNUSED_ARG(name);
120 GATE_UNUSED_ARG(prop);
121 return GATE_RESULT_NOTSUPPORTED;
122 }
123 static gate_result_t rasterfb_set_property(void* obj, gate_string_t const* name, gate_property_t const* prop)
124 {
125 GATE_UNUSED_ARG(obj);
126 GATE_UNUSED_ARG(name);
127 GATE_UNUSED_ARG(prop);
128 return GATE_RESULT_NOTSUPPORTED;
129 }
130
131 static gate_result_t rasterfb_update(void* obj)
132 {
133 /* rasterimage framebuffer is always up-to-date */
134 GATE_UNUSED_ARG(obj);
135 return GATE_RESULT_OK;
136 }
137
138 static gate_result_t rasterfb_get_pixel(void* obj, gate_uint32_t x, gate_uint32_t y, gate_color_t* ptr_col)
139 {
140 rasterfb_t* const impl = (rasterfb_t*)obj;
141 return gate_rasterimage_get_pixel(&impl->image_header, x, y, ptr_col);
142 }
143 static gate_result_t rasterfb_set_pixel(void* obj, gate_uint32_t x, gate_uint32_t y, gate_color_t col)
144 {
145 rasterfb_t* const impl = (rasterfb_t*)obj;
146 return gate_rasterimage_set_pixel(&impl->image_header, x, y, &col);
147 }
148
149 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)
150 {
151 rasterfb_t* const impl = (rasterfb_t*)obj;
152 gate_result_t ret = GATE_RESULT_FAILED;
153 gate_uint32_t fb_width = gate_rasterimage_width(&impl->image_header);
154 gate_uint32_t fb_height = gate_rasterimage_height(&impl->image_header);
155
156 if ((src_x == 0) && (src_y == 0) && (((width == 0) && (height == 0)) || ((width == fb_width) && (height == fb_height))))
157 {
158 if (gate_rasterimage_copy(ptr_image, &impl->image_header))
159 {
160 ret = GATE_RESULT_OK;
161 }
162 }
163 else
164 {
165 do
166 {
167 if (!gate_rasterimage_create(ptr_image, GATE_IMAGE_PIXELFORMAT_BGR32, width, height, NULL))
168 {
169 ret = GATE_RESULT_OUTOFMEMORY;
170 break;
171 }
172 ret = gate_rasterimage_paste_image(ptr_image, &impl->image_header, 0, 0, src_x, src_y, width, height, false);
173 if (GATE_FAILED(ret))
174 {
175 gate_rasterimage_release(ptr_image);
176 }
177 } while (0);
178 }
179 return ret;
180 }
181
182 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)
183 {
184 rasterfb_t* const impl = (rasterfb_t*)obj;
185 gate_result_t ret = GATE_RESULT_FAILED;
186 gate_uint32_t width = gate_rasterimage_width(ptr_image);
187 gate_uint32_t height = gate_rasterimage_height(ptr_image);
188
189 ret = gate_rasterimage_paste_image(&impl->image_header, ptr_image, dest_x, dest_y, 0, 0, width, height, false);
190 return ret;
191 }
192
193 static gate_result_t rasterfb_await_event(void* obj, gate_uint32_t timeout_ms, gate_framebuffer_event_t* ptr_received_evt)
194 {
195 GATE_UNUSED_ARG(obj);
196 GATE_UNUSED_ARG(timeout_ms);
197 GATE_UNUSED_ARG(ptr_received_evt);
198 return GATE_RESULT_NOTSUPPORTED;
199 }
200
201 static GATE_INTERFACE_VTBL(gate_framebuffer) gate_rasterfb_vtbl;
202 static void gate_init_rasterfb_vtbl()
203 {
204 if (!gate_rasterfb_vtbl.get_interface_name)
205 {
206 GATE_INTERFACE_VTBL(gate_framebuffer) const local_vtbl =
207 {
208 &rasterfb_get_interface_name,
209 &rasterfb_release,
210 &rasterfb_retain,
211
212 &rasterfb_get_info,
213 &rasterfb_get_property,
214 &rasterfb_set_property,
215
216 &rasterfb_update,
217
218 &rasterfb_get_pixel,
219 &rasterfb_set_pixel,
220
221 &rasterfb_get_image,
222 &rasterfb_set_image,
223
224 &rasterfb_await_event
225 };
226
227 gate_rasterfb_vtbl = local_vtbl;
228 }
229 }
230
231
232 gate_result_t gate_framebuffer_create_image(gate_uint32_t width, gate_uint32_t height, gate_framebuffer_t** ptr_framebuffer)
233 {
234 rasterfb_t* impl = NULL;
235 gate_result_t ret = GATE_RESULT_FAILED;
236 gate_size_t datasize;
237
238 do
239 {
240 datasize = sizeof(gate_color_t) * width * height;
241 impl = (rasterfb_t*)gate_mem_alloc(sizeof(rasterfb_t) + datasize);
242 if (!impl)
243 {
244 ret = GATE_RESULT_OUTOFMEMORY;
245 break;
246 }
247 gate_init_rasterfb_vtbl();
248 impl->vtbl = &gate_rasterfb_vtbl;
249 gate_atomic_int_init(&impl->ref_counter, 1);
250
251 impl->image_header.width = width;
252 impl->image_header.height = height;
253 impl->image_header.line_padding = 0;
254 impl->image_header.bits_per_pixel = sizeof(gate_color_t) * 8;
255 impl->image_header.data = &impl->image_data[0];
256 impl->image_header.databuffer = NULL;
257
258 gate_mem_clear(&impl->image_data[0], datasize);
259
260 if (ptr_framebuffer)
261 {
262 *ptr_framebuffer = (gate_framebuffer_t*)impl;
263 impl = NULL;
264 }
265 ret = GATE_RESULT_OK;
266 } while (0);
267
268 if (impl)
269 {
270 gate_mem_dealloc(impl);
271 }
272 return ret;
273 }
274
275
276
277 #if defined(GATE_GRAPHICS_FRAMEBUFFERS_DIRECTX)
278 #include "gate/graphics/platform/framebuffers_impl_directx.h"
279 #endif /* GATE_GRAPHICS_FRAMEBUFFERS_DIRECTX */
280
281
282 #if defined(GATE_GRAPHICS_FRAMEBUFFERS_WIN16)
283 #include "gate/graphics/platform/framebuffers_impl_win16.h"
284 #endif /* GATE_GRAPHICS_FRAMEBUFFERS_WIN16 */
285
286
287 #if defined(GATE_GRAPHICS_FRAMEBUFFERS_WIN32)
288 #include "gate/graphics/platform/framebuffers_impl_win32.h"
289 #endif /* GATE_GRAPHICS_FRAMEBUFFERS_WIN32 */
290
291
292 #if defined(GATE_GRAPHICS_FRAMEBUFFERS_WAYLAND)
293 #include "gate/graphics/platform/framebuffers_impl_wayland.h"
294 #endif /* GATE_GRAPHICS_FRAMEBUFFERS_WAYLAND */
295
296 #if defined(GATE_GRAPHICS_FRAMEBUFFERS_XLIB)
297 #include "gate/graphics/platform/framebuffers_impl_xlib.h"
298 #endif /* GATE_GRAPHICS_FRAMEBUFFERS_XLIB */
299
300
301 #if defined(GATE_GRAPHICS_FRAMEBUFFERS_GL)
302 #include "gate/graphics/platform/framebuffers_impl_gl.h"
303 #endif /* GATE_GRAPHICS_FRAMEBUFFERS_GL */
304
305
306 #if defined(GATE_GRAPHICS_FRAMEBUFFERS_UGA)
307 #include "gate/graphics/platform/framebuffers_impl_efigop.h"
308 #endif /* GATE_GRAPHICS_FRAMEBUFFERS_UGA */
309
310
311 #if defined(GATE_GRAPHICS_FRAMEBUFFERS_INT10)
312 #include "gate/graphics/platform/framebuffers_impl_int10.h"
313 #endif /* GATE_GRAPHICS_FRAMEBUFFERS_INT10 */
314
315
316 #if defined(GATE_GRAPHICS_FRAMEBUFFERS_WASM)
317 #include "gate/graphics/platform/framebuffers_impl_wasm.h"
318 #endif /* GATE_GRAPHICS_FRAMEBUFFERS_WASM */
319
320 #if defined(GATE_GRAPHICS_FRAMEBUFFERS_NOIMPL)
321
322 gate_size_t gate_framebuffer_enum_displays(gate_framebuffer_info_t* ptr_infos, gate_size_t infos_capacity)
323 {
324 GATE_UNUSED_ARG(ptr_infos);
325 GATE_UNUSED_ARG(infos_capacity);
326 return 0;
327 }
328
329 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)
330 {
331 GATE_UNUSED_ARG(required_width);
332 GATE_UNUSED_ARG(required_height);
333 GATE_UNUSED_ARG(ptr_found_display_info);
334 return GATE_RESULT_NOMATCH;
335 }
336
337 gate_result_t gate_framebuffer_open_display(gate_framebuffer_info_t const* ptr_infos, gate_framebuffer_t** ptr_framebuffer)
338 {
339 GATE_UNUSED_ARG(ptr_infos);
340 GATE_UNUSED_ARG(ptr_framebuffer);
341 return GATE_RESULT_NOMATCH;
342 }
343
344
345 #endif /* GATE_GRAPHICS_FRAMEBUFFERS_NOIMPL */
346