aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorinmarket <andrewh@inmarket.com.au>2013-09-27 01:37:32 +1000
committerinmarket <andrewh@inmarket.com.au>2013-09-27 01:37:32 +1000
commit548eb3c981772ec4be1211352867f2edcdc24423 (patch)
tree9f7e39a4574f69b4ad4304733802da7429cb373c
parenta7360c13c2f4527d38888a249d2ce83ed2dc41f0 (diff)
downloaduGFX-548eb3c981772ec4be1211352867f2edcdc24423.tar.gz
uGFX-548eb3c981772ec4be1211352867f2edcdc24423.tar.bz2
uGFX-548eb3c981772ec4be1211352867f2edcdc24423.zip
GDISP Streaming bug fixes and new optimisation method
-rw-r--r--src/gdisp/gdisp.c81
1 files changed, 70 insertions, 11 deletions
diff --git a/src/gdisp/gdisp.c b/src/gdisp/gdisp.c
index 2e423764..828e5aa9 100644
--- a/src/gdisp/gdisp.c
+++ b/src/gdisp/gdisp.c
@@ -185,7 +185,7 @@ static void hline_clip(void) {
gdisp_lld_fill_area(GC);
#elif GDISP_HARDWARE_STREAM
// Next best is streaming
- GC->p.cx = GC->p.x1 - GC->p.x;
+ GC->p.cx = GC->p.x1 - GC->p.x + 1;
GC->p.cy = 1;
gdisp_lld_stream_start(GC);
do { gdisp_lld_stream_color(GC); } while(GC->p.cx--);
@@ -243,7 +243,7 @@ static void vline_clip(void) {
gdisp_lld_fill_area(GC);
#elif GDISP_HARDWARE_STREAM
// Next best is streaming
- GC->p.cy = GC->p.y1 - GC->p.y;
+ GC->p.cy = GC->p.y1 - GC->p.y + 1;
GC->p.cx = 1;
gdisp_lld_stream_start(GC);
do { gdisp_lld_stream_color(GC); } while(GC->p.cy--);
@@ -392,7 +392,10 @@ void _gdispInit(void) {
GC->p.y1 = GC->p.y = y;
GC->p.x2 = x + cx;
GC->p.y2 = y + cy;
- GC->p.cx = 0;
+ #if (GDISP_LINEBUF_SIZE != 0 && GDISP_HARDWARE_BITFILLS) || GDISP_HARDWARE_FILLS
+ GC->p.cx = 0;
+ GC->p.cy = 1;
+ #endif
#endif
// Don't release the mutex as gdispStreamEnd() will do that.
@@ -415,12 +418,9 @@ void _gdispInit(void) {
gdisp_lld_stream_color(GC);
#elif GDISP_LINEBUF_SIZE != 0 && GDISP_HARDWARE_BITFILLS
GC->linebuf[GC->p.cx++] = color;
- GC->p.x++;
if (GC->p.cx >= GDISP_LINEBUF_SIZE) {
sx1 = GC->p.x1;
sy1 = GC->p.y1;
- GC->p.x -= GC->p.cx;
- GC->p.cy = 1;
GC->p.x1 = 0;
GC->p.y1 = 0;
GC->p.ptr = (void *)GC->linebuf;
@@ -432,12 +432,10 @@ void _gdispInit(void) {
}
// Just wrap at end-of-line and end-of-buffer
- if (GC->p.x >= GC->p.x2) {
+ if (GC->p.x+GC->p.cx >= GC->p.x2) {
if (GC->p.cx) {
sx1 = GC->p.x1;
sy1 = GC->p.y1;
- GC->p.x -= GC->p.cx;
- GC->p.cy = 1;
GC->p.x1 = 0;
GC->p.y1 = 0;
GC->p.ptr = (void *)GC->linebuf;
@@ -450,6 +448,33 @@ void _gdispInit(void) {
if (++GC->p.y >= GC->p.y2)
GC->p.y = GC->p.y1;
}
+ #elif GDISP_HARDWARE_FILLS
+ // Only slightly better than drawing pixels is to look for runs and use fill area
+ if (!GC->p.cx || GC->p.color == color) {
+ GC->p.cx++;
+ GC->p.color = color;
+ } else {
+ if (GC->p.cx == 1)
+ gdisp_lld_draw_pixel(GC);
+ else
+ gdisp_lld_fill_area(GC);
+ GC->p.x += GC->p.cx;
+ GC->p.color = color;
+ GC->p.cx = 1;
+ }
+ // Just wrap at end-of-line and end-of-buffer
+ if (GC->p.x+GC->p.cx >= GC->p.x2) {
+ if (GC->p.cx) {
+ if (GC->p.cx == 1)
+ gdisp_lld_draw_pixel(GC);
+ else
+ gdisp_lld_fill_area(GC);
+ GC->p.cx = 0;
+ }
+ GC->p.x = GC->p.x1;
+ if (++GC->p.y >= GC->p.y2)
+ GC->p.y = GC->p.y1;
+ }
#else
// Worst is using pixel drawing
GC->p.color = color;
@@ -475,13 +500,18 @@ void _gdispInit(void) {
#endif
#elif GDISP_LINEBUF_SIZE != 0 && GDISP_HARDWARE_BITFILLS
if (GC->p.cx) {
- GC->p.x -= GC->p.cx;
- GC->p.cy = 1;
GC->p.x1 = 0;
GC->p.y1 = 0;
GC->p.ptr = (void *)GC->linebuf;
gdisp_lld_blit_area(GC);
}
+ #elif GDISP_HARDWARE_FILLS
+ if (GC->p.cx) {
+ if (GC->p.cx == 1)
+ gdisp_lld_draw_pixel(GC);
+ else
+ gdisp_lld_fill_area(GC);
+ }
#endif
GC->flags &= ~GDISP_FLG_INSTREAM;
MUTEX_EXIT();
@@ -595,6 +625,10 @@ void gdispBlitAreaEx(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx,
srcy = y + cy;
srccx -= cx;
+ GC->p.x = x;
+ GC->p.y = y;
+ GC->p.cx = cx;
+ GC->p.cy = cy;
gdisp_lld_stream_start(GC);
for(GC->p.y = y; GC->p.y < srcy; GC->p.y++, buffer += srccx) {
for(GC->p.x = x; GC->p.x < srcx; GC->p.x++) {
@@ -605,6 +639,31 @@ void gdispBlitAreaEx(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx,
#if GDISP_HARDWARE_STREAM_STOP
gdisp_lld_stream_stop(GC);
#endif
+ #elif GDISP_HARDWARE_FILLS
+ // Only slightly better than drawing pixels is to look for runs and use fill area
+
+ // Translate buffer to the real image data, use srcx,srcy as the end point, srccx as the buffer line gap
+ buffer += srcy*srccx+srcx;
+ srcx = x + cx;
+ srcy = y + cy;
+ srccx -= cx;
+
+ GC->p.cy = 1;
+ for(GC->p.y = y; GC->p.y < srcy; GC->p.y++, buffer += srccx) {
+ for(GC->p.x=x; GC->p.x < srcx; GC->p.x += GC->p.cx) {
+ GC->p.cx=1;
+ GC->p.color = *buffer++;
+ while(GC->p.x+GC->p.cx < srcx && *buffer == GC->p.color) {
+ GC->p.cx++;
+ buffer++;
+ }
+ if (GC->p.cx == 1) {
+ gdisp_lld_draw_pixel(GC);
+ } else {
+ gdisp_lld_fill_area(GC);
+ }
+ }
+ }
#else
// Worst is drawing pixels