xref: /linux/drivers/gpu/drm/drm_draw.c (revision ab93e0dd72c37d378dd936f031ffb83ff2bd87ce)
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