This commit brings the per-framebuffer logic to code-complete. Still untested.

Squashed commit of the following:

    Update TODO list

    graphics/nxbe:  The moverectangle renderer now supports updates to the per-window framebuffer (unclipped) as well as the graphics device memory (clipped).

    graphics/nxbe:  The filltrapezond renderer now supports updates to the per-window framebuffer (unclipped) as well as the graphics device memory (clipped).

    graphics/nxbe:  The getrectangle method now returns data from the per-window framebuffer if available.

    graphics/nxbe:  The fillrectangle renderer now supports updates to the per-window framebuffer (unclipped) as well as the graphics device memory (clipped).

    graphics/nxmu:  If a window supports a per-window framebuffer, then redraw callbacks are suppressed and the device content is updated from the shadow, per-window framebuffer.  graphics/nxbe:  The copyrectangle renderer now supports updates to the per-window framebuffer (unclipped) as well as the graphics device memory (clipped).

    graphics/nxbe/nxbe_setsize.c:  Reallocate the per-window framebuffer when the window size changes.
This commit is contained in:
Gregory Nutt
2019-03-15 12:15:33 -06:00
parent 1690f2ca8b
commit 9a97eb0fcf
12 changed files with 1163 additions and 258 deletions
+78 -10
View File
@@ -69,10 +69,10 @@
/* Rasterization ************************************************************/
/* A vtable of raster operation function pointers. The types of the
* function points must match the rasterizer types exported by nxglib
* function points must match the device rasterizer types exported by nxglib.
*/
struct nxbe_vtable_s
struct nxbe_dev_vtable_s
{
CODE void (*setpixel)(FAR NX_PLANEINFOTYPE *pinfo,
FAR const struct nxgl_point_s *pos,
@@ -88,7 +88,7 @@ struct nxbe_vtable_s
FAR const struct nxgl_rect_s *bounds,
nxgl_mxpixel_t color);
CODE void (*moverectangle)(FAR NX_PLANEINFOTYPE *pinfo,
FAR const struct nxgl_rect_s *rect,
FAR const struct nxgl_rect_s *rect,
FAR struct nxgl_point_s *offset);
CODE void (*copyrectangle)(FAR NX_PLANEINFOTYPE *pinfo,
FAR const struct nxgl_rect_s *dest,
@@ -97,18 +97,50 @@ struct nxbe_vtable_s
unsigned int srcstride);
};
#ifdef CONFIG_NX_RAMBACKED
/* A vtable of raster operation function pointers. The types of the
* function points must match the per-window framebuffer rasterizer types
* exported by nxglib.
*/
struct nxbe_pwfb_vtable_s
{
CODE void (*setpixel)(FAR struct nxbe_window_s *bwnd,
FAR const struct nxgl_point_s *pos,
nxgl_mxpixel_t color);
CODE void (*fillrectangle)(FAR struct nxbe_window_s *bwnd,
FAR const struct nxgl_rect_s *rect,
nxgl_mxpixel_t color);
CODE void (*getrectangle)(FAR struct nxbe_window_s *bwnd,
FAR const struct nxgl_rect_s *rect,
FAR void *dest, unsigned int deststride);
CODE void (*filltrapezoid)(FAR struct nxbe_window_s *bwnd,
FAR const struct nxgl_trapezoid_s *trap,
FAR const struct nxgl_rect_s *bounds,
nxgl_mxpixel_t color);
CODE void (*moverectangle)(FAR struct nxbe_window_s *bwnd,
FAR const struct nxgl_rect_s *rect,
FAR struct nxgl_point_s *offset);
CODE void (*copyrectangle)(FAR struct nxbe_window_s *bwnd,
FAR const struct nxgl_rect_s *dest,
FAR const void *src,
FAR const struct nxgl_point_s *origin,
unsigned int srcstride);
};
#endif
/* Encapsulates everything needed support window rasterization commands. */
struct nxbe_plane_s
{
/* Raster device operation callbacks for this plane */
/* Raster device operation callbacks */
struct nxbe_vtable_s dev;
struct nxbe_dev_vtable_s dev;
#ifdef CONFIG_NX_RAMBACKED
/* Raster per-window framebuffer operation callbacks for this plane */
/* Raster per-window framebuffer operation callbacks */
struct nxbe_vtable_s pwfb;
struct nxbe_pwfb_vtable_s pwfb;
#endif
/* Framebuffer plane info describing destination video plane */
@@ -373,11 +405,12 @@ void nxbe_move(FAR struct nxbe_window_s *wnd,
FAR const struct nxgl_point_s *offset);
/****************************************************************************
* Name: nxbe_bitmap
* Name: nxbe_bitmap_dev
*
* Description:
* Copy a rectangular region of a larger image into the rectangle in the
* specified window.
* specified window. The graphics output is written to the graphics
* device unconditionally.
*
* Input Parameters:
* wnd - The window that will receive the bitmap image
@@ -390,15 +423,50 @@ void nxbe_move(FAR struct nxbe_window_s *wnd,
* stride - The width of the full source image in pixels.
*
* Returned Value:
* OK on success; ERROR on failure with errno set appropriately
* None
*
****************************************************************************/
void nxbe_bitmap_dev(FAR struct nxbe_window_s *wnd,
FAR const struct nxgl_rect_s *dest,
FAR const void *src[CONFIG_NX_NPLANES],
FAR const struct nxgl_point_s *origin,
unsigned int stride);
/****************************************************************************
* Name: nxbe_bitmap
*
* Description:
* Copy a rectangular region of a larger image into the rectangle in the
* specified window. This is a front end to nxbe_bitmap_dev() that is
* used only if CONFIG_NX_RAMBACKED=y. If the per-window frame buffer is
* selected, then the bit map will be written to both the graphics device
* and shadowed in the per-window framebuffer.
*
* Input Parameters:
* wnd - The window that will receive the bitmap image
* dest - Describes the rectangular on the display that will receive the
* the bit map.
* 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
* may lie outside of the display.
* stride - The width of the full source image in bytes.
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_NX_RAMBACKED
void nxbe_bitmap(FAR struct nxbe_window_s *wnd,
FAR const struct nxgl_rect_s *dest,
FAR const void *src[CONFIG_NX_NPLANES],
FAR const struct nxgl_point_s *origin,
unsigned int stride);
#else
# define nxbe_bitmap(w,d,s,o,n) nxbe_bitmap_dev(w,d,s,o,n)
#endif
/****************************************************************************
* Name: nxbe_redraw
+157 -25
View File
@@ -40,6 +40,7 @@
#include <nuttx/config.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
@@ -63,7 +64,7 @@ struct nx_bitmap_s
****************************************************************************/
/****************************************************************************
* Name: nxs_clipcopy
* Name: bitmap_clipcopy
*
* Description:
* Called from nxbe_clipper() to performed the fill operation on visible portions
@@ -71,9 +72,9 @@ struct nx_bitmap_s
*
****************************************************************************/
static void nxs_clipcopy(FAR struct nxbe_clipops_s *cops,
FAR struct nxbe_plane_s *plane,
FAR const struct nxgl_rect_s *rect)
static void bitmap_clipcopy(FAR struct nxbe_clipops_s *cops,
FAR struct nxbe_plane_s *plane,
FAR const struct nxgl_rect_s *rect)
{
struct nx_bitmap_s *bminfo = (struct nx_bitmap_s *)cops;
@@ -90,15 +91,11 @@ static void nxs_clipcopy(FAR struct nxbe_clipops_s *cops,
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: nxbe_bitmap
* Name: nxbe_bitmap_pwfb
*
* Description:
* Copy a rectangular region of a larger image into the rectangle in the
* specified window.
* Copy a rectangular region of a larger image into the per-window
* framebuffer.
*
* Input Parameters:
* wnd - The window that will receive the bitmap image
@@ -108,30 +105,27 @@ static void nxs_clipcopy(FAR struct nxbe_clipops_s *cops,
* origin - The origin of the upper, left-most corner of the full bitmap.
* Both dest and origin are in window coordinates, however, origin
* may lie outside of the display.
* stride - The width of the full source image in pixels.
* stride - The width of the full source image in bytes.
*
* Returned Value:
* OK on success; ERROR on failure with errno set appropriately
*
****************************************************************************/
void nxbe_bitmap(FAR struct nxbe_window_s *wnd, FAR const struct nxgl_rect_s *dest,
FAR const void *src[CONFIG_NX_NPLANES],
FAR const struct nxgl_point_s *origin, unsigned int stride)
#ifdef CONFIG_NX_RAMBACKED
static inline void nxbe_bitmap_pwfb(FAR struct nxbe_window_s *wnd,
FAR const struct nxgl_rect_s *dest,
FAR const void *src[CONFIG_NX_NPLANES],
FAR const struct nxgl_point_s *origin,
unsigned int stride)
{
struct nx_bitmap_s info;
struct nxgl_rect_s bounds;
struct nxgl_point_s offset;
struct nxgl_rect_s remaining;
unsigned int deststride;
int i;
#ifdef CONFIG_DEBUG_FEATURES
if (!wnd || !dest || !src || !origin)
{
return;
}
#endif
DEBUGASSERT(wnd != NULL && dest != NULL && src != NULL && origin != NULL);
DEBUGASSERT(wnd->be != NULL && wnd->be->plane != NULL);
/* Verify that the destination rectangle begins "below" and to the "right"
* of the origin
@@ -147,7 +141,96 @@ void nxbe_bitmap(FAR struct nxbe_window_s *wnd, FAR const struct nxgl_rect_s *de
* width of the source bitmap data (taking into account the bitmap origin)
*/
deststride = (((dest->pt2.x - origin->x + 1) * wnd->be->plane[0].pinfo.bpp + 7) >> 3);
deststride = (((dest->pt2.x - origin->x + 1) *
wnd->be->plane[0].pinfo.bpp + 7) >> 3);
if (deststride > stride)
{
gerr("ERROR: Bad dest width\n");
return;
}
/* Offset the rectangle and image origin by the window origin */
nxgl_rectoffset(&bounds, dest, wnd->bounds.pt1.x, wnd->bounds.pt1.y);
nxgl_vectoradd(&offset, origin, &wnd->bounds.pt1);
/* Clip to the limits of the window and of the background screen */
nxgl_rectintersect(&remaining, &bounds, &wnd->bounds);
nxgl_rectintersect(&remaining, &remaining, &wnd->be->bkgd.bounds);
if (!nxgl_nullrect(&remaining))
{
/* Copy the rectangular region to the framebuffer (no clipping).
* REVISIT: Assumes a single color plane.
*/
DEBUGASSERT(wnd->be->plane[0].pwfb.copyrectangle != NULL);
wnd->be->plane[0].pwfb.copyrectangle(wnd, &remaining, src[0],
&offset, stride);
}
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: nxbe_bitmap_dev
*
* Description:
* Copy a rectangular region of a larger image into the rectangle in the
* specified window. The graphics output is written to the graphics
* device unconditionally.
*
* Input Parameters:
* wnd - The window that will receive the bitmap image
* dest - Describes the rectangular on the display that will receive the
* the bit map.
* 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
* may lie outside of the display.
* stride - The width of the full source image in bytes.
*
* Returned Value:
* OK on success; ERROR on failure with errno set appropriately
*
****************************************************************************/
void nxbe_bitmap_dev(FAR struct nxbe_window_s *wnd,
FAR const struct nxgl_rect_s *dest,
FAR const void *src[CONFIG_NX_NPLANES],
FAR const struct nxgl_point_s *origin,
unsigned int stride)
{
struct nx_bitmap_s info;
struct nxgl_rect_s bounds;
struct nxgl_point_s offset;
struct nxgl_rect_s remaining;
unsigned int deststride;
int i;
DEBUGASSERT(wnd != NULL && dest != NULL && src != NULL && origin != NULL);
DEBUGASSERT(wnd->be != NULL && wnd->be->plane != NULL);
/* Verify that the destination rectangle begins "below" and to the "right"
* of the origin
*/
if (dest->pt1.x < origin->x || dest->pt1.y < origin->y)
{
gerr("ERROR: Bad dest start position\n");
return;
}
/* Verify that the width of the destination rectangle does not exceed the
* width of the source bitmap data (taking into account the bitmap origin)
*/
deststride = (((dest->pt2.x - origin->x + 1) *
wnd->be->plane[0].pinfo.bpp + 7) >> 3);
if (deststride > stride)
{
gerr("ERROR: Bad dest width\n");
@@ -177,7 +260,9 @@ void nxbe_bitmap(FAR struct nxbe_window_s *wnd, FAR const struct nxgl_rect_s *de
i = 0;
#endif
{
info.cops.visible = nxs_clipcopy;
DEBUGASSERT(wnd->be->plane[i].dev.copyrectangle != NULL);
info.cops.visible = bitmap_clipcopy;
info.cops.obscured = nxbe_clipnull;
info.src = src[i];
info.origin.x = offset.x;
@@ -188,3 +273,50 @@ void nxbe_bitmap(FAR struct nxbe_window_s *wnd, FAR const struct nxgl_rect_s *de
&info.cops, &wnd->be->plane[i]);
}
}
/****************************************************************************
* Name: nxbe_bitmap
*
* Description:
* Copy a rectangular region of a larger image into the rectangle in the
* specified window. This is a front end to nxbe_bitmap_dev() that is
* used only if CONFIG_NX_RAMBACKED=y. If the per-window frame buffer is
* selected, then the bit map will be written to both the graphics device
* and shadowed in the per-window framebuffer.
*
* Input Parameters:
* wnd - The window that will receive the bitmap image
* dest - Describes the rectangular on the display that will receive the
* the bit map.
* 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
* may lie outside of the display.
* stride - The width of the full source image in bytes.
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_NX_RAMBACKED
void nxbe_bitmap(FAR struct nxbe_window_s *wnd,
FAR const struct nxgl_rect_s *dest,
FAR const void *src[CONFIG_NX_NPLANES],
FAR const struct nxgl_point_s *origin,
unsigned int stride)
{
/* If this window supports a pre-window frame buffer then shadow the full,
* unclipped bitmap in that framebuffer.
*/
if (NXBE_ISRAMBACKED(wnd))
{
nxbe_bitmap_pwfb(wnd, dest, src, origin, stride);
}
/* Rend the bitmap directly to the graphics device in any case */
nxbe_bitmap_dev(wnd, dest, src, origin, stride);
}
#endif
+78 -78
View File
@@ -142,12 +142,12 @@ int nxbe_configure(FAR NX_DRIVERTYPE *dev, FAR struct nxbe_state_s *be)
be->plane[i].dev.copyrectangle = nxgl_copyrectangle_1bpp;
#ifdef CONFIG_NX_RAMBACKED
be->plane[i].pwfb.setpixel = nxgl_setpixel_1bpp;
be->plane[i].pwfb.fillrectangle = nxgl_fillrectangle_1bpp;
be->plane[i].pwfb.getrectangle = nxgl_getrectangle_1bpp;
be->plane[i].pwfb.filltrapezoid = nxgl_filltrapezoid_1bpp;
be->plane[i].pwfb.moverectangle = nxgl_moverectangle_1bpp;
be->plane[i].pwfb.copyrectangle = nxgl_copyrectangle_1bpp;
be->plane[i].pwfb.setpixel = pwfb_setpixel_1bpp;
be->plane[i].pwfb.fillrectangle = pwfb_fillrectangle_1bpp;
be->plane[i].pwfb.getrectangle = pwfb_getrectangle_1bpp;
be->plane[i].pwfb.filltrapezoid = pwfb_filltrapezoid_1bpp;
be->plane[i].pwfb.moverectangle = pwfb_moverectangle_1bpp;
be->plane[i].pwfb.copyrectangle = pwfb_copyrectangle_1bpp;
#endif
}
else
@@ -155,20 +155,20 @@ int nxbe_configure(FAR NX_DRIVERTYPE *dev, FAR struct nxbe_state_s *be)
#ifndef CONFIG_NX_DISABLE_2BPP
if (be->plane[i].pinfo.bpp == 2)
{
be->plane[i].dev.setpixel = nxgl_setpixel_2bpp;
be->plane[i].dev.fillrectangle = nxgl_fillrectangle_2bpp;
be->plane[i].dev.getrectangle = nxgl_getrectangle_2bpp;
be->plane[i].dev.filltrapezoid = nxgl_filltrapezoid_2bpp;
be->plane[i].dev.moverectangle = nxgl_moverectangle_2bpp;
be->plane[i].dev.copyrectangle = nxgl_copyrectangle_2bpp;
be->plane[i].dev.setpixel = nxgl_setpixel_2bpp;
be->plane[i].dev.fillrectangle = nxgl_fillrectangle_2bpp;
be->plane[i].dev.getrectangle = nxgl_getrectangle_2bpp;
be->plane[i].dev.filltrapezoid = nxgl_filltrapezoid_2bpp;
be->plane[i].dev.moverectangle = nxgl_moverectangle_2bpp;
be->plane[i].dev.copyrectangle = nxgl_copyrectangle_2bpp;
#ifdef CONFIG_NX_RAMBACKED
be->plane[i].pwfb.setpixel = nxgl_setpixel_2bpp;
be->plane[i].pwfb.fillrectangle = nxgl_fillrectangle_2bpp;
be->plane[i].pwfb.getrectangle = nxgl_getrectangle_2bpp;
be->plane[i].pwfb.filltrapezoid = nxgl_filltrapezoid_2bpp;
be->plane[i].pwfb.moverectangle = nxgl_moverectangle_2bpp;
be->plane[i].pwfb.copyrectangle = nxgl_copyrectangle_2bpp;
be->plane[i].pwfb.setpixel = pwfb_setpixel_2bpp;
be->plane[i].pwfb.fillrectangle = pwfb_fillrectangle_2bpp;
be->plane[i].pwfb.getrectangle = pwfb_getrectangle_2bpp;
be->plane[i].pwfb.filltrapezoid = pwfb_filltrapezoid_2bpp;
be->plane[i].pwfb.moverectangle = pwfb_moverectangle_2bpp;
be->plane[i].pwfb.copyrectangle = pwfb_copyrectangle_2bpp;
#endif
}
else
@@ -176,20 +176,20 @@ int nxbe_configure(FAR NX_DRIVERTYPE *dev, FAR struct nxbe_state_s *be)
#ifndef CONFIG_NX_DISABLE_4BPP
if (be->plane[i].pinfo.bpp == 4)
{
be->plane[i].dev.setpixel = nxgl_setpixel_4bpp;
be->plane[i].dev.fillrectangle = nxgl_fillrectangle_4bpp;
be->plane[i].dev.getrectangle = nxgl_getrectangle_4bpp;
be->plane[i].dev.filltrapezoid = nxgl_filltrapezoid_4bpp;
be->plane[i].dev.moverectangle = nxgl_moverectangle_4bpp;
be->plane[i].dev.copyrectangle = nxgl_copyrectangle_4bpp;
be->plane[i].dev.setpixel = nxgl_setpixel_4bpp;
be->plane[i].dev.fillrectangle = nxgl_fillrectangle_4bpp;
be->plane[i].dev.getrectangle = nxgl_getrectangle_4bpp;
be->plane[i].dev.filltrapezoid = nxgl_filltrapezoid_4bpp;
be->plane[i].dev.moverectangle = nxgl_moverectangle_4bpp;
be->plane[i].dev.copyrectangle = nxgl_copyrectangle_4bpp;
#ifdef CONFIG_NX_RAMBACKED
be->plane[i].pwfb.setpixel = nxgl_setpixel_4bpp;
be->plane[i].pwfb.fillrectangle = nxgl_fillrectangle_4bpp;
be->plane[i].pwfb.getrectangle = nxgl_getrectangle_4bpp;
be->plane[i].pwfb.filltrapezoid = nxgl_filltrapezoid_4bpp;
be->plane[i].pwfb.moverectangle = nxgl_moverectangle_4bpp;
be->plane[i].pwfb.copyrectangle = nxgl_copyrectangle_4bpp;
be->plane[i].pwfb.setpixel = pwfb_setpixel_4bpp;
be->plane[i].pwfb.fillrectangle = pwfb_fillrectangle_4bpp;
be->plane[i].pwfb.getrectangle = pwfb_getrectangle_4bpp;
be->plane[i].pwfb.filltrapezoid = pwfb_filltrapezoid_4bpp;
be->plane[i].pwfb.moverectangle = pwfb_moverectangle_4bpp;
be->plane[i].pwfb.copyrectangle = pwfb_copyrectangle_4bpp;
#endif
}
else
@@ -197,20 +197,20 @@ int nxbe_configure(FAR NX_DRIVERTYPE *dev, FAR struct nxbe_state_s *be)
#ifndef CONFIG_NX_DISABLE_8BPP
if (be->plane[i].pinfo.bpp == 8)
{
be->plane[i].dev.setpixel = nxgl_setpixel_8bpp;
be->plane[i].dev.fillrectangle = nxgl_fillrectangle_8bpp;
be->plane[i].dev.getrectangle = nxgl_getrectangle_8bpp;
be->plane[i].dev.filltrapezoid = nxgl_filltrapezoid_8bpp;
be->plane[i].dev.moverectangle = nxgl_moverectangle_8bpp;
be->plane[i].dev.copyrectangle = nxgl_copyrectangle_8bpp;
be->plane[i].dev.setpixel = nxgl_setpixel_8bpp;
be->plane[i].dev.fillrectangle = nxgl_fillrectangle_8bpp;
be->plane[i].dev.getrectangle = nxgl_getrectangle_8bpp;
be->plane[i].dev.filltrapezoid = nxgl_filltrapezoid_8bpp;
be->plane[i].dev.moverectangle = nxgl_moverectangle_8bpp;
be->plane[i].dev.copyrectangle = nxgl_copyrectangle_8bpp;
#ifdef CONFIG_NX_RAMBACKED
be->plane[i].pwfb.setpixel = nxgl_setpixel_8bpp;
be->plane[i].pwfb.fillrectangle = nxgl_fillrectangle_8bpp;
be->plane[i].pwfb.getrectangle = nxgl_getrectangle_8bpp;
be->plane[i].pwfb.filltrapezoid = nxgl_filltrapezoid_8bpp;
be->plane[i].pwfb.moverectangle = nxgl_moverectangle_8bpp;
be->plane[i].pwfb.copyrectangle = nxgl_copyrectangle_8bpp;
be->plane[i].pwfb.setpixel = pwfb_setpixel_8bpp;
be->plane[i].pwfb.fillrectangle = pwfb_fillrectangle_8bpp;
be->plane[i].pwfb.getrectangle = pwfb_getrectangle_8bpp;
be->plane[i].pwfb.filltrapezoid = pwfb_filltrapezoid_8bpp;
be->plane[i].pwfb.moverectangle = pwfb_moverectangle_8bpp;
be->plane[i].pwfb.copyrectangle = pwfb_copyrectangle_8bpp;
#endif
}
else
@@ -218,20 +218,20 @@ int nxbe_configure(FAR NX_DRIVERTYPE *dev, FAR struct nxbe_state_s *be)
#ifndef CONFIG_NX_DISABLE_16BPP
if (be->plane[i].pinfo.bpp == 16)
{
be->plane[i].dev.setpixel = nxgl_setpixel_16bpp;
be->plane[i].dev.fillrectangle = nxgl_fillrectangle_16bpp;
be->plane[i].dev.getrectangle = nxgl_getrectangle_16bpp;
be->plane[i].dev.filltrapezoid = nxgl_filltrapezoid_16bpp;
be->plane[i].dev.moverectangle = nxgl_moverectangle_16bpp;
be->plane[i].dev.copyrectangle = nxgl_copyrectangle_16bpp;
be->plane[i].dev.setpixel = nxgl_setpixel_16bpp;
be->plane[i].dev.fillrectangle = nxgl_fillrectangle_16bpp;
be->plane[i].dev.getrectangle = nxgl_getrectangle_16bpp;
be->plane[i].dev.filltrapezoid = nxgl_filltrapezoid_16bpp;
be->plane[i].dev.moverectangle = nxgl_moverectangle_16bpp;
be->plane[i].dev.copyrectangle = nxgl_copyrectangle_16bpp;
#ifdef CONFIG_NX_RAMBACKED
be->plane[i].pwfb.setpixel = nxgl_setpixel_16bpp;
be->plane[i].pwfb.fillrectangle = nxgl_fillrectangle_16bpp;
be->plane[i].pwfb.getrectangle = nxgl_getrectangle_16bpp;
be->plane[i].pwfb.filltrapezoid = nxgl_filltrapezoid_16bpp;
be->plane[i].pwfb.moverectangle = nxgl_moverectangle_16bpp;
be->plane[i].pwfb.copyrectangle = nxgl_copyrectangle_16bpp;
be->plane[i].pwfb.setpixel = pwfb_setpixel_16bpp;
be->plane[i].pwfb.fillrectangle = pwfb_fillrectangle_16bpp;
be->plane[i].pwfb.getrectangle = pwfb_getrectangle_16bpp;
be->plane[i].pwfb.filltrapezoid = pwfb_filltrapezoid_16bpp;
be->plane[i].pwfb.moverectangle = pwfb_moverectangle_16bpp;
be->plane[i].pwfb.copyrectangle = pwfb_copyrectangle_16bpp;
#endif
}
else
@@ -239,20 +239,20 @@ int nxbe_configure(FAR NX_DRIVERTYPE *dev, FAR struct nxbe_state_s *be)
#ifndef CONFIG_NX_DISABLE_24BPP
if (be->plane[i].pinfo.bpp == 24)
{
be->plane[i].dev.setpixel = nxgl_setpixel_24bpp;
be->plane[i].dev.fillrectangle = nxgl_fillrectangle_24bpp;
be->plane[i].dev.getrectangle = nxgl_getrectangle_24bpp;
be->plane[i].dev.filltrapezoid = nxgl_filltrapezoid_24bpp;
be->plane[i].dev.moverectangle = nxgl_moverectangle_24bpp;
be->plane[i].dev.copyrectangle = nxgl_copyrectangle_24bpp;
be->plane[i].dev.setpixel = nxgl_setpixel_24bpp;
be->plane[i].dev.fillrectangle = nxgl_fillrectangle_24bpp;
be->plane[i].dev.getrectangle = nxgl_getrectangle_24bpp;
be->plane[i].dev.filltrapezoid = nxgl_filltrapezoid_24bpp;
be->plane[i].dev.moverectangle = nxgl_moverectangle_24bpp;
be->plane[i].dev.copyrectangle = nxgl_copyrectangle_24bpp;
#ifdef CONFIG_NX_RAMBACKED
be->plane[i].pwfb.setpixel = nxgl_setpixel_24bpp;
be->plane[i].pwfb.fillrectangle = nxgl_fillrectangle_24bpp;
be->plane[i].pwfb.getrectangle = nxgl_getrectangle_24bpp;
be->plane[i].pwfb.filltrapezoid = nxgl_filltrapezoid_24bpp;
be->plane[i].pwfb.moverectangle = nxgl_moverectangle_24bpp;
be->plane[i].pwfb.copyrectangle = nxgl_copyrectangle_24bpp;
be->plane[i].pwfb.setpixel = pwfb_setpixel_24bpp;
be->plane[i].pwfb.fillrectangle = pwfb_fillrectangle_24bpp;
be->plane[i].pwfb.getrectangle = pwfb_getrectangle_24bpp;
be->plane[i].pwfb.filltrapezoid = pwfb_filltrapezoid_24bpp;
be->plane[i].pwfb.moverectangle = pwfb_moverectangle_24bpp;
be->plane[i].pwfb.copyrectangle = pwfb_copyrectangle_24bpp;
#endif
}
else
@@ -260,20 +260,20 @@ int nxbe_configure(FAR NX_DRIVERTYPE *dev, FAR struct nxbe_state_s *be)
#ifndef CONFIG_NX_DISABLE_32BPP
if (be->plane[i].pinfo.bpp == 32)
{
be->plane[i].dev.setpixel = nxgl_setpixel_32bpp;
be->plane[i].dev.fillrectangle = nxgl_fillrectangle_32bpp;
be->plane[i].dev.getrectangle = nxgl_getrectangle_32bpp;
be->plane[i].dev.filltrapezoid = nxgl_filltrapezoid_32bpp;
be->plane[i].dev.moverectangle = nxgl_moverectangle_32bpp;
be->plane[i].dev.copyrectangle = nxgl_copyrectangle_32bpp;
be->plane[i].dev.setpixel = nxgl_setpixel_32bpp;
be->plane[i].dev.fillrectangle = nxgl_fillrectangle_32bpp;
be->plane[i].dev.getrectangle = nxgl_getrectangle_32bpp;
be->plane[i].dev.filltrapezoid = nxgl_filltrapezoid_32bpp;
be->plane[i].dev.moverectangle = nxgl_moverectangle_32bpp;
be->plane[i].dev.copyrectangle = nxgl_copyrectangle_32bpp;
#ifdef CONFIG_NX_RAMBACKED
be->plane[i].pwfb.setpixel = nxgl_setpixel_1bpp;
be->plane[i].pwfb.fillrectangle = nxgl_fillrectangle_32bpp;
be->plane[i].pwfb.getrectangle = nxgl_getrectangle_32bpp;
be->plane[i].pwfb.filltrapezoid = nxgl_filltrapezoid_32bpp;
be->plane[i].pwfb.moverectangle = nxgl_moverectangle_32bpp;
be->plane[i].pwfb.copyrectangle = nxgl_copyrectangle_32bpp;
be->plane[i].pwfb.setpixel = pwfb_setpixel_1bpp;
be->plane[i].pwfb.fillrectangle = pwfb_fillrectangle_32bpp;
be->plane[i].pwfb.getrectangle = pwfb_getrectangle_32bpp;
be->plane[i].pwfb.filltrapezoid = pwfb_filltrapezoid_32bpp;
be->plane[i].pwfb.moverectangle = pwfb_moverectangle_32bpp;
be->plane[i].pwfb.copyrectangle = pwfb_copyrectangle_32bpp;
#endif
}
else
+90 -25
View File
@@ -40,6 +40,8 @@
#include <nuttx/config.h>
#include <assert.h>
#include <nuttx/nx/nxglib.h>
#include <nuttx/nx/nx.h>
@@ -63,8 +65,8 @@ struct nxbe_fill_s
* Name: nxbe_clipfill
*
* Description:
* Called from nxbe_clipper() to performed the fill operation on visible portions
* of the rectangle.
* Called from nxbe_clipper() to performed the fill operation on visible
* portions of the rectangle.
*
****************************************************************************/
@@ -85,6 +87,78 @@ static void nxbe_clipfill(FAR struct nxbe_clipops_s *cops,
#endif
}
/****************************************************************************
* Name: nxbe_fill_dev
*
* Description:
* Fill the specified rectangle in the window in device memory with the
* specified color, performing clipping as needed.
*
* Input Parameters:
* wnd - The window structure reference
* rect - The location to be filled
* col - The color to use in the fill
*
* Returned Value:
* None
*
****************************************************************************/
static inline void nxbe_fill_dev(FAR struct nxbe_window_s *wnd,
FAR const struct nxgl_rect_s *rect,
nxgl_mxpixel_t color[CONFIG_NX_NPLANES])
{
struct nxbe_fill_s info;
int i;
#if CONFIG_NX_NPLANES > 1
for (i = 0; i < wnd->be->vinfo.nplanes; i++)
#else
i = 0;
#endif
{
DEBUGASSERT(wnd->be->plane[i].dev.fillrectangle != NULL);
info.cops.visible = nxbe_clipfill;
info.cops.obscured = nxbe_clipnull;
info.color = color[i];
nxbe_clipper(wnd->above, rect, NX_CLIPORDER_DEFAULT,
&info.cops, &wnd->be->plane[i]);
}
}
/****************************************************************************
* Name: nxbe_fill_pwfb
*
* Description:
* Fill the specified rectangle in the per-window frame buffer with no
* clipping.
*
* Input Parameters:
* wnd - The window structure reference
* rect - The location to be filled
* col - The color to use in the fill
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_NX_RAMBACKED
static inline void nxbe_fill_pwfb(FAR struct nxbe_window_s *wnd,
FAR const struct nxgl_rect_s *rect,
nxgl_mxpixel_t color[CONFIG_NX_NPLANES])
{
/* Copy the rectangular region to the framebuffer (no clipping).
* REVISIT: Assumes a single color plane.
*/
DEBUGASSERT(wnd->be->plane[0].pwfb.fillrectangle != NULL);
wnd->be->plane[0].pwfb.fillrectangle(wnd, rect, color[0]);
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -109,16 +183,10 @@ void nxbe_fill(FAR struct nxbe_window_s *wnd,
FAR const struct nxgl_rect_s *rect,
nxgl_mxpixel_t color[CONFIG_NX_NPLANES])
{
struct nxbe_fill_s info;
struct nxgl_rect_s remaining;
int i;
#ifdef CONFIG_DEBUG_FEATURES
if (!wnd || !rect)
{
return;
}
#endif
DEBUGASSERT(wnd != NULL && rect != NULL && color != NULL);
DEBUGASSERT(wnd->be != NULL && wnd->be->plane != NULL);
/* Offset the rectangle by the window origin to convert it into a
* bounding box
@@ -133,24 +201,21 @@ void nxbe_fill(FAR struct nxbe_window_s *wnd,
nxgl_rectintersect(&remaining, &remaining, &wnd->bounds);
nxgl_rectintersect(&remaining, &remaining, &wnd->be->bkgd.bounds);
/* Then clip the bounding box due to other windows above this one.
* Render the portions of the trapezoid exposed in visible regions.
*/
if (!nxgl_nullrect(&remaining))
{
#if CONFIG_NX_NPLANES > 1
for (i = 0; i < wnd->be->vinfo.nplanes; i++)
#else
i = 0;
#endif
{
info.cops.visible = nxbe_clipfill;
info.cops.obscured = nxbe_clipnull;
info.color = color[i];
#ifdef CONFIG_NX_RAMBACKED
/* If this window supports a pre-window frame buffer then shadow the
* full, unclipped bitmap in that framebuffer.
*/
nxbe_clipper(wnd->above, &remaining, NX_CLIPORDER_DEFAULT,
&info.cops, &wnd->be->plane[i]);
if (NXBE_ISRAMBACKED(wnd))
{
nxbe_fill_pwfb(wnd, &remaining, color);
}
#endif
/* Rend the bitmap directly to the graphics device in any case */
nxbe_fill_dev(wnd, rect, color);
}
}
+122 -25
View File
@@ -40,7 +40,9 @@
#include <nuttx/config.h>
#include <assert.h>
#include <fixedmath.h>
#include <nuttx/nx/nxglib.h>
#include "nxbe.h"
@@ -109,6 +111,108 @@ static void nxbe_clipfilltrapezoid(FAR struct nxbe_clipops_s *cops,
#endif
}
/****************************************************************************
* Name: nxbe_filltrapezoid_dev
*
* Description:
* Fill the specified rectangle in the device graphics memory with the
* specified color
*
* Input Parameters:
* wnd - The window structure reference
* bounds - Trapezoid bounding box (in absolute window coordinates)
* rect - The location to be filled (in relative window coordinates)
* col - The color to use in the fill
*
* Returned Value:
* None
*
****************************************************************************/
static inline void nxbe_filltrapezoid_dev(FAR struct nxbe_window_s *wnd,
FAR const struct nxgl_rect_s *bounds,
FAR const struct nxgl_trapezoid_s *trap,
nxgl_mxpixel_t color[CONFIG_NX_NPLANES])
{
struct nxbe_filltrap_s info;
int i;
info.cops.visible = nxbe_clipfilltrapezoid;
info.cops.obscured = nxbe_clipnull;
nxgl_trapcopy(&info.trap, trap);
/* Process each color plane */
#if CONFIG_NX_NPLANES > 1
for (i = 0; i < wnd->be->vinfo.nplanes; i++)
#else
i = 0;
#endif
{
info.color = color[i];
nxbe_clipper(wnd->above, bounds, NX_CLIPORDER_DEFAULT,
&info.cops, &wnd->be->plane[i]);
}
}
/****************************************************************************
* Name: nxbe_filltrapezoid_pwfb
*
* Description:
* Fill the specified rectangle in the window with the specified color
*
* Input Parameters:
* wnd - The window structure reference
* bounds - Trapezoid bounding box (in absolute window coordinates)
* rect - The location to be filled (in relative window coordinates)
* col - The color to use in the fill
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_NX_RAMBACKED
static inline void nxbe_filltrapezoid_pwfb(FAR struct nxbe_window_s *wnd,
FAR const struct nxgl_rect_s *bounds,
FAR const struct nxgl_trapezoid_s *trap,
nxgl_mxpixel_t color[CONFIG_NX_NPLANES])
{
struct nxgl_rect_s newbounds;
FAR const void *src[CONFIG_NX_NPLANES] =
{
(FAR const void *)wnd->fbmem
};
struct nxgl_point_s origin =
{
0, 0
};
/* Copy the trapezoidal region to the framebuffer (no clipping).
* REVISIT: Assumes a single color plane.
*/
DEBUGASSERT(wnd->be->plane[0].pwfb.filltrapezoid != NULL);
wnd->be->plane[0].pwfb.filltrapezoid(wnd, trap, bounds, color[0]);
/* Copy the porition of the per-window framebuffer to the device graphics
* memory.
*/
/* Restore the rectangle origin to (0,0) as required by nxbe_bitmap_dev().
* nxbe_bitmap_dev() will offset the bounds yet again.
*/
nxgl_rectoffset(&newbounds, bounds,
-wnd->bounds.pt1.x, -wnd->bounds.pt1.y);
/* Then perform the bitmap copy from the pre-window framebuffer */
nxbe_bitmap_dev(wnd, &newbounds, src, &origin, wnd->stride);
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -135,33 +239,27 @@ void nxbe_filltrapezoid(FAR struct nxbe_window_s *wnd,
FAR const struct nxgl_trapezoid_s *trap,
nxgl_mxpixel_t color[CONFIG_NX_NPLANES])
{
struct nxbe_filltrap_s info;
struct nxgl_rect_s remaining;
int i;
struct nxgl_trapezoid_s offset_trap;
#ifdef CONFIG_DEBUG_FEATURES
if (!wnd || !trap)
{
return;
}
#endif
DEBUGASSERT(wnd != NULL && trap != NULL);
/* Offset the trapezoid by the window origin to position it within
* the framebuffer region
*/
nxgl_trapoffset(&info.trap, trap, wnd->bounds.pt1.x, wnd->bounds.pt1.y);
nxgl_trapoffset(&offset_trap, trap, wnd->bounds.pt1.x, wnd->bounds.pt1.y);
/* Create a bounding box that contains the trapezoid */
remaining.pt1.x = b16toi(ngl_min(info.trap.top.x1, info.trap.bot.x1));
remaining.pt1.y = info.trap.top.y;
remaining.pt2.x = b16toi(ngl_max(info.trap.top.x2, info.trap.bot.x2));
remaining.pt2.y = info.trap.bot.y;
remaining.pt1.x = b16toi(ngl_min(offset_trap.top.x1, offset_trap.bot.x1));
remaining.pt1.y = offset_trap.top.y;
remaining.pt2.x = b16toi(ngl_max(offset_trap.top.x2, offset_trap.bot.x2));
remaining.pt2.y = offset_trap.bot.y;
/* Clip to any user specified clipping window */
if (clip)
if (clip != NULL)
{
struct nxgl_rect_s tmp;
nxgl_rectoffset(&tmp, clip, wnd->bounds.pt1.x, wnd->bounds.pt1.y);
@@ -175,20 +273,19 @@ void nxbe_filltrapezoid(FAR struct nxbe_window_s *wnd,
if (!nxgl_nullrect(&remaining))
{
info.cops.visible = nxbe_clipfilltrapezoid;
info.cops.obscured = nxbe_clipnull;
#ifdef CONFIG_NX_RAMBACKED
/* Update the pre-window framebuffer first, then the device memory. */
/* Then process each color plane */
#if CONFIG_NX_NPLANES > 1
for (i = 0; i < wnd->be->vinfo.nplanes; i++)
#else
i = 0;
if (NXBE_ISRAMBACKED(wnd))
{
nxbe_filltrapezoid_pwfb(wnd, &remaining, &offset_trap, color);
}
else
#endif
{
info.color = color[i];
nxbe_clipper(wnd->above, &remaining, NX_CLIPORDER_DEFAULT,
&info.cops, &wnd->be->plane[i]);
/* Update only the graphics device memory. */
nxbe_filltrapezoid_dev(wnd, &remaining, &offset_trap, color);
}
}
}
+94 -15
View File
@@ -39,6 +39,7 @@
#include <nuttx/config.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
@@ -56,6 +57,76 @@ struct nxbe_fill_s
nxgl_mxpixel_t color;
};
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: nxbe_getrectangle_dev
*
* Description:
* Get the raw contents of graphic memory within a rectangular region. NOTE:
* Since raw graphic memory is returned, the returned memory content may be
* the memory of windows above this one and may not necessarily belong to
* this window unless you assure that this is the top window.
*
* Input Parameters:
* wnd - The window structure reference
* rect - The location to be copied
* plane - Specifies the color plane to get from.
* dest - The location to copy the memory region
* deststride - The width, in bytes, of the dest memory
*
* Returned Value:
* None
*
****************************************************************************/
static inline void nxbe_getrectangle_dev(FAR struct nxbe_window_s *wnd,
FAR const struct nxgl_rect_s *rect,
unsigned int plane,
FAR uint8_t *dest,
unsigned int deststride)
{
FAR struct nxbe_plane_s *pplane = &wnd->be->plane[plane];
DEBUGASSERT(pplane != NULL && pplane->dev.getrectangle != NULL);
pplane->dev.getrectangle(&pplane->pinfo, rect, dest, deststride);
}
/****************************************************************************
* Name: nxbe_getrectangle_pwfb
*
* Description:
* Get the contents of pre-window framebuffer graphic memory within a
* rectangular region.
*
* Input Parameters:
* wnd - The window structure reference
* rect - The location to be copied
* plane - Specifies the color plane to get from.
* dest - The location to copy the memory region
* deststride - The width, in bytes, of the dest memory
*
* Returned Value:
* None
*
****************************************************************************/
static inline void nxbe_getrectangle_pwfb(FAR struct nxbe_window_s *wnd,
FAR const struct nxgl_rect_s *rect,
unsigned int plane,
FAR uint8_t *dest,
unsigned int deststride)
{
FAR struct nxbe_plane_s *pplane = &wnd->be->plane[plane];
DEBUGASSERT(pplane != NULL && pplane->pwfb.getrectangle != NULL);
pplane->pwfb.getrectangle(wnd, rect, dest, deststride);
}
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -87,13 +158,9 @@ void nxbe_getrectangle(FAR struct nxbe_window_s *wnd,
{
struct nxgl_rect_s remaining;
#ifdef CONFIG_DEBUG_FEATURES
if (!wnd || !rect || !dest || plane >= wnd->be->vinfo.nplanes)
{
ginfo("Invalid parameters\n");
return;
}
#endif
DEBUGASSERT(wnd != NULL && rect != NULL && dest != NULL);
DEBUGASSERT(wnd->be != NULL && wnd->be->plane != NULL);
DEBUGASSERT(plane < wnd->be->vinfo.nplanes);
/* Offset the rectangle by the window origin to convert it into a
* bounding box
@@ -108,17 +175,29 @@ void nxbe_getrectangle(FAR struct nxbe_window_s *wnd,
nxgl_rectintersect(&remaining, &remaining, &wnd->bounds);
nxgl_rectintersect(&remaining, &remaining, &wnd->be->bkgd.bounds);
/* The return the graphics memory at this location. NOTE: Since raw
* graphic memory is returned, the returned memory content may be
* the memory of windows above this one and may not necessarily belong
* to this window.
*/
/* The return the graphics memory at this location. */
if (!nxgl_nullrect(&remaining))
{
FAR struct nxbe_plane_s *pplane = &wnd->be->plane[plane];
#ifdef CONFIG_NX_RAMBACKED
/* If this window supports a pre-window frame buffer then get the
* rectangle from pre-window framebuffer.
*/
pplane->dev.getrectangle(&pplane->pinfo, &remaining, dest,
deststride);
if (NXBE_ISRAMBACKED(wnd))
{
nxbe_getrectangle_pwfb(wnd, rect, plane, dest, deststride);
}
else
#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
* not necessarily belong to this window.
*/
nxbe_getrectangle_dev(wnd, rect, plane, dest, deststride);
}
}
}
+137 -34
View File
@@ -41,6 +41,7 @@
#include <nuttx/config.h>
#include <stdint.h>
#include <assert.h>
#include <nuttx/nx/nxglib.h>
@@ -95,12 +96,16 @@ static void nxbe_clipmovesrc(FAR struct nxbe_clipops_s *cops,
plane->dev.moverectangle(&plane->pinfo, rect, &offset);
#ifdef CONFIG_NX_UPDATE
/* Notify external logic that the display has been updated */
/* Move the source rectangle back to window relative coordinates and
* apply the offset.
*/
update.pt1.x = offset.x;
update.pt1.y = offset.y;
update.pt2.x = rect->pt2.x + info->offset.x;
update.pt2.y = rect->pt2.y + info->offset.y;
nxgl_rectoffset(&update, rect, offset.x - wnd->bounds.pt1.x,
offset.y - wnd->bounds.pt1.y);
/* Notify any listeners that the graphic content in the update
* rectangle has changed.
*/
nx_notify_rectangle(&plane->pinfo, &update);
#endif
@@ -184,18 +189,14 @@ static void nxbe_clipmovedest(FAR struct nxbe_clipops_s *cops,
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: nxbe_move
* Name: nxbe_move_dev
*
* Description:
* Move a rectangular region within the window
*
* Input Parameters:
* wnd - The window within which the move is to be done
* rect - Describes the rectangular region to move
* rect - Describes the rectangular region to move (absolute positions)
* offset - The offset to move the region
*
* Returned Value:
@@ -203,39 +204,21 @@ static void nxbe_clipmovedest(FAR struct nxbe_clipops_s *cops,
*
****************************************************************************/
void nxbe_move(FAR struct nxbe_window_s *wnd, FAR const struct nxgl_rect_s *rect,
FAR const struct nxgl_point_s *offset)
static inline void nxbe_move_dev(FAR struct nxbe_window_s *wnd,
FAR const struct nxgl_rect_s *rect,
FAR const struct nxgl_point_s *offset)
{
struct nxbe_move_s info;
int i;
#ifdef CONFIG_DEBUG_FEATURES
if (!wnd || !rect)
{
return;
}
#endif
/* Offset the rectangle by the window origin to create a bounding box */
nxgl_rectoffset(&info.srcrect, rect, wnd->bounds.pt1.x, wnd->bounds.pt1.y);
/* Clip to the limits of the window and of the background screen */
nxgl_rectintersect(&info.srcrect, &info.srcrect, &wnd->bounds);
nxgl_rectintersect(&info.srcrect, &info.srcrect, &wnd->be->bkgd.bounds);
if (nxgl_nullrect(&info.srcrect))
{
return;
}
info.cops.visible = nxbe_clipmovedest;
info.cops.obscured = nxbe_clipnull;
info.offset.x = offset->x;
info.offset.y = offset->y;
info.wnd = wnd;
nxgl_rectcopy(&info.srcrect, rect);
/* The clip order depends up the direction that the rectangle is being
* moved.
*/
@@ -287,3 +270,123 @@ void nxbe_move(FAR struct nxbe_window_s *wnd, FAR const struct nxgl_rect_s *rect
&info.cops, &wnd->be->plane[i]);
}
}
/****************************************************************************
* Name: nxbe_move_pwfb
*
* Description:
* Move a rectangular region within the window
*
* Input Parameters:
* wnd - The window within which the move is to be done
* rect - Describes the rectangular region to move (absolute positions)
* offset - The offset to move the region
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_NX_RAMBACKED
static inline void nxbe_move_pwfb(FAR struct nxbe_window_s *wnd,
FAR const struct nxgl_rect_s *rect,
FAR const struct nxgl_point_s *offset)
{
struct nxgl_point_s destpos;
struct nxgl_rect_s bounds;
FAR const void *src[CONFIG_NX_NPLANES] =
{
(FAR const void *)wnd->fbmem
};
FAR const struct nxgl_point_s origin =
{
0, 0
};
/* Offset is the destination position of the moved rectangle */
destpos.x = rect->pt1.x + offset->x;
destpos.y = rect->pt1.y + offset->y;
/* Move the source rectangle to the destination position in the
* frambebuffer.
* REVISIT: Assumes a single color plane.
*/
DEBUGASSERT(wnd->be->plane[0].pwfb.moverectangle != NULL);
wnd->be->plane[0].pwfb.moverectangle(wnd, rect, &destpos);
/* Construct the destination bounding box in relative window
* coordinates. This derives from the source bounding box with
* an offset distination and an offset to restore the relative
* window position.
*/
nxgl_rectoffset(&bounds, rect, offset->x - wnd->bounds.pt1.x,
offset->y - wnd->bounds.pt1.y);
/* Update the physical device by just copying the destination rectangle
* to the device graphics memory.
*/
nxbe_bitmap_dev(wnd, &bounds, src, &origin, wnd->stride);
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: nxbe_move
*
* Description:
* Move a rectangular region within the window
*
* Input Parameters:
* wnd - The window within which the move is to be done
* rect - Describes the rectangular region to move (window relative)
* offset - The offset to move the region
*
* Returned Value:
* None
*
****************************************************************************/
void nxbe_move(FAR struct nxbe_window_s *wnd,
FAR const struct nxgl_rect_s *rect,
FAR const struct nxgl_point_s *offset)
{
struct nxgl_rect_s srcrect;
DEBUGASSERT(wnd != NULL && rect != NULL && offset != 0);
if (offset->x != 0 || offset->y != 0)
{
/* Offset the rectangle by the window origin to create a bounding box */
nxgl_rectoffset(&srcrect, rect, wnd->bounds.pt1.x, wnd->bounds.pt1.y);
/* Clip to the limits of the window and of the background screen */
nxgl_rectintersect(&srcrect, &srcrect, &wnd->bounds);
nxgl_rectintersect(&srcrect, &srcrect, &wnd->be->bkgd.bounds);
if (!nxgl_nullrect(&srcrect))
{
#ifdef CONFIG_NX_RAMBACKED
/* Update the pre-window framebuffer first, then the device memory. */
if (NXBE_ISRAMBACKED(wnd))
{
nxbe_move_pwfb(wnd, &srcrect, offset);
}
else
#endif
{
/* Update only the graphics device memory. */
nxbe_move_dev(wnd, &srcrect, offset);
}
}
}
}
+174 -11
View File
@@ -1,7 +1,7 @@
/****************************************************************************
* graphics/nxbe/nxbe_setsize.c
*
* Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved.
* Copyright (C) 2008-2009, 2011, 2019 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -39,11 +39,172 @@
#include <nuttx/config.h>
#ifdef CONFIG_NX_RAMBACKED
# include <debug.h>
# include <string.h>
#ifdef CONFIG_BUILD_KERNEL
# include <nuttx/pgalloc.h>
#else
# include <nuttx/kmalloc.h>
#endif
#endif
#include <nuttx/nx/nxglib.h>
#include "nxbe.h"
#include "nxmu.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifndef MIN
# define MIN(a,b) ((a < b) ? a : b)
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: nxbe_realloc
*
* Description:
* After the display size has changed, reallocate the pre-window frame
* buffer for the new framebuffer size.
*
* REVISIT: This currently takes a brute force force approach, allocating
* the new framebuffer while the old framebuffer is still in place. There
* may be some clever way to do this reallocation in place.
*
****************************************************************************/
#ifdef CONFIG_NX_RAMBACKED
static void nxbe_realloc(FAR struct nxbe_window_s *wnd,
FAR struct nxgl_rect_s *oldbounds)
{
FAR nxgl_mxpixel_t *newfb;
FAR uint8_t *src;
FAR uint8_t *dest;
nxgl_coord_t minheight;
nxgl_coord_t newidth;
nxgl_coord_t newheight;
nxgl_coord_t oldheight;
nxgl_coord_t row;
size_t newfbsize;
unsigned int minstride;
unsigned int newstride;
unsigned int bpp;
#ifdef CONFIG_BUILD_KERNEL
unsigned int newnpages;
#endif
/* Allocate framebuffer memory if the per-window framebuffer feature has
* been selected.
*
* REVISIT: This initial state of the framebuffer is uninitialized and
* not synchronized with the graphic device content. It will take a full
* screen update from the application to force the framebuffer and device
* to be consistent.
*/
if (NXBE_ISRAMBACKED(wnd))
{
oldheight = oldbounds->pt2.y - oldbounds->pt1.y + 1;
newidth = wnd->bounds.pt2.x - wnd->bounds.pt1.x + 1;
newheight = wnd->bounds.pt2.y - wnd->bounds.pt1.y + 1;
bpp = wnd->be->plane[0].pinfo.bpp;
newstride = (bpp * newidth + 7) >> 8;
newfbsize = newstride * newheight;
#ifdef CONFIG_BUILD_KERNEL
/* Re-allocate memory from the page pool. */
/* Determine the number of pages to be allocated. */
newnpages = (uint16_t)MM_NPAGES(newfbsize);
/* Allocate the pages */
newfb = (FAR nxgl_mxpixel_t *)mm_pgalloc(newnpages);
if (newfb == NULL)
{
/* Fall back to no RAM back up */
gerr("ERROR: mm_pgalloc() failed\n");
mm_pgfree(wnd->fbmem, wnd->npages);
wnd->stride = 0;
wnd->npages = 0;
wnd->fbmem = NULL;
NXBE_CLRRAMBACKED(wnd);
return;
}
#else
/* Re-allocate memory from the user space heap. */
newfb = (FAR nxgl_mxpixel_t *)kumm_malloc(newfbsize);
if (newfb == NULL)
{
/* Fall back to no RAM back up */
gerr("ERROR: mm_pgalloc() failed\n");
kumm_free(wnd->fbmem);
wnd->stride = 0;
wnd->fbmem = NULL;
NXBE_CLRRAMBACKED(wnd);
return;
}
#endif
/* Copy the content of the old framebuffer to the new frame buffer */
minheight = MIN(oldheight, newheight);
minstride = MIN(wnd->stride, newstride);
/* Process each line one at a time */
for (src = (FAR uint8_t *)wnd->fbmem, dest = (FAR uint8_t *)newfb,
row = 0;
row < minheight;
src += wnd->stride, dest += newstride, row++)
{
/* Copy valid row data */
memcpy(src, dest, minstride);
/* Pad any extra pixel data on the right (with zeroes?) */
if (minstride < newstride)
{
memset(dest + minstride, 0, newstride - minstride);
}
}
/* Pad any extra lines at the bottom (with zeroes?) */
if (row < newheight)
{
size_t nbytes = newstride * (newheight - row);
memset(dest, 0, nbytes);
}
/* Free the old framebuffer and configure for the new framebuffer */
#ifdef CONFIG_BUILD_KERNEL
mm_pgfree(wnd->fbmem, wnd->npages);
wnd->npages = newnpages;
#else
kumm_free(wnd->fbmem);
#endif
wnd->stride = newstride;
wnd->fbmem = newfb;
}
}
#else
# define nxbe_realloc(w,b)
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -62,18 +223,15 @@ void nxbe_setsize(FAR struct nxbe_window_s *wnd,
{
struct nxgl_rect_s bounds;
#ifdef CONFIG_DEBUG_FEATURES
if (!wnd)
{
return;
}
#endif
DEBUGASSERT(wnd != NULL && size != NULL);
/* Save the before size of the window's bounding box */
/* Save the 'before' size of the window's bounding box */
nxgl_rectcopy(&bounds, &wnd->bounds);
/* Add the window origin to the supplied size get the new window bounding box */
/* Add the window origin to the supplied size get the new window bounding
* box
*/
wnd->bounds.pt2.x = wnd->bounds.pt1.x + size->w - 1;
wnd->bounds.pt2.y = wnd->bounds.pt1.y + size->h - 1;
@@ -82,8 +240,13 @@ void nxbe_setsize(FAR struct nxbe_window_s *wnd,
nxgl_rectintersect(&wnd->bounds, &wnd->bounds, &wnd->be->bkgd.bounds);
/* We need to update the larger of the two rectangles. That will be the
* union of the before and after sizes.
/* Re-allocate the per-window framebuffer memory for the new window size. */
nxbe_realloc(wnd, &bounds);
/* We need to update the larger of the two regions described by the
* original bounding box and the new bounding box. That will be the
* union of the two bounding boxes.
*/
nxgl_rectunion(&bounds, &bounds, &wnd->bounds);