graphics/nxbe: More work cursor coordinates. Still at least one big bug in the logic.

This commit is contained in:
Gregory Nutt
2019-04-13 10:13:00 -06:00
parent c38b6cb068
commit 099d9f94f4
13 changed files with 405 additions and 124 deletions
+3 -3
View File
@@ -44,9 +44,9 @@ ifeq ($(CONFIG_NX_RAMBACKED),y)
CSRCS += nxbe_flush.c
endif
ifeq ($(CONFIG_NX_HWCURSOR),y)
CSRCS += nxbe_cursor.c
else ifeq ($(CONFIG_NX_SWCURSOR),y)
ifeq ($(CONFIG_NX_SWCURSOR),y)
CSRCS += nxbe_cursor.c nxbe_cursor_backupdraw.c
else ifeq ($(CONFIG_NX_HWCURSOR),y)
CSRCS += nxbe_cursor.c
endif
+53
View File
@@ -374,8 +374,61 @@ void nxbe_cursor_setimage(FAR struct nxbe_state_s *be,
void nxbe_cursor_setposition(FAR struct nxbe_state_s *be,
FAR const struct nxgl_point_s *pos);
#endif /* CONFIG_NX_SWCURSOR || CONFIG_NX_HWCURSOR */
#ifdef CONFIG_NX_SWCURSOR
/****************************************************************************
* Name: nxbe_cursor_backupdraw and nxbe_cursor_backupdraw_dev
*
* Description:
* Called after any modification to the display (in window coordinate
* frame) to perform the backup-draw operation on one color plane.
*
* Input Parameters:
* be - The back-end state structure instance, or
* wnd - Window state structure
* rect - The modified region of the window. In windows coordinates for
* nxbe_cursor_backupdraw(); in graphics device corrdinates for
* nxbe_cursor_backupdraw_dev().
* plane - The plane number to use.
*
* Returned Value:
* None
*
****************************************************************************/
void nxbe_cursor_backupdraw(FAR struct nxbe_window_s *wnd,
FAR const struct nxgl_rect_s *rect, int plane);
void nxbe_cursor_backupdraw_dev(FAR struct nxbe_state_s *be,
FAR const struct nxgl_rect_s *rect,
int plane);
/****************************************************************************
* Name: nxbe_cursor_backupdraw_all and nxbe_cursor_backupdraw_devall
*
* Description:
* Called after any modification to the display to perform the backup-draw
* operation on all color planes.
*
* Input Parameters:
* be - The back-end state structure instance, or
* wnd - Window state structure
* rect - The modified region of the window. In windows coordinates for
* nxbe_cursor_backupdraw(); in graphics device corrdinates for
* nxbe_cursor_backupdraw_dev().
*
* Returned Value:
* None
*
****************************************************************************/
void nxbe_cursor_backupdraw_all(FAR struct nxbe_window_s *wnd,
FAR const struct nxgl_rect_s *rect);
void nxbe_cursor_backupdraw_devall(FAR struct nxbe_state_s *be,
FAR const struct nxgl_rect_s *rect);
#endif /* */
/****************************************************************************
* Name: nxbe_closewindow
*
+4 -15
View File
@@ -329,21 +329,10 @@ void nxbe_bitmap(FAR struct nxbe_window_s *wnd,
nxbe_bitmap_dev(wnd, dest, src, origin, stride);
#ifdef CONFIG_NX_SWCURSOR
/* Update the software cursor if it is visible */
/* Update cursor backup memory and redraw the cursor in the modified window
* region.
*/
if (wnd->be->cursor.visible)
{
/* Save the modified cursor background region
* REVISIT: Only a single color plane is supported
*/
wnd->be->plane[0].cursor.backup(wnd->be, dest, 0);
/* Restore the software cursor if any part of the cursor was
* overwritten by the bitmap copy.
*/
wnd->be->plane[0].cursor.draw(wnd->be, dest, 0);
}
nxbe_cursor_backupdraw_all(wnd, dest);
#endif
}
+53 -14
View File
@@ -84,14 +84,25 @@ void nxbe_cursor_enable(FAR struct nxbe_state_s *be, bool enable)
if (be->cursor.image != NULL)
{
/* Save the cursor background image */
struct nxgl_rect_s bounds;
DEBUGASSERT(be->cursor.bkgd != NULL);
be->plane[0].cursor.backup(be, &be->cursor.bounds, 0);
/* Write the new cursor image to device memory */
/* Handle the case where some or all of the cursor is off the
* display.
*/
be->plane[0].cursor.draw(be, &be->cursor.bounds, 0);
nxgl_rectintersect(&bounds, &be->cursor.bounds, &be->bkgd.bounds);
if (!nxgl_nullrect(&bounds))
{
/* Save the cursor background image */
be->plane[0].cursor.backup(be, &bounds, 0);
/* Write the new cursor image to device memory */
be->plane[0].cursor.draw(be, &bounds, 0);
}
/* Mark the cursor visible */
@@ -114,15 +125,26 @@ void nxbe_cursor_enable(FAR struct nxbe_state_s *be, bool enable)
else if (!enable && be->cursor.visible)
{
struct nxgl_rect_s bounds;
/* Mark the cursor not visible */
be->cursor.visible = false;
#ifdef CONFIG_NX_SWCURSOR
/* Erase the old cursor image by writing the saved background image. */
DEBUGASSERT(be->cursor.bkgd != NULL);
be->plane[0].cursor.erase(be, &be->cursor.bounds, 0);
/* Handle the case where some or all of the cursor is off the display. */
nxgl_rectintersect(&bounds, &be->cursor.bounds, &be->bkgd.bounds);
if (!nxgl_nullrect(&bounds))
{
/* Erase the old cursor image by writing the saved background
* image.
*/
be->plane[0].cursor.erase(be, &bounds, 0);
}
#else
/* For a hardware cursor, this would require some interaction with the
* grahics device.
@@ -162,6 +184,7 @@ void nxbe_cursor_setimage(FAR struct nxbe_state_s *be,
{
#ifdef CONFIG_NX_SWCURSOR
struct nxgl_size_s oldsize;
struct nxgl_rect_s bounds;
size_t allocsize;
unsigned int bpp;
@@ -173,10 +196,18 @@ void nxbe_cursor_setimage(FAR struct nxbe_state_s *be,
if (be->cursor.visible)
{
/* Erase the old cursor image by writing the saved background image. */
/* Handle the case where some or all of the cursor is off the display. */
DEBUGASSERT(be->cursor.bkgd != NULL);
be->plane[0].cursor.erase(be, &be->cursor.bounds, 0);
nxgl_rectintersect(&bounds, &be->cursor.bounds, &be->bkgd.bounds);
if (!nxgl_nullrect(&bounds))
{
/* Erase the old cursor image by writing the saved background
* image.
*/
DEBUGASSERT(be->cursor.bkgd != NULL);
be->plane[0].cursor.erase(be, &bounds, 0);
}
}
/* Has the cursor changed size? */
@@ -311,13 +342,21 @@ void nxbe_cursor_setposition(FAR struct nxbe_state_s *be,
if (be->cursor.visible)
{
/* Read in the new background image at this offset */
struct nxgl_rect_s bounds;
be->plane[0].cursor.backup(be, &be->cursor.bounds, 0);
/* Handle the case where some or all of the cursor is off the display. */
/* Write the new cursor image to the device graphics memory. */
nxgl_rectintersect(&bounds, &be->cursor.bounds, &be->bkgd.bounds);
if (!nxgl_nullrect(&bounds))
{
/* Read in the new background image at this offset */
be->plane[0].cursor.draw(be, &be->cursor.bounds, 0);
be->plane[0].cursor.backup(be, &bounds, 0);
/* Write the new cursor image to the device graphics memory. */
be->plane[0].cursor.draw(be, &bounds, 0);
}
}
#else
+224
View File
@@ -0,0 +1,224 @@
/****************************************************************************
* graphics/nxbe/nxbe_cursor_backupdraw.c
*
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <assert.h>
#include "nxglib.h"
#include "nxbe.h"
#ifdef CONFIG_NX_SWCURSOR
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: _nxbe_cursor_backupdraw_dev
*
* Description:
* Called after any modification to the display to backup and redraw one
* color plane
*
* Input Parameters:
* be - The back-end state structure instance
* rect - The modified region of the display, in device coordinates
* plane - The plane number to use.
*
* Returned Value:
* None
*
****************************************************************************/
static inline void _nxbe_cursor_backupdraw_dev(FAR struct nxbe_state_s *be,
FAR const struct nxgl_rect_s *rect,
int plane)
{
/* Save the modified cursor background region. */
be->plane[plane].cursor.backup(be, rect, plane);
/* Restore the software cursor in the region that was modified. */
be->plane[plane].cursor.draw(be, rect, plane);
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: nxbe_cursor_backupdraw
*
* Description:
* Called after any modification to the display (in window coordinate
* frame) to perform the backup-draw operation on one color plane.
*
* Input Parameters:
* be - The back-end state structure instance, or
* wnd - Window state structure
* rect - The modified region of the window, in windows coordinates
* plane - The plane number to use.
*
* Returned Value:
* None
*
****************************************************************************/
void nxbe_cursor_backupdraw_dev(FAR struct nxbe_state_s *be,
FAR const struct nxgl_rect_s *rect,
int plane)
{
struct nxgl_rect_s bounds;
/* Update the software cursor if it is visible */
if (be->cursor.visible)
{
/* Clip to the limits of the display */
nxgl_rectintersect(&bounds, &bounds, &be->bkgd.bounds);
if (!nxgl_nullrect(&bounds))
{
_nxbe_cursor_backupdraw_dev(be, &bounds, plane);
}
}
}
void nxbe_cursor_backupdraw(FAR struct nxbe_window_s *wnd,
FAR const struct nxgl_rect_s *rect,
int plane)
{
struct nxgl_rect_s bounds;
/* Update the software cursor if it is visible */
if (wnd->be->cursor.visible)
{
/* Offset the rectangle to convert to device coordinates */
nxgl_rectoffset(&bounds, rect, wnd->bounds.pt1.x, wnd->bounds.pt1.y);
/* Clip to the limits of the window */
nxgl_rectintersect(&bounds, &bounds, &wnd->bounds);
/* Let nxbe_cursor_backupdraw_dev() do the rest */
nxbe_cursor_backupdraw_dev(wnd->be, &bounds, plane);
}
}
/****************************************************************************
* Name: nxbe_cursor_backupdraw_all and nxbe_cursor_backupdraw_devall
*
* Description:
* Called after any modification to the display to perform the backup-draw
* operation on all color planes.
*
* Input Parameters:
* be - The back-end state structure instance, or
* wnd - Window state structure
* rect - The modified region of the window. In windows coordinates for
* nxbe_cursor_backupdraw(); in graphics device corrdinates for
* nxbe_cursor_backupdraw_dev().
*
* Returned Value:
* None
*
****************************************************************************/
void nxbe_cursor_backupdraw_devall(FAR struct nxbe_state_s *be,
FAR const struct nxgl_rect_s *rect)
{
#if CONFIG_NX_NPLANES > 1
struct nxgl_rect_s bounds;
int plane;
/* Update the software cursor if it is visible */
if (be->cursor.visible)
{
/* Clip to the limits of the display */
nxgl_rectintersect(&bounds, &bounds, &be->bkgd.bounds);
if (!nxgl_nullrect(&bounds))
{
/* Perform the backup-draw operation on all color planes */
for (plane = 0; plane < CONFIG_NX_NPLANES; plane++)
{
_nxbe_cursor_backupdraw_dev(be, &bounds, plane);
}
}
}
#else
nxbe_cursor_backupdraw_dev(be, rect, 0);
#endif
}
void nxbe_cursor_backupdraw_all(FAR struct nxbe_window_s *wnd,
FAR const struct nxgl_rect_s *rect)
{
#if CONFIG_NX_NPLANES > 1
struct nxgl_rect_s bounds;
/* Update the software cursor if it is visible */
if (wnd->be->cursor.visible)
{
/* Offset the rectangle to convert it to device coordinates */
nxgl_rectoffset(&bounds, rect, wnd->bounds.pt1.x, wnd->bounds.pt1.y);
/* Clip to the limits of the window */
nxgl_rectintersect(&bounds, &bounds, &wnd->bounds);
/* And then let nxbe_cursor_backupdraw_devall() do the rest */
nxbe_cursor_backupdraw_all(be, &bounds);
}
#else
nxbe_cursor_backupdraw(wnd->be, rect, 0);
#endif
}
#endif /* CONFIG_NX_SWCURSOR */
+8 -19
View File
@@ -129,26 +129,15 @@ static inline void nxbe_fill_dev(FAR struct nxbe_window_s *wnd,
&info.cops, &wnd->be->plane[i]);
#ifdef CONFIG_NX_SWCURSOR
/* Update the software cursor if it is visible */
/* Backup and redraw the cursor in the affect region.
*
* REVISIT: This and the following logic belongs in the function
* nxbe_clipfill(). It is here only because the struct nxbe_state_s
* (wnd->be) is not available at that point. This may result in an
* excessive number of cursor updates.
*/
if (wnd->be->cursor.visible)
{
/* Save the modified cursor background region.
*
* REVISIT: This and the following logic belongs in the function
* nxbe_clipfill(). It is here only because the struct nxbe_state_s
* (wnd->be) is not available at that point. This may result in an
* excessive number of cursor updates.
*/
wnd->be->plane[i].cursor.backup(wnd->be, rect, i);
/* Restore the software cursor if any part of the cursor was
* overwritten by the fill.
*/
wnd->be->plane[i].cursor.draw(wnd->be, rect, i);
}
nxbe_cursor_backupdraw_dev(wnd->be, rect, i);
#endif
}
}
+8 -19
View File
@@ -159,26 +159,15 @@ static inline void nxbe_filltrapezoid_dev(FAR struct nxbe_window_s *wnd,
&info.cops, &wnd->be->plane[i]);
#ifdef CONFIG_NX_SWCURSOR
/* Update the software cursor if it is visible */
/* Backup and redraw the cursor in the modified region.
*
* REVISIT: This and the following logic belongs in the function
* nxbe_clipfill(). It is here only because the struct nxbe_state_s
* (wnd->be) is not available at that point. This may result in an
* excessive number of cursor updates.
*/
if (wnd->be->cursor.visible)
{
/* Save the modified cursor background region.
*
* REVISIT: This and the following logic belongs in the function
* nxbe_clipfilltrapezoid(). It is here only because the struct
* nxbe_state_s (wnd->be) is not available at that point. This
* result in an excessive number of cursor updates.
*/
wnd->be->plane[i].cursor.backup(wnd->be, bounds, i);
/* Restore the software cursor if any part of the cursor was
* overwritten by the fill.
*/
wnd->be->plane[i].cursor.draw(wnd->be, bounds, i);
}
nxbe_cursor_backupdraw_dev(wnd->be, bounds, i);
#endif
}
}
+5 -10
View File
@@ -72,7 +72,7 @@
* Input Parameters (same as for nxbe_flush):
* wnd - The window that will receive the bitmap image
* dest - Describes the rectangular on the display that will receive the
* the bit map.
* the bit map (device corrdinates).
* src - The start of the source image.
* origin - The origin of the upper, left-most corner of the full bitmap.
* Both dest and origin are in window coordinates, however, origin
@@ -95,16 +95,11 @@ void nxbe_flush(FAR struct nxbe_window_s *wnd,
nxbe_bitmap_dev(wnd, dest, src, origin, stride);
#ifdef CONFIG_NX_SWCURSOR
/* Is the software cursor visible? */
/* Update cursor backup memory and redraw the cursor in the modified window
* region.
*/
if (wnd->be->cursor.visible)
{
/* Restore the software cursor if any part of the cursor was
* overwritten by the above copy.
*/
wnd->be->plane[0].cursor.draw(wnd->be, dest, 0);
}
nxbe_cursor_backupdraw_devall(wnd, dest);
#endif
}
+26
View File
@@ -202,6 +202,19 @@ void nxbe_getrectangle(FAR struct nxbe_window_s *wnd,
else
#endif
{
#ifdef CONFIG_NX_SWCURSOR
/* Is the software cursor visible? */
if (wnd->be->cursor.visible)
{
/* Erase any portion of the cursor that may be above this
* region.
* REVISIT: Only a single color plane is supported
*/
wnd->be->plane[0].cursor.erase(wnd->be, &remaining, 0);
}
#endif
/* Get the rectangle from the graphics device memory.
* NOTE: Since raw graphic memory is returned, the returned memory
* content may be the memory of windows above this one and may
@@ -209,6 +222,19 @@ void nxbe_getrectangle(FAR struct nxbe_window_s *wnd,
*/
nxbe_getrectangle_dev(wnd, rect, plane, dest, deststride);
#ifdef CONFIG_NX_SWCURSOR
/* Was the software cursor visible? */
if (wnd->be->cursor.visible)
{
/* Restore the software cursor if any part of the cursor was
* erased above.
*/
wnd->be->plane[0].cursor.draw(wnd->be, &remaining, 0);
}
#endif
}
}
}
+10 -23
View File
@@ -200,7 +200,8 @@ static void nxbe_clipmovedest(FAR struct nxbe_clipops_s *cops,
*
* Input Parameters:
* wnd - The window within which the move is to be done
* rect - Describes the rectangular region to move (absolute positions)
* rect - Describes the rectangular region to move (absolute device
* positions)
* offset - The offset to move the region
*
* Returned Value:
@@ -293,30 +294,16 @@ static inline void nxbe_move_dev(FAR struct nxbe_window_s *wnd,
nxbe_clipper(wnd->above, &info.srcrect, info.order,
&info.cops, &wnd->be->plane[i]);
#ifdef CONFIG_NX_SWCURSOR
/* Update the software cursor if it is visible */
/* Backup and redraw the cursor in the modified region.
*
* REVISIT: This and the following logic belongs in the function
* nxbe_clipfill(). It is here only because the struct nxbe_state_s
* (wnd->be) is not available at that point. This may result in an
* excessive number of cursor updates.
*/
if (wnd->be->cursor.visible)
{
/* Save the modified cursor background region at the destination
* region. This would be necessary only for small moves that stay
* within the cursor region.
*
* REVISIT: This and the following logic belongs in the function
* nxbe_clipmovedest(). It is here only because the struct
* nxbe_state_s (wnd->be) is not available at that point. This
* result in an excessive number of cursor updates.
*/
wnd->be->plane[i].cursor.backup(wnd->be, &dest, i);
/* Restore the software cursor if any part of the cursor was
* overwritten by the fill.
*/
wnd->be->plane[i].cursor.draw(wnd->be, &dest, i);
}
nxbe_cursor_backupdraw_dev(wnd->be, &dest, i);
#endif
}
}
+2 -2
View File
@@ -66,8 +66,8 @@ struct nxbe_redraw_s
****************************************************************************/
static void nxbe_clipredraw(FAR struct nxbe_clipops_s *cops,
FAR struct nxbe_plane_s *plane,
FAR const struct nxgl_rect_s *rect)
FAR struct nxbe_plane_s *plane,
FAR const struct nxgl_rect_s *rect)
{
FAR struct nxbe_window_s *wnd = ((struct nxbe_redraw_s *)cops)->wnd;
if (wnd)
+8 -18
View File
@@ -153,25 +153,15 @@ void nxbe_setpixel(FAR struct nxbe_window_s *wnd,
&info.cops, &wnd->be->plane[i]);
#ifdef CONFIG_NX_SWCURSOR
/* Update the software cursor if it is visible */
/* Update cursor backup memory and redraw the cursor in the modified
* window region.
*
* REVISIT: This and the following logic belongs in the function
* nxbe_clipfill(). It is here only because the struct
* nxbe_state_s (wnd->be) is not available at that point.
*/
if (wnd->be->cursor.visible)
{
/* Save the modified cursor pixe at the point.
*
* REVISIT: This and the following logic belongs in the function
* nxbe_clipfill(). It is here only because the struct
* nxbe_state_s (wnd->be) is not available at that point.
*/
wnd->be->plane[i].cursor.backup(wnd->be, &rect, i);
/* Restore the software cursor if if that point is a visible
* cursor bit that was overwritten by the above operation.
*/
wnd->be->plane[i].cursor.draw(wnd->be, &rect, i);
}
nxbe_cursor_backupdraw_dev(wnd->be, &rect, i);
#endif
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
/****************************************************************************
* graphics/nxbe/nxbe_redraw.c
* graphics/nxbe/nxbe_visible.c
*
* Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>