Skip to content

Commit 8f66e6b

Browse files
committed
Implement SVGA backend for libvideo-driver
Already in-use by `showpic(1)`
1 parent 9a65132 commit 8f66e6b

File tree

20 files changed

+1256
-133
lines changed

20 files changed

+1256
-133
lines changed

kos/include/libvideo/driver/adapter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ video_adapter_close(struct video_adapter *__restrict __self);
8383
* @return: NULL: [errno=*] Some other error */
8484
extern __ATTR_WUNUSED __ATTR_INOUT(1) __REF struct video_monitor *
8585
video_adapter_getmonitor(struct video_adapter *__restrict __self,
86-
__size_t __index);
86+
__size_t __index);
8787
#else /* __INTELLISENSE__ */
8888
#define video_adapter_close(self) (*(self)->vad_ops->vdro_close)(self)
8989
#define video_adapter_getmonitor(self, index) (*(self)->vad_ops->vdro_getmonitor)(self, index)

kos/include/libvideo/driver/monitor.h

Lines changed: 92 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
/**/
2525

2626
#include <__stdinc.h>
27+
#include <bits/types.h>
2728

2829
#include <libvideo/gfx/display.h>
2930

@@ -33,37 +34,119 @@ __DECL_BEGIN
3334

3435
#ifdef __CC__
3536

37+
struct video_adapter;
38+
3639
struct video_monitor_mode {
37-
struct video_codec const *vmm_codec; /* [1..1] Video codec */
40+
__REF struct video_codec *vmm_codec; /* [1..1] Video codec */
3841
video_dim_t vmm_xres; /* Resolution in X */
3942
video_dim_t vmm_yres; /* Resolution in Y */
4043
__UINT_LEAST16_TYPE__ vmm_hz; /* Refresh rate (frames per second) */
4144
};
4245

46+
#define video_monitor_mode_fini(self) video_codec_decref((self)->vmm_codec)
47+
48+
/* Enumeration callback for `video_monitor_lsmodes()' */
49+
typedef __ATTR_WUNUSED_T __ATTR_IN_T(2) __ssize_t
50+
(LIBVIDEO_DRIVER_CC *video_monitor_lsmodes_cb_t)(void *__cookie, struct video_monitor_mode const *__restrict __mode);
51+
4352
struct video_monitor_ops {
4453
struct video_display_ops vmo_display; /* Display operators */
4554

46-
/* Get the currently set video mode */
55+
/* Enumerate supported video modes
56+
* @return: >= 0: [errno=*] Sum of all return values of `__cb'
57+
* @return: -1: [errno=*] Either `__cb' returned `-1', or enumeration failed
58+
* @return: < 0: `__cb' returned this same negative value */
59+
__ATTR_WUNUSED_T __ATTR_INOUT_T(1) __ATTR_NONNULL_T((2)) __ssize_t
60+
(LIBVIDEO_DRIVER_CC *vmo_lsmodes)(struct video_monitor *__restrict __self,
61+
video_monitor_lsmodes_cb_t __cb, void *__cookie);
62+
63+
/* Get the currently set video mode
64+
* @return: 0 : Success
65+
* @return: -1: Error (s.a. `errno') */
4766
__ATTR_WUNUSED_T __ATTR_INOUT_T(1) __ATTR_OUT_T(2) int
4867
(LIBVIDEO_DRIVER_CC *vmo_getmode)(struct video_monitor *__restrict __self,
4968
struct video_monitor_mode *__restrict __mode);
5069

51-
/* Set a new video mode */
52-
__ATTR_WUNUSED_T __ATTR_INOUT_T(1) __ATTR_OUT_T(2) int
70+
/* Set the video mode to-be used. After a call to this function,
71+
* you are probably going to have to re-acquire a new reference
72+
* to the monitor's display buffer.
73+
* @return: 0 : Success
74+
* @return: -1: Error (s.a. `errno') */
75+
__ATTR_WUNUSED_T __ATTR_INOUT_T(1) __ATTR_IN_T(2) int
5376
(LIBVIDEO_DRIVER_CC *vmo_setmode)(struct video_monitor *__restrict __self,
54-
struct video_monitor_mode *__restrict __mode);
77+
struct video_monitor_mode const *__restrict __mode);
5578
};
5679

