graphic_primary.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023-02-25 GuEe-GUI the first version
  9. */
  10. #include <rthw.h>
  11. #include <rtthread.h>
  12. #include <rtdevice.h>
  13. #define DBG_TAG "graphic.primary"
  14. #define DBG_LVL DBG_INFO
  15. #include <rtdbg.h>
  16. static struct rt_graphic_device *primary_gdev = RT_NULL;
  17. #define framebuffer_drift(plane, x, y, bpp) \
  18. ((plane)->framebuffer + (x) * ((bpp) / 8) + (y) * (plane)->line_length)
  19. #define fixup_dir(a1, a2) \
  20. if ((a1) > (a2)) { (a1) ^= (a2); (a2) ^= (a1); (a1) ^= (a2); }
  21. static void graphic_primary_set_pixel_8bit(const char *pixel, int x, int y)
  22. {
  23. struct rt_graphic_plane *plane = primary_gdev->primary_plane;
  24. *(rt_uint8_t *)framebuffer_drift(plane, x, y, 8) = *(rt_uint8_t *)pixel;
  25. }
  26. static void graphic_primary_get_pixel_8bit(char *pixel, int x, int y)
  27. {
  28. struct rt_graphic_plane *plane = primary_gdev->primary_plane;
  29. *(rt_uint8_t *)pixel = *(rt_uint8_t *)framebuffer_drift(plane, x, y, 8);
  30. }
  31. static void graphic_primary_draw_hline_8bit(const char *pixel, int x1, int x2, int y)
  32. {
  33. struct rt_graphic_plane *plane = primary_gdev->primary_plane;
  34. fixup_dir(x1, x2);
  35. rt_memset(framebuffer_drift(plane, x1, y, 8), *(rt_uint8_t *)pixel, x2 - x1);
  36. }
  37. static void graphic_primary_draw_vline_8bit(const char *pixel, int x, int y1, int y2)
  38. {
  39. rt_uint8_t *fb;
  40. struct rt_graphic_plane *plane = primary_gdev->primary_plane;
  41. fixup_dir(y1, y2);
  42. fb = framebuffer_drift(plane, x, y1, 8);
  43. for (; y1 < y2; ++y1)
  44. {
  45. *fb = *(rt_uint8_t *)pixel;
  46. fb += plane->line_length;
  47. }
  48. }
  49. static void graphic_primary_blit_line_8bit(const char *pixel, int x, int y, rt_size_t size)
  50. {
  51. struct rt_graphic_plane *plane = primary_gdev->primary_plane;
  52. rt_memcpy(framebuffer_drift(plane, x, y, 8), pixel, size);
  53. }
  54. static struct rt_device_graphic_ops graphic_primary_8bit_ops =
  55. {
  56. .set_pixel = graphic_primary_set_pixel_8bit,
  57. .get_pixel = graphic_primary_get_pixel_8bit,
  58. .draw_hline = graphic_primary_draw_hline_8bit,
  59. .draw_vline = graphic_primary_draw_vline_8bit,
  60. .blit_line = graphic_primary_blit_line_8bit,
  61. };
  62. static void graphic_primary_set_pixel_16bit(const char *pixel, int x, int y)
  63. {
  64. struct rt_graphic_plane *plane = primary_gdev->primary_plane;
  65. *(rt_uint16_t *)framebuffer_drift(plane, x, y, 16) = *(rt_uint16_t *)pixel;
  66. }
  67. static void graphic_primary_get_pixel_16bit(char *pixel, int x, int y)
  68. {
  69. struct rt_graphic_plane *plane = primary_gdev->primary_plane;
  70. *(rt_uint16_t *)pixel = *(rt_uint16_t *)framebuffer_drift(plane, x, y, 16);
  71. }
  72. static void graphic_primary_draw_hline_16bit(const char *pixel, int x1, int x2, int y)
  73. {
  74. rt_uint16_t *fb;
  75. struct rt_graphic_plane *plane = primary_gdev->primary_plane;
  76. fixup_dir(x1, x2);
  77. fb = framebuffer_drift(plane, x1, y, 16);
  78. for (; x1 < x2; ++x1)
  79. {
  80. *fb++ = *(rt_uint16_t *)pixel;
  81. }
  82. }
  83. static void graphic_primary_draw_vline_16bit(const char *pixel, int x, int y1, int y2)
  84. {
  85. rt_uint16_t *fb;
  86. struct rt_graphic_plane *plane = primary_gdev->primary_plane;
  87. fixup_dir(y1, y2);
  88. fb = framebuffer_drift(plane, x, y1, 16);
  89. for (; y1 < y2; ++y1)
  90. {
  91. *fb = *(rt_uint16_t *)pixel;
  92. fb = (void *)fb + plane->line_length;
  93. }
  94. }
  95. static void graphic_primary_blit_line_16bit(const char *pixel, int x, int y, rt_size_t size)
  96. {
  97. rt_uint16_t *fb;
  98. struct rt_graphic_plane *plane = primary_gdev->primary_plane;
  99. fb = framebuffer_drift(plane, x, y, 16);
  100. while (size --> 0)
  101. {
  102. *fb++ = *(rt_uint16_t *)pixel;
  103. pixel += 2;
  104. }
  105. }
  106. static struct rt_device_graphic_ops graphic_primary_16bit_ops =
  107. {
  108. .set_pixel = graphic_primary_set_pixel_16bit,
  109. .get_pixel = graphic_primary_get_pixel_16bit,
  110. .draw_hline = graphic_primary_draw_hline_16bit,
  111. .draw_vline = graphic_primary_draw_vline_16bit,
  112. .blit_line = graphic_primary_blit_line_16bit,
  113. };
  114. static void graphic_primary_set_pixel_24bit(const char *pixel, int x, int y)
  115. {
  116. struct rt_graphic_plane *plane = primary_gdev->primary_plane;
  117. rt_memcpy(framebuffer_drift(plane, x, y, 24), pixel, 3);
  118. }
  119. static void graphic_primary_get_pixel_24bit(char *pixel, int x, int y)
  120. {
  121. struct rt_graphic_plane *plane = primary_gdev->primary_plane;
  122. rt_memcpy(pixel, framebuffer_drift(plane, x, y, 24), 3);
  123. }
  124. static void graphic_primary_draw_hline_24bit(const char *pixel, int x1, int x2, int y)
  125. {
  126. rt_uint8_t *fb;
  127. struct rt_graphic_plane *plane = primary_gdev->primary_plane;
  128. fixup_dir(x1, x2);
  129. fb = framebuffer_drift(plane, x1, y, 24);
  130. for (; x1 < x2; ++x1)
  131. {
  132. *fb++ = ((rt_uint8_t *)pixel)[0];
  133. *fb++ = ((rt_uint8_t *)pixel)[1];
  134. *fb++ = ((rt_uint8_t *)pixel)[2];
  135. }
  136. }
  137. static void graphic_primary_draw_vline_24bit(const char *pixel, int x, int y1, int y2)
  138. {
  139. rt_uint8_t *fb;
  140. rt_size_t xlate;
  141. struct rt_graphic_plane *plane = primary_gdev->primary_plane;
  142. fixup_dir(y1, y2);
  143. fb = framebuffer_drift(plane, x, y1, 24);
  144. xlate = plane->line_length - 3;
  145. for (; y1 < y2; ++y1)
  146. {
  147. *fb++ = ((rt_uint8_t *)pixel)[0];
  148. *fb++ = ((rt_uint8_t *)pixel)[1];
  149. *fb++ = ((rt_uint8_t *)pixel)[2];
  150. fb = (void *)fb + xlate;
  151. }
  152. }
  153. static void graphic_primary_blit_line_24bit(const char *pixel, int x, int y, rt_size_t size)
  154. {
  155. rt_uint8_t *fb;
  156. struct rt_graphic_plane *plane = primary_gdev->primary_plane;
  157. fb = framebuffer_drift(plane, x, y, 24);
  158. while (size --> 0)
  159. {
  160. *fb++ = *(rt_uint8_t *)pixel++;
  161. *fb++ = *(rt_uint8_t *)pixel++;
  162. *fb++ = *(rt_uint8_t *)pixel++;
  163. }
  164. }
  165. static struct rt_device_graphic_ops graphic_primary_24bit_ops =
  166. {
  167. .set_pixel = graphic_primary_set_pixel_24bit,
  168. .get_pixel = graphic_primary_get_pixel_24bit,
  169. .draw_hline = graphic_primary_draw_hline_24bit,
  170. .draw_vline = graphic_primary_draw_vline_24bit,
  171. .blit_line = graphic_primary_blit_line_24bit,
  172. };
  173. static void graphic_primary_set_pixel_32bit(const char *pixel, int x, int y)
  174. {
  175. struct rt_graphic_plane *plane = primary_gdev->primary_plane;
  176. *(rt_uint32_t *)framebuffer_drift(plane, x, y, 32) = *(rt_uint32_t *)pixel;
  177. }
  178. static void graphic_primary_get_pixel_32bit(char *pixel, int x, int y)
  179. {
  180. struct rt_graphic_plane *plane = primary_gdev->primary_plane;
  181. *(rt_uint32_t *)pixel = *(rt_uint32_t *)framebuffer_drift(plane, x, y, 32);
  182. }
  183. static void graphic_primary_draw_hline_32bit(const char *pixel, int x1, int x2, int y)
  184. {
  185. rt_uint32_t *fb;
  186. struct rt_graphic_plane *plane = primary_gdev->primary_plane;
  187. fixup_dir(x1, x2);
  188. fb = framebuffer_drift(plane, x1, y, 32);
  189. for (; x1 < x2; ++x1)
  190. {
  191. *fb++ = *(rt_uint32_t *)pixel;
  192. }
  193. }
  194. static void graphic_primary_draw_vline_32bit(const char *pixel, int x, int y1, int y2)
  195. {
  196. rt_uint32_t *fb;
  197. struct rt_graphic_plane *plane = primary_gdev->primary_plane;
  198. fixup_dir(y1, y2);
  199. fb = framebuffer_drift(plane, x, y1, 32);
  200. for (; y1 < y2; ++y1)
  201. {
  202. *fb = *(rt_uint32_t *)pixel;
  203. fb = (void *)fb + plane->line_length;
  204. }
  205. }
  206. static void graphic_primary_blit_line_32bit(const char *pixel, int x, int y, rt_size_t size)
  207. {
  208. rt_uint32_t *fb;
  209. struct rt_graphic_plane *plane = primary_gdev->primary_plane;
  210. fb = framebuffer_drift(plane, x, y, 32);
  211. while (size --> 0)
  212. {
  213. *fb++ = *(rt_uint32_t *)pixel;
  214. pixel += 4;
  215. }
  216. }
  217. static struct rt_device_graphic_ops graphic_primary_32bit_ops =
  218. {
  219. .set_pixel = graphic_primary_set_pixel_32bit,
  220. .get_pixel = graphic_primary_get_pixel_32bit,
  221. .draw_hline = graphic_primary_draw_hline_32bit,
  222. .draw_vline = graphic_primary_draw_vline_32bit,
  223. .blit_line = graphic_primary_blit_line_32bit,
  224. };
  225. static void graphic_primary_set_pixel_64bit(const char *pixel, int x, int y)
  226. {
  227. struct rt_graphic_plane *plane = primary_gdev->primary_plane;
  228. *(rt_uint64_t *)framebuffer_drift(plane, x, y, 64) = *(rt_uint64_t *)pixel;
  229. }
  230. static void graphic_primary_get_pixel_64bit(char *pixel, int x, int y)
  231. {
  232. struct rt_graphic_plane *plane = primary_gdev->primary_plane;
  233. *(rt_uint64_t *)pixel = *(rt_uint64_t *)framebuffer_drift(plane, x, y, 64);
  234. }
  235. static void graphic_primary_draw_hline_64bit(const char *pixel, int x1, int x2, int y)
  236. {
  237. rt_uint64_t *fb;
  238. struct rt_graphic_plane *plane = primary_gdev->primary_plane;
  239. fixup_dir(x1, x2);
  240. fb = framebuffer_drift(plane, x1, y, 64);
  241. for (; x1 < x2; ++x1)
  242. {
  243. *fb++ = *(rt_uint64_t *)pixel;
  244. }
  245. }
  246. static void graphic_primary_draw_vline_64bit(const char *pixel, int x, int y1, int y2)
  247. {
  248. rt_uint64_t *fb;
  249. struct rt_graphic_plane *plane = primary_gdev->primary_plane;
  250. fixup_dir(y1, y2);
  251. fb = framebuffer_drift(plane, x, y1, 64);
  252. for (; y1 < y2; ++y1)
  253. {
  254. *fb = *(rt_uint64_t *)pixel;
  255. fb = (void *)fb + plane->line_length;
  256. }
  257. }
  258. static void graphic_primary_blit_line_64bit(const char *pixel, int x, int y, rt_size_t size)
  259. {
  260. rt_uint64_t *fb;
  261. struct rt_graphic_plane *plane = primary_gdev->primary_plane;
  262. fb = framebuffer_drift(plane, x, y, 64);
  263. while (size --> 0)
  264. {
  265. *fb++ = *(rt_uint64_t *)pixel;
  266. pixel += 8;
  267. }
  268. }
  269. static struct rt_device_graphic_ops graphic_primary_64bit_ops =
  270. {
  271. .set_pixel = graphic_primary_set_pixel_64bit,
  272. .get_pixel = graphic_primary_get_pixel_64bit,
  273. .draw_hline = graphic_primary_draw_hline_64bit,
  274. .draw_vline = graphic_primary_draw_vline_64bit,
  275. .blit_line = graphic_primary_blit_line_64bit,
  276. };
  277. struct rt_device_graphic_ops *rt_graphic_device_switch_primary(struct rt_graphic_device *gdev)
  278. {
  279. primary_gdev = gdev;
  280. RT_ASSERT(primary_gdev != RT_NULL);
  281. RT_ASSERT(primary_gdev->primary_plane != RT_NULL);
  282. switch (rt_graphic_mode_bpp(primary_gdev->primary_plane->mode))
  283. {
  284. case 32: return &graphic_primary_32bit_ops;
  285. case 24: return &graphic_primary_24bit_ops;
  286. case 16: return &graphic_primary_16bit_ops;
  287. case 64: return &graphic_primary_64bit_ops;
  288. case 8: return &graphic_primary_8bit_ops;
  289. default:
  290. LOG_E("What the fuck format(%u)", primary_gdev->primary_plane->mode);
  291. RT_ASSERT(0);
  292. break;
  293. }
  294. return RT_NULL;
  295. }