drm_draw.c 5.1 KB

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