80+
#ifdef __INTELLISENSE__
81+
/* Enumerate supported video modes
82+
* @return: >= 0: [errno=*] Sum of all return values of `__cb'
83+
* @return: -1: [errno=*] Either `__cb' returned `-1', or enumeration failed
84+
* @return: < 0: `__cb' returned this same negative value */
85+
extern __ATTR_WUNUSED __ATTR_INOUT(1) __ATTR_NONNULL((2)) __ssize_t
86+
video_monitor_lsmodes(struct video_monitor *__restrict __self,
87+
video_monitor_lsmodes_cb_t __cb, void *__cookie);
88+
89+
/* Get the currently set video mode
90+
* @return: 0 : Success
91+
* @return: -1: Error (s.a. `errno') */
92+
extern __ATTR_WUNUSED __ATTR_INOUT(1) __ATTR_OUT(2) int
93+
video_monitor_getmode(struct video_monitor *__restrict __self,
94+
struct video_monitor_mode *__restrict __mode);
95+
96+
/* Set the video mode to-be used. After a call to this function,
97+
* you are probably going to have to re-acquire a new reference
98+
* to the monitor's display buffer.
99+
* @return: 0 : Success
100+
* @return: -1: Error (s.a. `errno') */
101+
extern __ATTR_WUNUSED __ATTR_INOUT(1) __ATTR_IN(2) int
102+
video_monitor_setmode(struct video_monitor *__restrict __self,
103+
struct video_monitor_mode const *__restrict __mode);
104+
105+
/* Helpers for performing video-display operations */
106+
extern __ATTR_WUNUSED __ATTR_INOUT((1)) __REF struct video_buffer *
107+
video_monitor_getbuffer(struct video_monitor *__restrict __self);
108+
extern __ATTR_INOUT(1) __ATTR_IN(2) void
109+
video_monitor_updaterect(struct video_monitor *__restrict __self,
110+
struct video_rect const *__restrict __rect);
111+
extern __ATTR_INOUT(1) __ATTR_INS(2, 3) void
112+
video_monitor_updaterects(struct video_monitor *__restrict __self,
113+
struct video_rect const *__restrict __rects,
114+
__size_t __n_rects);
115+
116+
/* Return the domain/adapter associated with `__self' */
117+
extern __ATTR_PURE __ATTR_WUNUSED __ATTR_IN(1) struct video_domain const *
118+
video_monitor_getdomain(struct video_monitor const *__restrict __self);
119+
extern __ATTR_PURE __ATTR_WUNUSED __ATTR_IN(1) struct video_adapter const *
120+
video_monitor_getadapter(struct video_monitor const *__restrict __self);
121+
#else /* __INTELLISENSE__ */
122+
#define video_monitor_lsmodes(self, cb, cookie) (*_video_monitor_getops(self)->vmo_lsmodes)(self, cb, cookie)
123+
#define video_monitor_getmode(self, mode) (*_video_monitor_getops(self)->vmo_getmode)(self, mode)
124+
#define video_monitor_setmode(self, mode) (*_video_monitor_getops(self)->vmo_setmode)(self, mode)
125+
#define video_monitor_getbuffer(self) video_display_getbuffer(video_monitor_asdisplay(self))
126+
#define video_monitor_updaterect(self, rect) video_display_updaterect(video_monitor_asdisplay(self), rect)
127+
#define video_monitor_updaterects(self, rects, n_rects) video_display_updaterects(video_monitor_asdisplay(self), rects, n_rects)
128+
#define video_monitor_getdomain(self) video_display_getdomain(video_monitor_asdisplay(self))
129+
#define video_monitor_getadapter(self) ((struct video_adapter const *)video_monitor_getdomain(self))
130+
#endif /* !__INTELLISENSE__ */
131+
57132
struct video_monitor
58133
#ifdef __cplusplus
59-
: video_display
134+
: video_display /* Underlying display */
135+
#define _video_monitor__vm_display /* nothing */
136+
#define video_monitor_asdisplay /* nothing */
60137
#endif /* __cplusplus */
61138
{
62-
139+
#ifndef __cplusplus
140+
struct video_display vm_display; /* Underlying display */
141+
#define _video_monitor__vm_display vm_display.
142+
#define video_monitor_asdisplay(x) (&(x)->vm_display)
143+
#endif /* __cplusplus */
63144
};
64145

