nxbe_bitmap.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. /****************************************************************************
  2. * graphics/nxbe/nxbe_bitmap.c
  3. *
  4. * Copyright (C) 2008-2009, 2012, 2016, 2019 Gregory Nutt. All rights
  5. * reserved.
  6. * Author: Gregory Nutt <gnutt@nuttx.org>
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in
  16. * the documentation and/or other materials provided with the
  17. * distribution.
  18. * 3. Neither the name NuttX nor the names of its contributors may be
  19. * used to endorse or promote products derived from this software
  20. * without specific prior written permission.
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  23. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  24. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  25. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  26. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  27. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  28. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  29. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  30. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  31. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  32. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  33. * POSSIBILITY OF SUCH DAMAGE.
  34. *
  35. ****************************************************************************/
  36. /****************************************************************************
  37. * Included Files
  38. ****************************************************************************/
  39. #include <nuttx/config.h>
  40. #include <assert.h>
  41. #include <errno.h>
  42. #include <debug.h>
  43. #include <nuttx/nx/nxglib.h>
  44. #include "nxbe.h"
  45. /****************************************************************************
  46. * Private Types
  47. ****************************************************************************/
  48. struct nx_bitmap_s
  49. {
  50. struct nxbe_clipops_s cops;
  51. FAR const void *src; /* The start of the source image. */
  52. struct nxgl_point_s origin; /* Offset into the source image data */
  53. unsigned int stride; /* The width of the full source image in pixels. */
  54. };
  55. /****************************************************************************
  56. * Private Functions
  57. ****************************************************************************/
  58. /****************************************************************************
  59. * Name: bitmap_clipcopy
  60. *
  61. * Description:
  62. * Called from nxbe_clipper() to performed the fill operation on visible portions
  63. * of the rectangle.
  64. *
  65. ****************************************************************************/
  66. static void bitmap_clipcopy(FAR struct nxbe_clipops_s *cops,
  67. FAR struct nxbe_plane_s *plane,
  68. FAR const struct nxgl_rect_s *rect)
  69. {
  70. struct nx_bitmap_s *bminfo = (struct nx_bitmap_s *)cops;
  71. /* Copy the rectangular region to the graphics device. */
  72. plane->dev.copyrectangle(&plane->pinfo, rect, bminfo->src,
  73. &bminfo->origin, bminfo->stride);
  74. #ifdef CONFIG_NX_UPDATE
  75. /* Notify external logic that the display has been updated */
  76. nx_notify_rectangle(&plane->pinfo, rect);
  77. #endif
  78. }
  79. /****************************************************************************
  80. * Name: nxbe_bitmap_pwfb
  81. *
  82. * Description:
  83. * Copy a rectangular region of a larger image into the per-window
  84. * framebuffer.
  85. *
  86. * Input Parameters:
  87. * wnd - The window that will receive the bitmap image
  88. * dest - Describes the rectangular on the display that will receive the
  89. * the bit map (window coordinate frame).
  90. * src - The start of the source image.
  91. * origin - The origin of the upper, left-most corner of the full bitmap.
  92. * Both dest and origin are in window coordinates, however, origin
  93. * may lie outside of the display.
  94. * stride - The width of the full source image in bytes.
  95. *
  96. * Returned Value:
  97. * OK on success; ERROR on failure with errno set appropriately
  98. *
  99. ****************************************************************************/
  100. #ifdef CONFIG_NX_RAMBACKED
  101. static inline void nxbe_bitmap_pwfb(FAR struct nxbe_window_s *wnd,
  102. FAR const struct nxgl_rect_s *dest,
  103. FAR const void *src[CONFIG_NX_NPLANES],
  104. FAR const struct nxgl_point_s *origin,
  105. unsigned int stride)
  106. {
  107. struct nxgl_rect_s destrect;
  108. unsigned int deststride;
  109. DEBUGASSERT(wnd != NULL && dest != NULL && src != NULL && origin != NULL);
  110. DEBUGASSERT(wnd->be != NULL && wnd->be->plane != NULL);
  111. /* Verify that the destination rectangle begins "below" and to the "right"
  112. * of the origin
  113. */
  114. if (dest->pt1.x < origin->x || dest->pt1.y < origin->y)
  115. {
  116. gerr("ERROR: Bad dest start position\n");
  117. return;
  118. }
  119. /* Verify that the width of the destination rectangle does not exceed the
  120. * width of the source bitmap data (taking into account the bitmap origin)
  121. */
  122. deststride = (((dest->pt2.x - origin->x + 1) *
  123. wnd->be->plane[0].pinfo.bpp + 7) >> 3);
  124. if (deststride > stride)
  125. {
  126. gerr("ERROR: Bad dest width\n");
  127. return;
  128. }
  129. /* Offset the rectangle and image origin by the window origin. This
  130. * converts the rectangle in the device absolute coordinates.
  131. */
  132. nxgl_rectoffset(&destrect, dest, wnd->bounds.pt1.x, wnd->bounds.pt1.y);
  133. /* Clip to the limits of the window and of the background screen (in
  134. * device coordinates.
  135. */
  136. nxgl_rectintersect(&destrect, &destrect, &wnd->bounds);
  137. nxgl_rectintersect(&destrect, &destrect, &wnd->be->bkgd.bounds);
  138. if (!nxgl_nullrect(&destrect))
  139. {
  140. /* Restore the destination rectangle to relative window coordinates. */
  141. nxgl_rectoffset(&destrect, &destrect,
  142. -wnd->bounds.pt1.x, -wnd->bounds.pt1.y);
  143. /* Copy the rectangular region to the framebuffer (no clipping).
  144. * REVISIT: Assumes a single color plane.
  145. */
  146. DEBUGASSERT(wnd->be->plane[0].pwfb.copyrectangle != NULL);
  147. wnd->be->plane[0].pwfb.copyrectangle(wnd, &destrect, src[0],
  148. origin, stride);
  149. }
  150. }
  151. #endif
  152. /****************************************************************************
  153. * Public Functions
  154. ****************************************************************************/
  155. /****************************************************************************
  156. * Name: nxbe_bitmap_dev
  157. *
  158. * Description:
  159. * Copy a rectangular region of a larger image into the rectangle in the
  160. * specified window. The graphics output is written to the graphics
  161. * device unconditionally.
  162. *
  163. * Input Parameters:
  164. * wnd - The window that will receive the bitmap image
  165. * dest - Describes the rectangular region on the display that will
  166. * receive the the bit map (window coordinate frame).
  167. * src - The start of the source image.
  168. * origin - The origin of the upper, left-most corner of the full bitmap.
  169. * Both dest and origin are in window coordinates, however, origin
  170. * may lie outside of the display.
  171. * stride - The width of the full source image in bytes.
  172. *
  173. * Returned Value:
  174. * OK on success; ERROR on failure with errno set appropriately
  175. *
  176. ****************************************************************************/
  177. void nxbe_bitmap_dev(FAR struct nxbe_window_s *wnd,
  178. FAR const struct nxgl_rect_s *dest,
  179. FAR const void *src[CONFIG_NX_NPLANES],
  180. FAR const struct nxgl_point_s *origin,
  181. unsigned int stride)
  182. {
  183. struct nx_bitmap_s info;
  184. struct nxgl_rect_s bounds;
  185. struct nxgl_point_s offset;
  186. struct nxgl_rect_s remaining;
  187. unsigned int deststride;
  188. int i;
  189. DEBUGASSERT(wnd != NULL && dest != NULL && src != NULL && origin != NULL);
  190. DEBUGASSERT(wnd->be != NULL && wnd->be->plane != NULL);
  191. /* Don't update hidden windows */
  192. if (NXBE_ISHIDDEN(wnd))
  193. {
  194. return;
  195. }
  196. /* Verify that the destination rectangle begins "below" and to the "right"
  197. * of the origin
  198. */
  199. if (dest->pt1.x < origin->x || dest->pt1.y < origin->y)
  200. {
  201. gerr("ERROR: Bad dest start position\n");
  202. return;
  203. }
  204. /* Verify that the width of the destination rectangle does not exceed the
  205. * width of the source bitmap data (taking into account the bitmap origin)
  206. */
  207. deststride = (((dest->pt2.x - origin->x + 1) *
  208. wnd->be->plane[0].pinfo.bpp + 7) >> 3);
  209. if (deststride > stride)
  210. {
  211. gerr("ERROR: Bad dest width\n");
  212. return;
  213. }
  214. /* Offset the rectangle and image origin by the window origin */
  215. nxgl_rectoffset(&bounds, dest, wnd->bounds.pt1.x, wnd->bounds.pt1.y);
  216. nxgl_vectoradd(&offset, origin, &wnd->bounds.pt1);
  217. /* Clip to the limits of the window and of the background screen */
  218. nxgl_rectintersect(&remaining, &bounds, &wnd->bounds);
  219. nxgl_rectintersect(&remaining, &remaining, &wnd->be->bkgd.bounds);
  220. if (nxgl_nullrect(&remaining))
  221. {
  222. return;
  223. }
  224. /* Then perform the clipped fill */
  225. #if CONFIG_NX_NPLANES > 1
  226. for (i = 0; i < wnd->be->vinfo.nplanes; i++)
  227. #else
  228. i = 0;
  229. #endif
  230. {
  231. DEBUGASSERT(wnd->be->plane[i].dev.copyrectangle != NULL);
  232. info.cops.visible = bitmap_clipcopy;
  233. info.cops.obscured = nxbe_clipnull;
  234. info.src = src[i];
  235. info.origin.x = offset.x;
  236. info.origin.y = offset.y;
  237. info.stride = stride;
  238. nxbe_clipper(wnd->above, &remaining, NX_CLIPORDER_DEFAULT,
  239. &info.cops, &wnd->be->plane[i]);
  240. }
  241. }
  242. /****************************************************************************
  243. * Name: nxbe_bitmap
  244. *
  245. * Description:
  246. * Copy a rectangular region of a larger image into the rectangle in the
  247. * specified window. This is a front end to nxbe_bitmap_dev() that is
  248. * used only if CONFIG_NX_RAMBACKED=y. If the per-window frame buffer is
  249. * selected, then the bit map will be written to both the graphics device
  250. * and shadowed in the per-window framebuffer.
  251. *
  252. * Input Parameters:
  253. * wnd - The window that will receive the bitmap image
  254. * dest - Describes the rectangular region on the display that will
  255. * receive the the bit map (window coordinate frame).
  256. * src - The start of the source image.
  257. * origin - The origin of the upper, left-most corner of the full bitmap.
  258. * Both dest and origin are in window coordinates, however, origin
  259. * may lie outside of the display.
  260. * stride - The width of the full source image in bytes.
  261. *
  262. * Returned Value:
  263. * None
  264. *
  265. ****************************************************************************/
  266. void nxbe_bitmap(FAR struct nxbe_window_s *wnd,
  267. FAR const struct nxgl_rect_s *dest,
  268. FAR const void *src[CONFIG_NX_NPLANES],
  269. FAR const struct nxgl_point_s *origin,
  270. unsigned int stride)
  271. {
  272. #ifdef CONFIG_NX_RAMBACKED
  273. /* If this window supports a pre-window frame buffer then shadow the full,
  274. * unclipped bitmap in that framebuffer.
  275. */
  276. if (NXBE_ISRAMBACKED(wnd))
  277. {
  278. /* Update the per-window framebuffer */
  279. nxbe_bitmap_pwfb(wnd, dest, src, origin, stride);
  280. }
  281. #endif
  282. /* Don't update hidden windows */
  283. if (!NXBE_ISHIDDEN(wnd))
  284. {
  285. /* Rend the bitmap directly to the graphics device */
  286. nxbe_bitmap_dev(wnd, dest, src, origin, stride);
  287. #ifdef CONFIG_NX_SWCURSOR
  288. /* Update cursor backup memory and redraw the cursor in the modified window
  289. * region.
  290. */
  291. nxbe_cursor_backupdraw_all(wnd, dest);
  292. #endif
  293. }
  294. }