1 // SPDX-License-Identifier: GPL-2.0 or MIT
2 /*
3 * Copyright (c) 2023 Red Hat.
4 * Author: Jocelyn Falempe <jfalempe@redhat.com>
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_color_from_xrgb8888 - convert one pixel from xrgb8888 to the desired format
20 * @color: input color, in xrgb8888 format
21 * @format: output format
22 *
23 * Returns:
24 * Color in the format specified, casted to u32.
25 * Or 0 if the format is not supported.
26 */
drm_draw_color_from_xrgb8888(u32 color,u32 format)27 u32 drm_draw_color_from_xrgb8888(u32 color, u32 format)
28 {
29 switch (format) {
30 case DRM_FORMAT_RGB565:
31 return drm_pixel_xrgb8888_to_rgb565(color);
32 case DRM_FORMAT_RGBA5551:
33 return drm_pixel_xrgb8888_to_rgba5551(color);
34 case DRM_FORMAT_XRGB1555:
35 return drm_pixel_xrgb8888_to_xrgb1555(color);
36 case DRM_FORMAT_ARGB1555:
37 return drm_pixel_xrgb8888_to_argb1555(color);
38 case DRM_FORMAT_RGB888:
39 case DRM_FORMAT_XRGB8888:
40 return color;
41 case DRM_FORMAT_ARGB8888:
42 return drm_pixel_xrgb8888_to_argb8888(color);
43 case DRM_FORMAT_XBGR8888:
44 return drm_pixel_xrgb8888_to_xbgr8888(color);
45 case DRM_FORMAT_ABGR8888:
46 return drm_pixel_xrgb8888_to_abgr8888(color);
47 case DRM_FORMAT_XRGB2101010:
48 return drm_pixel_xrgb8888_to_xrgb2101010(color);
49 case DRM_FORMAT_ARGB2101010:
50 return drm_pixel_xrgb8888_to_argb2101010(color);
51 case DRM_FORMAT_ABGR2101010:
52 return drm_pixel_xrgb8888_to_abgr2101010(color);
53 default:
54 WARN_ONCE(1, "Can't convert to %p4cc\n", &format);
55 return 0;
56 }
57 }
58 EXPORT_SYMBOL(drm_draw_color_from_xrgb8888);
59
60 /*
61 * Blit functions
62 */
drm_draw_blit16(struct iosys_map * dmap,unsigned int dpitch,const u8 * sbuf8,unsigned int spitch,unsigned int height,unsigned int width,unsigned int scale,u16 fg16)63 void drm_draw_blit16(struct iosys_map *dmap, unsigned int dpitch,
64 const u8 *sbuf8, unsigned int spitch,
65 unsigned int height, unsigned int width,
66 unsigned int scale, u16 fg16)
67 {
68 unsigned int y, x;
69
70 for (y = 0; y < height; y++)
71 for (x = 0; x < width; x++)
72 if (drm_draw_is_pixel_fg(sbuf8, spitch, x / scale, y / scale))
73 iosys_map_wr(dmap, y * dpitch + x * sizeof(u16), u16, fg16);
74 }
75 EXPORT_SYMBOL(drm_draw_blit16);
76
drm_draw_blit24(struct iosys_map * dmap,unsigned int dpitch,const u8 * sbuf8,unsigned int spitch,unsigned int height,unsigned int width,unsigned int scale,u32 fg32)77 void drm_draw_blit24(struct iosys_map *dmap, unsigned int dpitch,
78 const u8 *sbuf8, unsigned int spitch,
79 unsigned int height, unsigned int width,
80 unsigned int scale, u32 fg32)
81 {
82 unsigned int y, x;
83
84 for (y = 0; y < height; y++) {
85 for (x = 0; x < width; x++) {
86 u32 off = y * dpitch + x * 3;
87
88 if (drm_draw_is_pixel_fg(sbuf8, spitch, x / scale, y / scale)) {
89 /* write blue-green-red to output in little endianness */
90 iosys_map_wr(dmap, off, u8, (fg32 & 0x000000FF) >> 0);
91 iosys_map_wr(dmap, off + 1, u8, (fg32 & 0x0000FF00) >> 8);
92 iosys_map_wr(dmap, off + 2, u8, (fg32 & 0x00FF0000) >> 16);
93 }
94 }
95 }
96 }
97 EXPORT_SYMBOL(drm_draw_blit24);
98
drm_draw_blit32(struct iosys_map * dmap,unsigned int dpitch,const u8 * sbuf8,unsigned int spitch,unsigned int height,unsigned int width,unsigned int scale,u32 fg32)99 void drm_draw_blit32(struct iosys_map *dmap, unsigned int dpitch,
100 const u8 *sbuf8, unsigned int spitch,
101 unsigned int height, unsigned int width,
102 unsigned int scale, u32 fg32)
103 {
104 unsigned int y, x;
105
106 for (y = 0; y < height; y++)
107 for (x = 0; x < width; x++)
108 if (drm_draw_is_pixel_fg(sbuf8, spitch, x / scale, y / scale))
109 iosys_map_wr(dmap, y * dpitch + x * sizeof(u32), u32, fg32);
110 }
111 EXPORT_SYMBOL(drm_draw_blit32);
112
113 /*
114 * Fill functions
115 */
drm_draw_fill16(struct iosys_map * dmap,unsigned int dpitch,unsigned int height,unsigned int width,u16 color)116 void drm_draw_fill16(struct iosys_map *dmap, unsigned int dpitch,
117 unsigned int height, unsigned int width,
118 u16 color)
119 {
120 unsigned int y, x;
121
122 for (y = 0; y < height; y++)
123 for (x = 0; x < width; x++)
124 iosys_map_wr(dmap, y * dpitch + x * sizeof(u16), u16, color);
125 }
126 EXPORT_SYMBOL(drm_draw_fill16);
127
drm_draw_fill24(struct iosys_map * dmap,unsigned int dpitch,unsigned int height,unsigned int width,u16 color)128 void drm_draw_fill24(struct iosys_map *dmap, unsigned int dpitch,
129 unsigned int height, unsigned int width,
130 u16 color)
131 {
132 unsigned int y, x;
133
134 for (y = 0; y < height; y++) {
135 for (x = 0; x < width; x++) {
136 unsigned int off = y * dpitch + x * 3;
137
138 /* write blue-green-red to output in little endianness */
139 iosys_map_wr(dmap, off, u8, (color & 0x000000FF) >> 0);
140 iosys_map_wr(dmap, off + 1, u8, (color & 0x0000FF00) >> 8);
141 iosys_map_wr(dmap, off + 2, u8, (color & 0x00FF0000) >> 16);
142 }
143 }
144 }
145 EXPORT_SYMBOL(drm_draw_fill24);
146
drm_draw_fill32(struct iosys_map * dmap,unsigned int dpitch,unsigned int height,unsigned int width,u32 color)147 void drm_draw_fill32(struct iosys_map *dmap, unsigned int dpitch,
148 unsigned int height, unsigned int width,
149 u32 color)
150 {
151 unsigned int y, x;
152
153 for (y = 0; y < height; y++)
154 for (x = 0; x < width; x++)
155 iosys_map_wr(dmap, y * dpitch + x * sizeof(u32), u32, color);
156 }
157 EXPORT_SYMBOL(drm_draw_fill32);
158