65-
66-
146+
#define _video_monitor_getops(self) \
147+
((struct video_monitor_ops const *)(self)->_video_monitor__vm_display vd_ops)
148+
#define video_monitor_incref(self) video_display_incref(video_monitor_asdisplay(self))
149+
#define video_monitor_decref(self) video_display_decref(video_monitor_asdisplay(self))
67150

68151
#endif /* __CC__ */
69152

kos/include/libvideo/gfx/buffer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,7 @@ struct video_buffer {
816816
(void)((self)->vb_ops = (ops))
817817
#ifdef __INTELLISENSE__
818818
#define __video_buffer_init_common(self) ((self)->vb_surf.vs_buffer = (self))
819-
#define __video_buffer_fini_common(self) (void)((self)->vb_surf.vs_buffer = (self))
819+
#define __video_buffer_fini_common(self) (void)(++(self)->vb_surf.vs_buffer)
820820
#else /* __INTELLISENSE__ */
821821
#define __video_buffer_init_common(self) \
822822
(!((self)->vb_surf.vs_flags & VIDEO_GFX_F_PALOBJ) || \
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/* Copyright (c) 2019-2025 Griefer@Work *
2+
* *
3+
* This software is provided 'as-is', without any express or implied *
4+
* warranty. In no event will the authors be held liable for any damages *
5+
* arising from the use of this software. *
6+
* *
7+
* Permission is granted to anyone to use this software for any purpose, *
8+
* including commercial applications, and to alter it and redistribute it *
9+
* freely, subject to the following restrictions: *
10+
* *
11+
* 1. The origin of this software must not be misrepresented; you must not *
12+
* claim that you wrote the original software. If you use this software *
13+
* in a product, an acknowledgement (see the following) in the product *
14+
* documentation is required: *
15+
* Portions Copyright (c) 2019-2025 Griefer@Work *
16+
* 2. Altered source versions must be plainly marked as such, and must not be *
17+
* misrepresented as being the original software. *
18+
* 3. This notice may not be removed or altered from any source distribution. *
19+
*/
20+
#ifndef _LIBVIDEO_GFX_BUFFER_RAMBUFFER_H
21+
#define _LIBVIDEO_GFX_BUFFER_RAMBUFFER_H 1
22+
23+
#include "../api.h"
24+
/**/
25+
26+
#include <__stdinc.h>
27+
28+
#include <bits/types.h>
29+
#include <kos/anno.h>
30+
31+
#include "../../types.h"
32+
#include "../buffer.h"
33+
34+
#ifdef LIBVIDEO_GFX_EXPOSE_INTERNALS
35+
#ifdef __CC__
36+
__DECL_BEGIN
37+
38+
struct video_rambuffer
39+
#ifdef __cplusplus
40+
: video_buffer
41+
#endif /* __cplusplus */
42+
{
43+
#ifndef __cplusplus
44+
struct video_buffer rb_buffer;
45+
#endif /* !__cplusplus */
46+
/* >> vb_ops == &video_rambuffer_ops */
47+
/* This type is sufficient for doing simple GFX */
48+
__byte_t *rb_data; /* [1..1][owned][const] Buffer data */
49+
__size_t rb_stride; /* [const] Buffer stride */
50+
};
51+
52+
struct video_rambuffer_formem
53+
#ifdef __cplusplus
54+
: video_rambuffer
55+
#endif /* __cplusplus */
56+
{
57+
#ifndef __cplusplus
58+
struct video_rambuffer rbfm_rambuffer;
59+
#endif /* !__cplusplus */
60+
/* >> vb_ops == &video_rambuffer_formem_ops */
61+
void (LIBVIDEO_GFX_CC *rbfm_release_mem)(void *__cookie, void *__mem); /* [1..1][const] Callback invoked the first time `rbrv_dummy' is written to `rbrv_data' */
62+
void *rbfm_release_mem_cookie; /* [?..?][const] Cookie for `rbfm_release_mem' */
63+
};
64+
65+
struct video_rambuffer_subregion
66+
#ifdef __cplusplus
67+
: video_rambuffer
68+
#endif /* __cplusplus */
69+
{
70+
#ifndef __cplusplus
71+
struct video_rambuffer rbs_rambuffer;
72+
#endif /* !__cplusplus */
73+
/* >> vb_ops == &video_rambuffer_subregion_ops ||
74+
* >> vb_ops == &video_rambuffer_subregion_norem_ops */
75+
__REF struct video_rambuffer *rbs_base; /* [0..1][lock(ATOMIC && CLEAR_ONCE)] Underlying base buffer */
76+
video_coord_t rbs_bxrem; /* [const] Extra X-offset added to all pixel coords */
77+
video_coord_t rbs_xoff; /* [const] GFX X-offset */
78+
video_coord_t rbs_yoff; /* [const] GFX Y-offset */
79+
video_coord_t rbs_xend; /* [const] GFX X-end-offset */
80+
video_coord_t rbs_yend; /* [const] GFX Y-end-offset */
81+
};
82+
83+
84+
/* Return operator tables for different types of ram-buffers, as seen above */
85+
typedef __ATTR_RETNONNULL_T __ATTR_WUNUSED_T struct video_buffer_ops const *(LIBVIDEO_GFX_CC *PVIDEO_RAMBUFFER_OPS)(void);
86+
typedef __ATTR_RETNONNULL_T __ATTR_WUNUSED_T struct video_buffer_ops const *(LIBVIDEO_GFX_CC *PVIDEO_RAMBUFFER_FORMEM_OPS)(void);
87+
typedef __ATTR_RETNONNULL_T __ATTR_WUNUSED_T struct video_buffer_ops const *(LIBVIDEO_GFX_CC *PVIDEO_RAMBUFFER_SUBREGION_OPS)(void);
88+
typedef __ATTR_RETNONNULL_T __ATTR_WUNUSED_T struct video_buffer_ops const *(LIBVIDEO_GFX_CC *PVIDEO_RAMBUFFER_SUBREGION_NOREM_OPS)(void);
89+
#ifdef LIBVIDEO_GFX_WANT_PROTOTYPES
90+
LIBVIDEO_GFX_DECL __ATTR_RETNONNULL __ATTR_WUNUSED struct video_buffer_ops const *LIBVIDEO_GFX_CC video_rambuffer_ops(void);
91+
LIBVIDEO_GFX_DECL __ATTR_RETNONNULL __ATTR_WUNUSED struct video_buffer_ops const *LIBVIDEO_GFX_CC video_rambuffer_formem_ops(void);
92+
LIBVIDEO_GFX_DECL __ATTR_RETNONNULL __ATTR_WUNUSED struct video_buffer_ops const *LIBVIDEO_GFX_CC video_rambuffer_subregion_ops(void);
93+
LIBVIDEO_GFX_DECL __ATTR_RETNONNULL __ATTR_WUNUSED struct video_buffer_ops const *LIBVIDEO_GFX_CC video_rambuffer_subregion_norem_ops(void);
94+
#endif /* LIBVIDEO_GFX_WANT_PROTOTYPES */
95+
96+
__DECL_END
97+
#endif /* __CC__ */
98+
#endif /* LIBVIDEO_GFX_EXPOSE_INTERNALS */
99+
100+
#endif /* !_LIBVIDEO_GFX_BUFFER_RAMBUFFER_H */

kos/include/libvideo/gfx/codec/codec-extra.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,18 @@
4545
* >> B3 = (B3 & 0xdf) | (((v >> 3) & 1) << 5); // Bit#3 */
4646
#define VIDEO_CODEC_X_VBE16 0x3001
4747

48-
/* TODO: 4-bit-per-pixel, 8-pixels-per-byte, planar */
48+
/* Tile-based video codec, where each "pixel" is actually a descriptor for a tile:
49+
* >> TTTTTTTTBBBBFFFF
50+
* T: Tile index (== R)
51+
* B: Background color (== G)
52+
* F: Foreground color (== B)
53+
*
54+
* When it comes to pixel<=>color conversion, we encode TBG as RGB
55+
*
56+
* As such, this format could also be called "RGB844" */
57+
#define VIDEO_CODEC_X_TILE16 0x3002
58+
59+
/* TODO: 4-bit-per-pixel, 8-pixels-per-byte, planar */
4960

5061

5162
#endif /* !_LIBVIDEO_GFX_CODEC_CODEC_EXTRA_H */

kos/include/libvideo/gfx/codec/codec.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,8 @@ video_codec_getpalcolors(struct video_codec const *__restrict self);
487487
#define video_codec_decref(self) \
488488
(void)(__hybrid_atomic_decfetch(&(self)->vc_refcnt, __ATOMIC_SEQ_CST) || \
489489
(video_codec_destroy(self), 0))
490+
#define video_codec_xincref(self) (void)(!(self) || (video_codec_incref(self), 0))
491+
#define video_codec_xdecref(self) (void)(!(self) || (video_codec_decref(self), 0))
490492
__DEFINE_REFCNT_FUNCTIONS(struct video_codec, vc_refcnt, video_codec_destroy)
491493

492494

kos/include/libvideo/gfx/display.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ struct video_display_ops {
6262
__ATTR_WUNUSED_T __ATTR_INOUT_T((1)) __REF struct video_buffer *
6363
(LIBVIDEO_GFX_CC *vdo_getbuffer)(struct video_display *__restrict __self);
6464

65+
/* TODO: Operator for changing/updating the palette used by `vdo_getbuffer' */
66+
6567
/* Indicate that the contents of a given physical rect have changed.
6668
* Chipset drivers might need this to propagate changes to actually
6769
* appear on-screen, and a compositor might need this to do its thing
@@ -97,26 +99,31 @@ struct video_display_ops {
9799
*
98100
* @return: * : The currently active video buffer
99101
* @return: NULL: Video I/O access failed (s.a. `errno') */
100-
extern __ATTR_WUNUSED __ATTR_INOUT((1)) __REF struct video_buffer *LIBVIDEO_GFX_CC
102+
extern __ATTR_WUNUSED __ATTR_INOUT((1)) __REF struct video_buffer *
101103
video_display_getbuffer(struct video_display *__restrict __self);
102104

103105
/* Indicate that the contents of a given physical rect have changed.
104106
* Chipset drivers might need this to propagate changes to actually
105107
* appear on-screen, and a compositor might need this to do its thing
106108
* and composite the specified rects and make them visible. */
107-
extern __ATTR_INOUT(1) __ATTR_IN(2) void LIBVIDEO_GFX_CC
109+
extern __ATTR_INOUT(1) __ATTR_IN(2) void
108110
video_display_updaterect(struct video_display *__restrict __self,
109111
struct video_rect const *__restrict __rect);
110112

111113
/* Same as `video_display_updaterect()', but update multiple rects at once. */
112-
extern __ATTR_INOUT(1) __ATTR_INS(2, 3) void LIBVIDEO_GFX_CC
114+
extern __ATTR_INOUT(1) __ATTR_INS(2, 3) void
113115
video_display_updaterects(struct video_display *__restrict __self,
114116
struct video_rect const *__restrict __rects,
115117
__size_t __n_rects);
118+
119+
/* Return the domain associated with `__self' */
120+
extern __ATTR_PURE __ATTR_WUNUSED __ATTR_IN(1) struct video_domain const *
121+
video_display_getdomain(struct video_display const *__restrict __self);
116122
#else /* __INTELLISENSE__ */
117123
#define video_display_getbuffer(self) (*(self)->vd_ops->vdo_getbuffer)(self)
118124
#define video_display_updaterect(self, rect) (*(self)->vd_ops->vdo_updaterect)(self, rect)
119125
#define video_display_updaterects(self, rects, n_rects) (*(self)->vd_ops->vdo_updaterects)(self, rects, n_rects)
126+
#define video_display_getdomain(self) (self)->vd_domain
120127
#endif /* !__INTELLISENSE__ */
121128

122129

kos/src/.sources

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ BEGIN
165165
USELIB("libvideo-gfx")
166166
SOURCE({
167167
"libvideo/driver/*.c",
168+
"libvideo/driver/adapter/*.c",
168169
})
169170
END
170171
END

kos/src/apps/.sources

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ DEFINE_SIMPLE_C_APPLICATION("snake")
4343
DEFINE_SIMPLE_C_APPLICATION("vconf")
4444
DEFINE_SIMPLE_CXX_APPLICATION("gfx", USELIB("libvideo-gfx"))
4545
DEFINE_SIMPLE_C_APPLICATION("showpic",
46+
USELIB("libvideo-driver")
4647
USELIB("libvideo-gfx")
4748
USELIB("libvideo-compositor") // TODO: Remove this dependency
4849
)

0 commit comments

Comments
 (0)