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 */ 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 */ 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 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 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 */ 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 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 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