projects/linux·blob master · refs

186 lines · 5.1 KiB

1// SPDX-License-Identifier: GPL-2.0 or MIT
2/*
3 * Copyright (c) 2023 Red Hat.
4 * Author: Jocelyn Falempe <[email protected]>
5 */
6
7#include <linux/bits.h>
8#include <linux/bug.h>
9#include <linux/export.h>
10#include <linux/iosys-map.h>
11#include <linux/types.h>
12
13#include <drm/drm_fourcc.h>
14
15#include "drm_draw_internal.h"
16#include "drm_format_internal.h"
17
18/**
19 * drm_draw_can_convert_from_xrgb8888 - check if xrgb8888 can be converted to the desired format
20 * @format: format
21 *
22 * Returns:
23 * True if XRGB8888 can be converted to the specified format, false otherwise.
24 */
25bool drm_draw_can_convert_from_xrgb8888(u32 format)
26{
27 switch (format) {
28 case DRM_FORMAT_RGB565:
29 case DRM_FORMAT_RGBA5551:
30 case DRM_FORMAT_XRGB1555:
31 case DRM_FORMAT_ARGB1555:
32 case DRM_FORMAT_RGB888:
33 case DRM_FORMAT_XRGB8888:
34 case DRM_FORMAT_ARGB8888:
35 case DRM_FORMAT_XBGR8888:
36 case DRM_FORMAT_ABGR8888:
37 case DRM_FORMAT_XRGB2101010:
38 case DRM_FORMAT_ARGB2101010:
39 case DRM_FORMAT_ABGR2101010:
40 return true;
41 default:
42 return false;
43 }
44}
45EXPORT_SYMBOL(drm_draw_can_convert_from_xrgb8888);
46
47/**
48 * drm_draw_color_from_xrgb8888 - convert one pixel from xrgb8888 to the desired format
49 * @color: input color, in xrgb8888 format
50 * @format: output format
51 *
52 * Returns:
53 * Color in the format specified, casted to u32.
54 * Or 0 if the format is not supported.
55 */
56u32 drm_draw_color_from_xrgb8888(u32 color, u32 format)
57{
58 switch (format) {
59 case DRM_FORMAT_RGB565:
60 return drm_pixel_xrgb8888_to_rgb565(color);
61 case DRM_FORMAT_RGBA5551:
62 return drm_pixel_xrgb8888_to_rgba5551(color);
63 case DRM_FORMAT_XRGB1555:
64 return drm_pixel_xrgb8888_to_xrgb1555(color);
65 case DRM_FORMAT_ARGB1555:
66 return drm_pixel_xrgb8888_to_argb1555(color);
67 case DRM_FORMAT_RGB888:
68 case DRM_FORMAT_XRGB8888:
69 return color;
70 case DRM_FORMAT_ARGB8888:
71 return drm_pixel_xrgb8888_to_argb8888(color);
72 case DRM_FORMAT_XBGR8888:
73 return drm_pixel_xrgb8888_to_xbgr8888(color);
74 case DRM_FORMAT_ABGR8888:
75 return drm_pixel_xrgb8888_to_abgr8888(color);
76 case DRM_FORMAT_XRGB2101010:
77 return drm_pixel_xrgb8888_to_xrgb2101010(color);
78 case DRM_FORMAT_ARGB2101010:
79 return drm_pixel_xrgb8888_to_argb2101010(color);
80 case DRM_FORMAT_ABGR2101010:
81 return drm_pixel_xrgb8888_to_abgr2101010(color);
82 default:
83 WARN_ONCE(1, "Can't convert to %p4cc\n", &format);
84 return 0;
85 }
86}
87EXPORT_SYMBOL(drm_draw_color_from_xrgb8888);
88
89/*
90 * Blit functions
91 */
92void drm_draw_blit16(struct iosys_map *dmap, unsigned int dpitch,
93 const u8 *sbuf8, unsigned int spitch,
94 unsigned int height, unsigned int width,
95 unsigned int scale, u16 fg16)
96{
97 unsigned int y, x;
98
99 for (y = 0; y < height; y++)
100 for (x = 0; x < width; x++)
101 if (drm_draw_is_pixel_fg(sbuf8, spitch, x / scale, y / scale))
102 iosys_map_wr(dmap, y * dpitch + x * sizeof(u16), u16, fg16);
103}
104EXPORT_SYMBOL(drm_draw_blit16);
105
106void drm_draw_blit24(struct iosys_map *dmap, unsigned int dpitch,
107 const u8 *sbuf8, unsigned int spitch,
108 unsigned int height, unsigned int width,
109 unsigned int scale, u32 fg32)
110{
111 unsigned int y, x;
112
113 for (y = 0; y < height; y++) {
114 for (x = 0; x < width; x++) {
115 u32 off = y * dpitch + x * 3;
116
117 if (drm_draw_is_pixel_fg(sbuf8, spitch, x / scale, y / scale)) {
118 /* write blue-green-red to output in little endianness */
119 iosys_map_wr(dmap, off, u8, (fg32 & 0x000000FF) >> 0);
120 iosys_map_wr(dmap, off + 1, u8, (fg32 & 0x0000FF00) >> 8);
121 iosys_map_wr(dmap, off + 2, u8, (fg32 & 0x00FF0000) >> 16);
122 }
123 }
124 }
125}
126EXPORT_SYMBOL(drm_draw_blit24);
127
128void drm_draw_blit32(struct iosys_map *dmap, unsigned int dpitch,
129 const u8 *sbuf8, unsigned int spitch,
130 unsigned int height, unsigned int width,
131 unsigned int scale, u32 fg32)
132{
133 unsigned int y, x;
134
135 for (y = 0; y < height; y++)
136 for (x = 0; x < width; x++)
137 if (drm_draw_is_pixel_fg(sbuf8, spitch, x / scale, y / scale))
138 iosys_map_wr(dmap, y * dpitch + x * sizeof(u32), u32, fg32);
139}
140EXPORT_SYMBOL(drm_draw_blit32);
141
142/*
143 * Fill functions
144 */
145void drm_draw_fill16(struct iosys_map *dmap, unsigned int dpitch,
146 unsigned int height, unsigned int width,
147 u16 color)
148{
149 unsigned int y, x;
150
151 for (y = 0; y < height; y++)
152 for (x = 0; x < width; x++)
153 iosys_map_wr(dmap, y * dpitch + x * sizeof(u16), u16, color);
154}
155EXPORT_SYMBOL(drm_draw_fill16);
156
157void drm_draw_fill24(struct iosys_map *dmap, unsigned int dpitch,
158 unsigned int height, unsigned int width,
159 u32 color)
160{
161 unsigned int y, x;
162
163 for (y = 0; y < height; y++) {
164 for (x = 0; x < width; x++) {
165 unsigned int off = y * dpitch + x * 3;
166
167 /* write blue-green-red to output in little endianness */
168 iosys_map_wr(dmap, off, u8, (color & 0x000000FF) >> 0);
169 iosys_map_wr(dmap, off + 1, u8, (color & 0x0000FF00) >> 8);
170 iosys_map_wr(dmap, off + 2, u8, (color & 0x00FF0000) >> 16);
171 }
172 }
173}
174EXPORT_SYMBOL(drm_draw_fill24);
175
176void drm_draw_fill32(struct iosys_map *dmap, unsigned int dpitch,
177 unsigned int height, unsigned int width,
178 u32 color)
179{
180 unsigned int y, x;
181
182 for (y = 0; y < height; y++)
183 for (x = 0; x < width; x++)
184 iosys_map_wr(dmap, y * dpitch + x * sizeof(u32), u32, color);
185}
186EXPORT_SYMBOL(drm_draw_fill32);