GDISP streaming bug fixes

Win32 bitmap support
Win32 Rotation is back to front. Need to check touch and other drivers.
ugfx_release_2.6
inmarket 2013-09-24 16:10:15 +10:00
parent 40ec5a4e52
commit 973e34089e
8 changed files with 209 additions and 162 deletions

View File

@ -340,16 +340,16 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) {
y = g->p.y; y = g->p.y;
break; break;
case GDISP_ROTATE_90: case GDISP_ROTATE_90:
x = g->g.Height - 1 - g->p.y; x = g->p.y;
y = g->p.x; y = g->g.Width - 1 - g->p.x;
break; break;
case GDISP_ROTATE_180: case GDISP_ROTATE_180:
x = g->g.Width - 1 - g->p.x; x = g->g.Width - 1 - g->p.x;
y = g->g.Height - 1 - g->p.y; y = g->g.Height - 1 - g->p.y;
break; break;
case GDISP_ROTATE_270: case GDISP_ROTATE_270:
x = g->p.y; x = g->g.Height - 1 - g->p.y;
y = g->g.Width - 1 - g->p.x; y = g->p.x;
break; break;
} }
#else #else
@ -384,10 +384,10 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) {
rect.right = rect.left + g->p.cx; rect.right = rect.left + g->p.cx;
break; break;
case GDISP_ROTATE_90: case GDISP_ROTATE_90:
rect.top = g->p.x; rect.bottom = g->g.Width - g->p.x;
rect.bottom = rect.top + g->p.cx; rect.top = rect.bottom - g->p.cx;
rect.right = g->g.Height - g->p.y; rect.left = g->p.y;
rect.left = rect.right - g->p.cy; rect.right = rect.left + g->p.cy;
break; break;
case GDISP_ROTATE_180: case GDISP_ROTATE_180:
rect.bottom = g->g.Height - g->p.y; rect.bottom = g->g.Height - g->p.y;
@ -396,10 +396,10 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) {
rect.left = rect.right - g->p.cx; rect.left = rect.right - g->p.cx;
break; break;
case GDISP_ROTATE_270: case GDISP_ROTATE_270:
rect.bottom = g->g.Width - g->p.x; rect.top = g->p.x;
rect.top = rect.bottom - g->p.cx; rect.bottom = rect.top + g->p.cx;
rect.left = g->p.y; rect.right = g->g.Height - g->p.y;
rect.right = rect.left + g->p.cy; rect.left = rect.right - g->p.cy;
break; break;
} }
#else #else
@ -420,8 +420,8 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) {
} }
#endif #endif
#if 0 && (GDISP_HARDWARE_BITFILLS && GDISP_NEED_CONTROL) #if GDISP_HARDWARE_BITFILLS && GDISP_NEED_CONTROL
static pixel_t *rotateimg(coord_t cx, coord_t cy, coord_t srcx, coord_t srccx, const pixel_t *buffer) { static pixel_t *rotateimg(GDISPDriver *g, const pixel_t *buffer) {
pixel_t *dstbuf; pixel_t *dstbuf;
pixel_t *dst; pixel_t *dst;
const pixel_t *src; const pixel_t *src;
@ -429,37 +429,37 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) {
coord_t i, j; coord_t i, j;
// Shortcut. // Shortcut.
if (GC->g.Orientation == GDISP_ROTATE_0 && srcx == 0 && cx == srccx) if (g->g.Orientation == GDISP_ROTATE_0 && g->p.x1 == 0 && g->p.cx == g->p.x2)
return (pixel_t *)buffer; return (pixel_t *)buffer;
// Allocate the destination buffer // Allocate the destination buffer
sz = (size_t)cx * (size_t)cy; sz = (size_t)g->p.cx * (size_t)g->p.cy;
if (!(dstbuf = (pixel_t *)malloc(sz * sizeof(pixel_t)))) if (!(dstbuf = (pixel_t *)malloc(sz * sizeof(pixel_t))))
return 0; return 0;
// Copy the bits we need // Copy the bits we need
switch(GC->g.Orientation) { switch(g->g.Orientation) {
case GDISP_ROTATE_0: case GDISP_ROTATE_0:
for(dst = dstbuf, src = buffer+srcx, j = 0; j < cy; j++) for(dst = dstbuf, src = buffer+g->p.x1, j = 0; j < g->p.cy; j++, src += g->p.x2 - g->p.cx)
for(i = 0; i < cx; i++, src += srccx - cx) for(i = 0; i < g->p.cx; i++)
*dst++ = *src++; *dst++ = *src++;
break; break;
case GDISP_ROTATE_90: case GDISP_ROTATE_90:
for(src = buffer+srcx, j = 0; j < cy; j++) { for(src = buffer+g->p.x1, j = 0; j < g->p.cy; j++, src += g->p.x2 - g->p.cx) {
dst = dstbuf+cy-j-1; dst = dstbuf+sz-g->p.cy+j;
for(i = 0; i < cx; i++, src += srccx - cx, dst += cy) for(i = 0; i < g->p.cx; i++, dst -= g->p.cy)
*dst = *src++; *dst = *src++;
} }
break; break;
case GDISP_ROTATE_180: case GDISP_ROTATE_180:
for(dst = dstbuf+sz, src = buffer+srcx, j = 0; j < cy; j++) for(dst = dstbuf+sz, src = buffer+g->p.x1, j = 0; j < g->p.cy; j++, src += g->p.x2 - g->p.cx)
for(i = 0; i < cx; i++, src += srccx - cx) for(i = 0; i < g->p.cx; i++)
*--dst = *src++; *--dst = *src++;
break; break;
case GDISP_ROTATE_270: case GDISP_ROTATE_270:
for(src = buffer+srcx, j = 0; j < cy; j++) { for(src = buffer+g->p.x1, j = 0; j < g->p.cy; j++, src += g->p.x2 - g->p.cx) {
dst = dstbuf+sz-cy+j; dst = dstbuf+g->p.cy-j-1;
for(i = 0; i < cx; i++, src += srccx - cx, dst -= cy) for(i = 0; i < g->p.cx; i++, dst += g->p.cy)
*dst = *src++; *dst = *src++;
} }
break; break;
@ -468,34 +468,24 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) {
} }
#endif #endif
#if 0 && GDISP_HARDWARE_BITFILLS #if GDISP_HARDWARE_BITFILLS
/** void gdisp_lld_blit_area(GDISPDriver *g) {
* @brief Fill an area with a bitmap.
* @note Optional - The high level driver can emulate using software.
*
* @param[in] x, y The start filled area
* @param[in] cx, cy The width and height to be filled
* @param[in] srcx, srcy The bitmap position to start the fill from
* @param[in] srccx The width of a line in the bitmap.
* @param[in] buffer The pixels to use to fill the area.
*
* @notapi
*/
void gdisp_lld_blit_area(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) {
BITMAPV4HEADER bmpInfo; BITMAPV4HEADER bmpInfo;
RECT rect; HDC dcScreen;
pixel_t * buffer;
#if GDISP_NEED_CONTROL #if GDISP_NEED_CONTROL
pixel_t *srcimg; RECT rect;
pixel_t * srcimg;
#endif #endif
// Make everything relative to the start of the line // Make everything relative to the start of the line
buffer += srccx*srcy; buffer = g->p.ptr;
srcy = 0; buffer += g->p.x2*g->p.y1;
memset(&bmpInfo, 0, sizeof(bmpInfo)); memset(&bmpInfo, 0, sizeof(bmpInfo));
bmpInfo.bV4Size = sizeof(bmpInfo); bmpInfo.bV4Size = sizeof(bmpInfo);
bmpInfo.bV4Planes = 1; bmpInfo.bV4Planes = 1;
bmpInfo.bV4BitCount = 32; bmpInfo.bV4BitCount = sizeof(pixel_t)*8;
bmpInfo.bV4AlphaMask = 0; bmpInfo.bV4AlphaMask = 0;
bmpInfo.bV4RedMask = RGB2COLOR(255,0,0); bmpInfo.bV4RedMask = RGB2COLOR(255,0,0);
bmpInfo.bV4GreenMask = RGB2COLOR(0,255,0); bmpInfo.bV4GreenMask = RGB2COLOR(0,255,0);
@ -508,62 +498,60 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) {
bmpInfo.bV4CSType = 0; //LCS_sRGB; bmpInfo.bV4CSType = 0; //LCS_sRGB;
#if GDISP_NEED_CONTROL #if GDISP_NEED_CONTROL
bmpInfo.bV4SizeImage = (cy*cx) * sizeof(pixel_t); bmpInfo.bV4SizeImage = (g->p.cy*g->p.cx) * sizeof(pixel_t);
srcimg = rotateimg(cx, cy, srcx, srccx, buffer); srcimg = rotateimg(g, buffer);
if (!srcimg) return; if (!srcimg) return;
switch(GC->g.Orientation) { switch(g->g.Orientation) {
case GDISP_ROTATE_0: case GDISP_ROTATE_0:
bmpInfo.bV4Width = cx; bmpInfo.bV4Width = g->p.cx;
bmpInfo.bV4Height = -cy; /* top-down image */ bmpInfo.bV4Height = -g->p.cy; /* top-down image */
rect.top = y; rect.top = g->p.y;
rect.bottom = rect.top+cy; rect.bottom = rect.top+g->p.cy;
rect.left = x; rect.left = g->p.x;
rect.right = rect.left+cx; rect.right = rect.left+g->p.cx;
break; break;
case GDISP_ROTATE_90: case GDISP_ROTATE_90:
bmpInfo.bV4Width = cy; bmpInfo.bV4Width = g->p.cy;
bmpInfo.bV4Height = -cx; /* top-down image */ bmpInfo.bV4Height = -g->p.cx; /* top-down image */
rect.top = x; rect.bottom = g->g.Width - g->p.x;
rect.bottom = rect.top+cx; rect.top = rect.bottom-g->p.cx;
rect.right = GC->g.Height - y; rect.left = g->p.y;
rect.left = rect.right-cy; rect.right = rect.left+g->p.cy;
break; break;
case GDISP_ROTATE_180: case GDISP_ROTATE_180:
bmpInfo.bV4Width = cx; bmpInfo.bV4Width = g->p.cx;
bmpInfo.bV4Height = -cy; /* top-down image */ bmpInfo.bV4Height = -g->p.cy; /* top-down image */
rect.bottom = GC->g.Height - y; rect.bottom = g->g.Height-1 - g->p.y;
rect.top = rect.bottom-cy; rect.top = rect.bottom-g->p.cy;
rect.right = GC->g.Width - x; rect.right = g->g.Width - g->p.x;
rect.left = rect.right-cx; rect.left = rect.right-g->p.cx;
break; break;
case GDISP_ROTATE_270: case GDISP_ROTATE_270:
bmpInfo.bV4Width = cy; bmpInfo.bV4Width = g->p.cy;
bmpInfo.bV4Height = -cx; /* top-down image */ bmpInfo.bV4Height = -g->p.cx; /* top-down image */
rect.bottom = GC->g.Width - x; rect.top = g->p.x;
rect.top = rect.bottom-cx; rect.bottom = rect.top+g->p.cx;
rect.left = y; rect.right = g->g.Height - g->p.y;
rect.right = rect.left+cy; rect.left = rect.right-g->p.cy;
break; break;
} }
dcScreen = GetDC(winRootWindow);
SetDIBitsToDevice(dcBuffer, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, 0, 0, 0, rect.bottom-rect.top, srcimg, (BITMAPINFO*)&bmpInfo, DIB_RGB_COLORS); SetDIBitsToDevice(dcBuffer, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, 0, 0, 0, rect.bottom-rect.top, srcimg, (BITMAPINFO*)&bmpInfo, DIB_RGB_COLORS);
if (srcimg != (pixel_t *)buffer) SetDIBitsToDevice(dcScreen, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, 0, 0, 0, rect.bottom-rect.top, srcimg, (BITMAPINFO*)&bmpInfo, DIB_RGB_COLORS);
ReleaseDC(winRootWindow, dcScreen);
if (srcimg != buffer)
free(srcimg); free(srcimg);
#else #else
bmpInfo.bV4Width = srccx; bmpInfo.bV4Width = g->p.x2;
bmpInfo.bV4Height = -cy; /* top-down image */ bmpInfo.bV4Height = -g->p.cy; /* top-down image */
bmpInfo.bV4SizeImage = (cy*srccx) * sizeof(pixel_t); bmpInfo.bV4SizeImage = (g->p.cy*g->p.x2) * sizeof(pixel_t);
rect.top = y; dcScreen = GetDC(winRootWindow);
rect.bottom = rect.top+cy; SetDIBitsToDevice(dcBuffer, g->p.x, g->p.y, g->p.cx, g->p.cy, g->p.x1, 0, 0, g->p.cy, buffer, (BITMAPINFO*)&bmpInfo, DIB_RGB_COLORS);
rect.left = x; SetDIBitsToDevice(dcScreen, g->p.x, g->p.y, g->p.cx, g->p.cy, g->p.x1, 0, 0, g->p.cy, buffer, (BITMAPINFO*)&bmpInfo, DIB_RGB_COLORS);
rect.right = rect.left+cx; ReleaseDC(winRootWindow, dcScreen);
SetDIBitsToDevice(dcBuffer, x, y, cx, cy, srcx, 0, 0, cy, buffer, (BITMAPINFO*)&bmpInfo, DIB_RGB_COLORS);
#endif #endif
// Invalidate the region to get it on the screen.
InvalidateRect(winRootWindow, &rect, FALSE);
UpdateWindow(winRootWindow);
} }
#endif #endif
@ -577,13 +565,13 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) {
color = GetPixel(dcBuffer, g->p.x, g->p.y); color = GetPixel(dcBuffer, g->p.x, g->p.y);
break; break;
case GDISP_ROTATE_90: case GDISP_ROTATE_90:
color = GetPixel(dcBuffer, g->g.Height - 1 - g->p.y, g->p.x); color = GetPixel(dcBuffer, g->p.y, g->g.Width - 1 - g->p.x);
break; break;
case GDISP_ROTATE_180: case GDISP_ROTATE_180:
color = GetPixel(dcBuffer, g->g.Width - 1 - g->p.x, g->g.Height - 1 - g->p.y); color = GetPixel(dcBuffer, g->g.Width - 1 - g->p.x, g->g.Height - 1 - g->p.y);
break; break;
case GDISP_ROTATE_270: case GDISP_ROTATE_270:
color = GetPixel(dcBuffer, g->p.y, g->g.Width - 1 - g->p.x); color = GetPixel(dcBuffer, g->g.Height - 1 - g->p.y, g->p.x);
break; break;
} }
#else #else
@ -610,11 +598,11 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) {
lines = -g->p.y1; lines = -g->p.y1;
goto vertical_scroll; goto vertical_scroll;
case GDISP_ROTATE_90: case GDISP_ROTATE_90:
rect.top = g->p.x; rect.bottom = g->g.Width - g->p.x;
rect.bottom = rect.top+g->p.cx; rect.top = rect.bottom-g->p.cx;
rect.right = g->g.Height - g->p.y; rect.left = g->p.y;
rect.left = rect.right-g->p.cy; rect.right = rect.left+g->p.cy;
lines = g->p.y1; lines = -g->p.y1;
goto horizontal_scroll; goto horizontal_scroll;
case GDISP_ROTATE_180: case GDISP_ROTATE_180:
rect.bottom = g->g.Height - g->p.y; rect.bottom = g->g.Height - g->p.y;
@ -636,11 +624,11 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) {
} }
break; break;
case GDISP_ROTATE_270: case GDISP_ROTATE_270:
rect.bottom = g->g.Width - g->p.x; rect.top = g->p.x;
rect.top = rect.bottom-g->p.cx; rect.bottom = rect.top+g->p.cx;
rect.left = g->p.y; rect.right = g->g.Height - g->p.y;
rect.right = rect.left+g->p.cy; rect.left = rect.right-g->p.cy;
lines = -g->p.y1; lines = g->p.y1;
horizontal_scroll: horizontal_scroll:
if (lines > 0) { if (lines > 0) {
rect.right -= lines; rect.right -= lines;
@ -684,17 +672,11 @@ LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g) {
return; return;
switch((orientation_t)g->p.ptr) { switch((orientation_t)g->p.ptr) {
case GDISP_ROTATE_0: case GDISP_ROTATE_0:
g->g.Width = wWidth;
g->g.Height = wHeight;
break;
case GDISP_ROTATE_90:
g->g.Height = wWidth;
g->g.Width = wHeight;
break;
case GDISP_ROTATE_180: case GDISP_ROTATE_180:
g->g.Width = wWidth; g->g.Width = wWidth;
g->g.Height = wHeight; g->g.Height = wHeight;
break; break;
case GDISP_ROTATE_90:
case GDISP_ROTATE_270: case GDISP_ROTATE_270:
g->g.Height = wWidth; g->g.Height = wWidth;
g->g.Width = wHeight; g->g.Width = wHeight;

View File

@ -29,7 +29,7 @@
#define GDISP_HARDWARE_FILLS TRUE #define GDISP_HARDWARE_FILLS TRUE
#define GDISP_HARDWARE_PIXELREAD TRUE #define GDISP_HARDWARE_PIXELREAD TRUE
#define GDISP_HARDWARE_CONTROL TRUE #define GDISP_HARDWARE_CONTROL TRUE
//#define GDISP_HARDWARE_BITFILLS TRUE #define GDISP_HARDWARE_BITFILLS TRUE
#define GDISP_HARDWARE_SCROLL TRUE #define GDISP_HARDWARE_SCROLL TRUE
#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_RGB888 #define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_RGB888

View File

@ -14,11 +14,11 @@
#ifndef _GFXCONF_H #ifndef _GFXCONF_H
#define _GFXCONF_H #define _GFXCONF_H
/* The operating system to use - one of these must be defined */ /* The operating system to use - one of these must be defined - preferably via your makefile */
#define GFX_USE_OS_CHIBIOS FALSE //#define GFX_USE_OS_CHIBIOS FALSE
#define GFX_USE_OS_WIN32 FALSE //#define GFX_USE_OS_WIN32 FALSE
#define GFX_USE_OS_LINUX FALSE //#define GFX_USE_OS_LINUX FALSE
#define GFX_USE_OS_OSX FALSE //#define GFX_USE_OS_OSX FALSE
/* GFX subsystems to turn on */ /* GFX subsystems to turn on */
#define GFX_USE_GDISP FALSE #define GFX_USE_GDISP FALSE
@ -37,8 +37,8 @@
#define GDISP_NEED_VALIDATION TRUE #define GDISP_NEED_VALIDATION TRUE
#define GDISP_NEED_CLIP TRUE #define GDISP_NEED_CLIP TRUE
#define GDISP_NEED_TEXT TRUE #define GDISP_NEED_TEXT TRUE
#define GDISP_NEED_CIRCLE TRUE #define GDISP_NEED_CIRCLE FALSE
#define GDISP_NEED_ELLIPSE TRUE #define GDISP_NEED_ELLIPSE FALSE
#define GDISP_NEED_ARC FALSE #define GDISP_NEED_ARC FALSE
#define GDISP_NEED_CONVEX_POLYGON FALSE #define GDISP_NEED_CONVEX_POLYGON FALSE
#define GDISP_NEED_SCROLL FALSE #define GDISP_NEED_SCROLL FALSE
@ -47,13 +47,17 @@
#define GDISP_NEED_QUERY FALSE #define GDISP_NEED_QUERY FALSE
#define GDISP_NEED_IMAGE FALSE #define GDISP_NEED_IMAGE FALSE
#define GDISP_NEED_MULTITHREAD FALSE #define GDISP_NEED_MULTITHREAD FALSE
#define GDISP_NEED_ASYNC FALSE #define GDISP_NEED_STREAMING FALSE
#define GDISP_NEED_MSGAPI FALSE
/* GDISP - text features */
#define GDISP_NEED_ANTIALIAS FALSE #define GDISP_NEED_ANTIALIAS FALSE
#define GDISP_NEED_UTF8 FALSE #define GDISP_NEED_UTF8 FALSE
#define GDISP_NEED_TEXT_KERNING FALSE #define GDISP_NEED_TEXT_KERNING FALSE
/* GDISP - fonts to include */ /* GDISP - fonts to include */
#define GDISP_INCLUDE_FONT_UI1 FALSE
#define GDISP_INCLUDE_FONT_UI2 FALSE
#define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE
#define GDISP_INCLUDE_FONT_DEJAVUSANS10 FALSE #define GDISP_INCLUDE_FONT_DEJAVUSANS10 FALSE
#define GDISP_INCLUDE_FONT_DEJAVUSANS12 FALSE #define GDISP_INCLUDE_FONT_DEJAVUSANS12 FALSE
#define GDISP_INCLUDE_FONT_DEJAVUSANS16 FALSE #define GDISP_INCLUDE_FONT_DEJAVUSANS16 FALSE
@ -68,10 +72,6 @@
#define GDISP_INCLUDE_FONT_DEJAVUSANS24_AA FALSE #define GDISP_INCLUDE_FONT_DEJAVUSANS24_AA FALSE
#define GDISP_INCLUDE_FONT_DEJAVUSANS32_AA FALSE #define GDISP_INCLUDE_FONT_DEJAVUSANS32_AA FALSE
#define GDISP_INCLUDE_FONT_DEJAVUSANSBOLD12_AA FALSE #define GDISP_INCLUDE_FONT_DEJAVUSANSBOLD12_AA FALSE
#define GDISP_INCLUDE_FONT_UI1 FALSE
#define GDISP_INCLUDE_FONT_UI2 FALSE
#define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE
#define GDISP_INCLUDE_USER_FONTS FALSE #define GDISP_INCLUDE_USER_FONTS FALSE
/* GDISP image decoders */ /* GDISP image decoders */
@ -139,12 +139,11 @@
#define GMISC_NEED_ARRAYOPS FALSE #define GMISC_NEED_ARRAYOPS FALSE
#define GMISC_NEED_FASTTRIG FALSE #define GMISC_NEED_FASTTRIG FALSE
#define GMISC_NEED_FIXEDTRIG FALSE #define GMISC_NEED_FIXEDTRIG FALSE
#define GMISC_NEED_INVSQRT FALSE
/* Optional Parameters for various subsystems */ /* Optional Parameters for various subsystems */
/* /*
#define GDISP_NEED_UTF8 FALSE #define GDISP_LINEBUF_SIZE 128
#define GDISP_NEED_TEXT_KERNING FALSE
#define GDISP_NEED_ANTIALIAS FALSE
#define GEVENT_MAXIMUM_SIZE 32 #define GEVENT_MAXIMUM_SIZE 32
#define GEVENT_MAX_SOURCE_LISTENERS 32 #define GEVENT_MAX_SOURCE_LISTENERS 32
#define GTIMER_THREAD_WORKAREA_SIZE 512 #define GTIMER_THREAD_WORKAREA_SIZE 512

View File

@ -430,6 +430,58 @@ void gdispBlitAreaEx(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx,
*/ */
void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color); void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
/* Streaming Functions */
#if GDISP_NEED_STREAMING || defined(__DOXYGEN__)
/**
* @brief Start a streaming operation.
* @details Stream data to a window on the display sequentially and very fast.
* @note While streaming is in operation - no other calls to GDISP functions
* can be made (with the exception of @p gdispBlendColor() and streaming
* functions). If a call is made (eg in a multi-threaded application) the other
* call is blocked waiting for the streaming operation to finish.
* @note @p gdispStreamStop() must be called to finish the streaming operation.
* @note If more data is written than the defined area then the results are unspecified.
* Some drivers may wrap back to the beginning of the area, others may just
* ignore subsequent data.
* @note Unlike most operations that clip the defined area to the display to generate
* a smaller active area, this call will just silently fail if any of the stream
* region lies outside the current clipping area.
* @note A streaming operation may be terminated early (without writing to every location
* in the stream area) by calling @p gdispStreamStop().
*
* @param[in] x,y The start position
* @param[in] cx,cy The size of the streamable area
*
* @api
*/
void gdispStreamStart(coord_t x, coord_t y, coord_t cx, coord_t cy);
/**
* @brief Send pixel data to the stream.
* @details Write a pixel to the next position in the streamed area and increment the position
* @pre @p gdispStreamStart() has been called.
* @note If the gdispStreamStart() has not been called (or failed due to clipping), the
* data provided here is simply thrown away.
*
* @param[in] color The color of the pixel to write
*
* @api
*/
void gdispStreamColor(color_t color);
/**
* @brief Finish the current streaming operation.
* @details Completes the current streaming operation and allows other GDISP calls to operate again.
* @pre @p gdispStreamStart() has been called.
* @note If the gdispStreamStart() has not been called (or failed due to clipping), this
* call is simply ignored.
*
* @api
*/
void gdispStreamStop(void);
#endif
/* Clipping Functions */ /* Clipping Functions */
#if GDISP_NEED_CLIP || defined(__DOXYGEN__) #if GDISP_NEED_CLIP || defined(__DOXYGEN__)

View File

@ -184,7 +184,7 @@ typedef struct GDISPDriver {
} GDISPDriver; } GDISPDriver;
#if !GDISP_MULTIPLE_DRIVERS || defined(GDISP_LLD_DECLARATIONS) #if !GDISP_MULTIPLE_DRIVERS || defined(GDISP_LLD_DECLARATIONS) || defined(__DOXYGEN__)
#if GDISP_MULTIPLE_DRIVERS #if GDISP_MULTIPLE_DRIVERS
#define LLDSPEC static #define LLDSPEC static
#else #else
@ -203,7 +203,7 @@ typedef struct GDISPDriver {
*/ */
LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g); LLDSPEC bool_t gdisp_lld_init(GDISPDriver *g);
#if GDISP_HARDWARE_STREAM #if GDISP_HARDWARE_STREAM || defined(__DOXYGEN__)
/** /**
* @brief Start a streamed operation * @brief Start a streamed operation
* @pre GDISP_HARDWARE_STREAM is TRUE * @pre GDISP_HARDWARE_STREAM is TRUE
@ -228,7 +228,7 @@ typedef struct GDISPDriver {
*/ */
LLDSPEC void gdisp_lld_stream_color(GDISPDriver *g); LLDSPEC void gdisp_lld_stream_color(GDISPDriver *g);
#if GDISP_HARDWARE_STREAM_READ #if GDISP_HARDWARE_STREAM_READ || defined(__DOXYGEN__)
/** /**
* @brief Read a pixel from the current streaming position and then increment that position * @brief Read a pixel from the current streaming position and then increment that position
* @return The color at the current position * @return The color at the current position
@ -241,7 +241,7 @@ typedef struct GDISPDriver {
LLDSPEC color_t gdisp_lld_stream_read(GDISPDriver *g); LLDSPEC color_t gdisp_lld_stream_read(GDISPDriver *g);
#endif #endif
#if GDISP_HARDWARE_STREAM_END #if GDISP_HARDWARE_STREAM_END || defined(__DOXYGEN__)
/** /**
* @brief End the current streaming operation * @brief End the current streaming operation
* @pre GDISP_HARDWARE_STREAM and GDISP_HARDWARE_STREAM_END is TRUE * @pre GDISP_HARDWARE_STREAM and GDISP_HARDWARE_STREAM_END is TRUE
@ -254,7 +254,7 @@ typedef struct GDISPDriver {
#endif #endif
#endif #endif
#if GDISP_HARDWARE_DRAWPIXEL #if GDISP_HARDWARE_DRAWPIXEL || defined(__DOXYGEN__)
/** /**
* @brief Draw a pixel * @brief Draw a pixel
* @pre GDISP_HARDWARE_DRAWPIXEL is TRUE * @pre GDISP_HARDWARE_DRAWPIXEL is TRUE
@ -268,7 +268,7 @@ typedef struct GDISPDriver {
LLDSPEC void gdisp_lld_draw_pixel(GDISPDriver *g); LLDSPEC void gdisp_lld_draw_pixel(GDISPDriver *g);
#endif #endif
#if GDISP_HARDWARE_CLEARS #if GDISP_HARDWARE_CLEARS || defined(__DOXYGEN__)
/** /**
* @brief Clear the screen using the defined color * @brief Clear the screen using the defined color
* @pre GDISP_HARDWARE_CLEARS is TRUE * @pre GDISP_HARDWARE_CLEARS is TRUE
@ -281,7 +281,7 @@ typedef struct GDISPDriver {
LLDSPEC void gdisp_lld_clear(GDISPDriver *g); LLDSPEC void gdisp_lld_clear(GDISPDriver *g);
#endif #endif
#if GDISP_HARDWARE_FILLS #if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__)
/** /**
* @brief Fill an area with a single color * @brief Fill an area with a single color
* @pre GDISP_HARDWARE_FILLS is TRUE * @pre GDISP_HARDWARE_FILLS is TRUE
@ -296,7 +296,7 @@ typedef struct GDISPDriver {
LLDSPEC void gdisp_lld_fill_area(GDISPDriver *g); LLDSPEC void gdisp_lld_fill_area(GDISPDriver *g);
#endif #endif
#if GDISP_HARDWARE_BITFILLS #if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__)
/** /**
* @brief Fill an area using a bitmap * @brief Fill an area using a bitmap
* @pre GDISP_HARDWARE_BITFILLS is TRUE * @pre GDISP_HARDWARE_BITFILLS is TRUE
@ -313,7 +313,7 @@ typedef struct GDISPDriver {
LLDSPEC void gdisp_lld_blit_area(GDISPDriver *g); LLDSPEC void gdisp_lld_blit_area(GDISPDriver *g);
#endif #endif
#if GDISP_HARDWARE_PIXELREAD #if GDISP_HARDWARE_PIXELREAD || defined(__DOXYGEN__)
/** /**
* @brief Read a pixel from the display * @brief Read a pixel from the display
* @return The color at the defined position * @return The color at the defined position
@ -327,7 +327,7 @@ typedef struct GDISPDriver {
LLDSPEC color_t gdisp_lld_get_pixel_color(GDISPDriver *g); LLDSPEC color_t gdisp_lld_get_pixel_color(GDISPDriver *g);
#endif #endif
#if GDISP_HARDWARE_SCROLL && GDISP_NEED_SCROLL #if (GDISP_HARDWARE_SCROLL && GDISP_NEED_SCROLL) || defined(__DOXYGEN__)
/** /**
* @brief Scroll an area of the screen * @brief Scroll an area of the screen
* @pre GDISP_HARDWARE_SCROLL is TRUE (and the application needs it) * @pre GDISP_HARDWARE_SCROLL is TRUE (and the application needs it)
@ -346,7 +346,7 @@ typedef struct GDISPDriver {
LLDSPEC void gdisp_lld_vertical_scroll(GDISPDriver *g); LLDSPEC void gdisp_lld_vertical_scroll(GDISPDriver *g);
#endif #endif
#if GDISP_HARDWARE_CONTROL && GDISP_NEED_CONTROL #if (GDISP_HARDWARE_CONTROL && GDISP_NEED_CONTROL) || defined(__DOXYGEN__)
/** /**
* @brief Control some feature of the hardware * @brief Control some feature of the hardware
* @pre GDISP_HARDWARE_CONTROL is TRUE (and the application needs it) * @pre GDISP_HARDWARE_CONTROL is TRUE (and the application needs it)
@ -360,7 +360,7 @@ typedef struct GDISPDriver {
LLDSPEC void gdisp_lld_control(GDISPDriver *g); LLDSPEC void gdisp_lld_control(GDISPDriver *g);
#endif #endif
#if GDISP_HARDWARE_QUERY && GDISP_NEED_QUERY #if (GDISP_HARDWARE_QUERY && GDISP_NEED_QUERY) || defined(__DOXYGEN__)
/** /**
* @brief Query some feature of the hardware * @brief Query some feature of the hardware
* @return The information requested (typecast as void *) * @return The information requested (typecast as void *)
@ -374,7 +374,7 @@ typedef struct GDISPDriver {
LLDSPEC void *gdisp_lld_query(GDISPDriver *g); // Uses p.x (=what); LLDSPEC void *gdisp_lld_query(GDISPDriver *g); // Uses p.x (=what);
#endif #endif
#if GDISP_HARDWARE_CLIP && (GDISP_NEED_CLIP || GDISP_NEED_VALIDATION) #if (GDISP_HARDWARE_CLIP && (GDISP_NEED_CLIP || GDISP_NEED_VALIDATION)) || defined(__DOXYGEN__)
/** /**
* @brief Set the hardware clipping area * @brief Set the hardware clipping area
* @pre GDISP_HARDWARE_CLIP is TRUE (and the application needs it) * @pre GDISP_HARDWARE_CLIP is TRUE (and the application needs it)

View File

@ -184,6 +184,23 @@ extern "C" {
/** @} */ /** @} */
#endif #endif
#if GMISC_NEED_INVSQRT
/**
* @brief Fast inverse square root function (x^-1/2)
* @return The approximate inverse square root
*
* @param[in] n The number to find the inverse square root of
*
* @note This function generates an approximate result. Higher accuracy (at the expense
* of speed) can be obtained by modifying the source code (the necessary line
* is already there - just commented out).
* @note This function relies on the internal machine format of a float and a long.
* If your machine architecture is very unusual this function may not work.
*
* @api
*/
float invsqrt(float n);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -27,13 +27,6 @@
#ifndef GMISC_NEED_ARRAYOPS #ifndef GMISC_NEED_ARRAYOPS
#define GMISC_NEED_ARRAYOPS FALSE #define GMISC_NEED_ARRAYOPS FALSE
#endif #endif
/**
* @brief Include fast array based trig functions (sin, cos)
* @details Defaults to FALSE
*/
#ifndef GMISC_NEED_FASTTRIG
#define GMISC_NEED_FASTTRIG FALSE
#endif
/** /**
* @brief Include fast fixed point trig functions (sin, cos) * @brief Include fast fixed point trig functions (sin, cos)
* @details Defaults to FALSE * @details Defaults to FALSE
@ -41,6 +34,13 @@
#ifndef GMISC_NEED_FIXEDTRIG #ifndef GMISC_NEED_FIXEDTRIG
#define GMISC_NEED_FIXEDTRIG FALSE #define GMISC_NEED_FIXEDTRIG FALSE
#endif #endif
/**
* @brief Include fast inverse square root (x^-1/2)
* @details Defaults to FALSE
*/
#ifndef GMISC_NEED_INVSQRT
#define GMISC_NEED_INVSQRT FALSE
#endif
/** /**
* @} * @}
* *

View File

@ -367,7 +367,7 @@ void _gdispInit(void) {
#if NEED_CLIPPING #if NEED_CLIPPING
// Test if the area is valid - if not then exit // Test if the area is valid - if not then exit
if (x < GC->clipx0 || x+cx >= GC->clipx1 || y < GC->clipy0 || y+cy >= GC->clipy1) { if (x < GC->clipx0 || x+cx > GC->clipx1 || y < GC->clipy0 || y+cy > GC->clipy1) {
MUTEX_EXIT(); MUTEX_EXIT();
return; return;
} }
@ -398,7 +398,7 @@ void _gdispInit(void) {
void gdispStreamColor(color_t color) { void gdispStreamColor(color_t color) {
#if !GDISP_HARDWARE_STREAM && GDISP_LINEBUF_SIZE != 0 && GDISP_HARDWARE_BITFILLS #if !GDISP_HARDWARE_STREAM && GDISP_LINEBUF_SIZE != 0 && GDISP_HARDWARE_BITFILLS
coord_t pos, sx1, sy1, sx2; coord_t sx1, sy1, sx2;
#endif #endif
// Don't touch the mutex as we should already own it // Don't touch the mutex as we should already own it
@ -413,48 +413,45 @@ void _gdispInit(void) {
gdisp_lld_stream_color(GC); gdisp_lld_stream_color(GC);
#elif GDISP_LINEBUF_SIZE != 0 && GDISP_HARDWARE_BITFILLS #elif GDISP_LINEBUF_SIZE != 0 && GDISP_HARDWARE_BITFILLS
GC->linebuf[GC->p.cx++] = color; GC->linebuf[GC->p.cx++] = color;
GC->p.x++;
if (GC->p.cx >= GDISP_LINEBUF_SIZE) { if (GC->p.cx >= GDISP_LINEBUF_SIZE) {
pos = GC->p.cx;
sx1 = GC->p.x1; sx1 = GC->p.x1;
sy1 = GC->p.y1; sy1 = GC->p.y1;
sx2 = GC->p.x2; //sx2 = GC->p.x2;
GC->p.x -= pos; GC->p.x -= GC->p.cx;
GC->p.cx = pos;
GC->p.cy = 1; GC->p.cy = 1;
GC->p.x1 = 0; GC->p.x1 = 0;
GC->p.y1 = 0; GC->p.y1 = 0;
GC->p.x2 = pos; //GC->p.x2 = GC->p.cx;
GC->p.ptr = (void *)GC->linebuf; GC->p.ptr = (void *)GC->linebuf;
gdisp_lld_blit_area(GC); gdisp_lld_blit_area(GC);
GC->p.x1 = sx1; GC->p.x1 = sx1;
GC->p.y1 = sy1; GC->p.y1 = sy1;
GC->p.x2 = sx2; //GC->p.x2 = sx2;
GC->p.x += pos; GC->p.x += GC->p.cx;
GC->p.cx = 0; GC->p.cx = 0;
} }
// Just wrap at end-of-line and end-of-buffer // Just wrap at end-of-line and end-of-buffer
if (++GC->p.x >= GC->p.x2) { if (GC->p.x >= GC->p.x2) {
if (GC->p.cx) { if (GC->p.cx) {
pos = GC->p.cx;
sx1 = GC->p.x1; sx1 = GC->p.x1;
sy1 = GC->p.y1; sy1 = GC->p.y1;
sx2 = GC->p.x2; //sx2 = GC->p.x2;
GC->p.x -= pos; GC->p.x -= GC->p.cx;
GC->p.cx = pos;
GC->p.cy = 1; GC->p.cy = 1;
GC->p.x1 = 0; GC->p.x1 = 0;
GC->p.y1 = 0; GC->p.y1 = 0;
GC->p.x2 = pos; //GC->p.x2 = GC->p.cx;
GC->p.ptr = (void *)GC->linebuf; GC->p.ptr = (void *)GC->linebuf;
gdisp_lld_blit_area(GC); gdisp_lld_blit_area(GC);
GC->p.x1 = sx1; GC->p.x1 = sx1;
GC->p.y1 = sy1; GC->p.y1 = sy1;
GC->p.x2 = sx2; //GC->p.x2 = sx2;
GC->p.cx = 0; GC->p.cx = 0;
} }
GC->p.x = GC->p.x1; GC->p.x = GC->p.x1;
if (++GC->p.y >= GC->p.x2) if (++GC->p.y >= GC->p.y2)
GC->p.y = GC->p.y1; GC->p.y = GC->p.y1;
} }
#else #else
@ -465,13 +462,13 @@ void _gdispInit(void) {
// Just wrap at end-of-line and end-of-buffer // Just wrap at end-of-line and end-of-buffer
if (++GC->p.x >= GC->p.x2) { if (++GC->p.x >= GC->p.x2) {
GC->p.x = GC->p.x1; GC->p.x = GC->p.x1;
if (++GC->p.y >= GC->p.x2) if (++GC->p.y >= GC->p.y2)
GC->p.y = GC->p.y1; GC->p.y = GC->p.y1;
} }
#endif #endif
} }
void gdispStreamEnd(void) { void gdispStreamStop(void) {
// Only release the mutex and end the stream if we are actually streaming. // Only release the mutex and end the stream if we are actually streaming.
if (!(GC->flags & GDISP_FLG_INSTREAM)) if (!(GC->flags & GDISP_FLG_INSTREAM))
return; return;
@ -486,7 +483,7 @@ void _gdispInit(void) {
GC->p.cy = 1; GC->p.cy = 1;
GC->p.x1 = 0; GC->p.x1 = 0;
GC->p.y1 = 0; GC->p.y1 = 0;
GC->p.x2 = GC->p.cx; //GC->p.x2 = GC->p.cx;
GC->p.ptr = (void *)GC->linebuf; GC->p.ptr = (void *)GC->linebuf;
gdisp_lld_blit_area(GC); gdisp_lld_blit_area(GC);
} }