mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-12-27 14:41:22 -05:00
Add support for DRM_FORMAT_C8 to vesadrm. The new pixel-format description PIXEL_FORMAT_C8 describes the layout. Vesadrm's helpers vesadrm_fill_palette_lut() and vesadrm_load_palette_lut() set the hardware palette according to the CRTC's output format. The driver emulates XRGB8888 by converting the source buffer to RGB332 and using the resulting 256 colors as index into the hardware palette. The hardware palette converts back to RGB during scanout. This has no overhead compared to other format conversion, but allows common userspace, such as Wayland compositors, to operate on the display. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://lore.kernel.org/r/20250714151513.309475-10-tzimmermann@suse.de
103 lines
2.7 KiB
C
103 lines
2.7 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
|
|
#ifndef VIDEO_PIXEL_FORMAT_H
|
|
#define VIDEO_PIXEL_FORMAT_H
|
|
|
|
struct pixel_format {
|
|
unsigned char bits_per_pixel;
|
|
bool indexed;
|
|
union {
|
|
struct {
|
|
struct {
|
|
unsigned char offset;
|
|
unsigned char length;
|
|
} alpha, red, green, blue;
|
|
};
|
|
struct {
|
|
unsigned char offset;
|
|
unsigned char length;
|
|
} index;
|
|
};
|
|
};
|
|
|
|
#define PIXEL_FORMAT_C8 \
|
|
{ 8, true, { .index = {0, 8}, } }
|
|
|
|
#define PIXEL_FORMAT_XRGB1555 \
|
|
{ 16, false, { .alpha = {0, 0}, .red = {10, 5}, .green = {5, 5}, .blue = {0, 5} } }
|
|
|
|
#define PIXEL_FORMAT_RGB565 \
|
|
{ 16, false, { .alpha = {0, 0}, .red = {11, 5}, .green = {5, 6}, .blue = {0, 5} } }
|
|
|
|
#define PIXEL_FORMAT_RGB888 \
|
|
{ 24, false, { .alpha = {0, 0}, .red = {16, 8}, .green = {8, 8}, .blue = {0, 8} } }
|
|
|
|
#define PIXEL_FORMAT_XRGB8888 \
|
|
{ 32, false, { .alpha = {0, 0}, .red = {16, 8}, .green = {8, 8}, .blue = {0, 8} } }
|
|
|
|
#define PIXEL_FORMAT_XBGR8888 \
|
|
{ 32, false, { .alpha = {0, 0}, .red = {0, 8}, .green = {8, 8}, .blue = {16, 8} } }
|
|
|
|
#define PIXEL_FORMAT_XRGB2101010 \
|
|
{ 32, false, { .alpha = {0, 0}, .red = {20, 10}, .green = {10, 10}, .blue = {0, 10} } }
|
|
|
|
#define __pixel_format_cmp_field(lhs, rhs, name) \
|
|
{ \
|
|
int ret = ((lhs)->name) - ((rhs)->name); \
|
|
if (ret) \
|
|
return ret; \
|
|
}
|
|
|
|
#define __pixel_format_cmp_bitfield(lhs, rhs, name) \
|
|
{ \
|
|
__pixel_format_cmp_field(lhs, rhs, name.offset); \
|
|
__pixel_format_cmp_field(lhs, rhs, name.length); \
|
|
}
|
|
|
|
/**
|
|
* pixel_format_cmp - Compares two pixel-format descriptions
|
|
*
|
|
* @lhs: a pixel-format description
|
|
* @rhs: a pixel-format description
|
|
*
|
|
* Compares two pixel-format descriptions for their order. The semantics
|
|
* are equivalent to memcmp().
|
|
*
|
|
* Returns:
|
|
* 0 if both arguments describe the same pixel format, less-than-zero if lhs < rhs,
|
|
* or greater-than-zero if lhs > rhs.
|
|
*/
|
|
static inline int pixel_format_cmp(const struct pixel_format *lhs, const struct pixel_format *rhs)
|
|
{
|
|
__pixel_format_cmp_field(lhs, rhs, bits_per_pixel);
|
|
__pixel_format_cmp_field(lhs, rhs, indexed);
|
|
|
|
if (lhs->indexed) {
|
|
__pixel_format_cmp_bitfield(lhs, rhs, index);
|
|
} else {
|
|
__pixel_format_cmp_bitfield(lhs, rhs, alpha);
|
|
__pixel_format_cmp_bitfield(lhs, rhs, red);
|
|
__pixel_format_cmp_bitfield(lhs, rhs, green);
|
|
__pixel_format_cmp_bitfield(lhs, rhs, blue);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* pixel_format_equal - Compares two pixel-format descriptions for equality
|
|
*
|
|
* @lhs: a pixel-format description
|
|
* @rhs: a pixel-format description
|
|
*
|
|
* Returns:
|
|
* True if both arguments describe the same pixel format, or false otherwise.
|
|
*/
|
|
static inline bool pixel_format_equal(const struct pixel_format *lhs,
|
|
const struct pixel_format *rhs)
|
|
{
|
|
return !pixel_format_cmp(lhs, rhs);
|
|
}
|
|
|
|
#endif
|