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_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 */ 25 bool 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 } 45 EXPORT_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 */ 56 u32 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 } 87 EXPORT_SYMBOL(drm_draw_color_from_xrgb8888); 88 89 /* 90 * Blit functions 91 */ 92 void 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 } 104 EXPORT_SYMBOL(drm_draw_blit16); 105 106 void 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 } 126 EXPORT_SYMBOL(drm_draw_blit24); 127 128 void 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 } 140 EXPORT_SYMBOL(drm_draw_blit32); 141 142 /* 143 * Fill functions 144 */ 145 void 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 } 155 EXPORT_SYMBOL(drm_draw_fill16); 156 157 void 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 } 174 EXPORT_SYMBOL(drm_draw_fill24); 175 176 void 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 } 186 EXPORT_SYMBOL(drm_draw_fill32); 187