diff --git a/gfxconf.example.h b/gfxconf.example.h index 958d35da..d5b4af5c 100644 --- a/gfxconf.example.h +++ b/gfxconf.example.h @@ -35,6 +35,7 @@ /* Features for the GDISP subsystem */ #define GDISP_NEED_AUTOFLUSH FALSE +#define GDISP_NEED_TIMERFLUSH FALSE #define GDISP_NEED_VALIDATION TRUE #define GDISP_NEED_CLIP TRUE #define GDISP_NEED_TEXT TRUE diff --git a/include/gdisp/options.h b/include/gdisp/options.h index 72fe2038..4b199118 100644 --- a/include/gdisp/options.h +++ b/include/gdisp/options.h @@ -28,12 +28,25 @@ * Setting this to TRUE causes GDISP to automatically flush * after each drawing operation. Note this may be slow but enables * an application to avoid having to manually call the flush routine. + * @note If TRUE and GDISP_NEED_TIMERFLUSH is also TRUE, this takes precedence. * @note Most controllers don't need flushing which is why this is set to * FALSE by default. */ #ifndef GDISP_NEED_AUTOFLUSH #define GDISP_NEED_AUTOFLUSH FALSE #endif + /** + * @brief Should drawing operations be automatically flushed on a timer. + * @details Defaults to FALSE, Can be set to FALSE or a timer period in milliseconds. + * @note The period should not be set too short or it will consume all your CPU. A + * value between 250 and 500 milliseconds would probably be suitable. + * @note If TRUE and GDISP_NEED_AUTOFLUSH is also TRUE, this is ineffective. + * @note Most controllers don't need flushing which is why this is set to + * FALSE by default. + */ + #ifndef GDISP_NEED_TIMERFLUSH + #define GDISP_NEED_TIMERFLUSH FALSE + #endif /** * @brief Should all operations be clipped to the screen and colors validated. * @details Defaults to TRUE. diff --git a/include/gfx_rules.h b/include/gfx_rules.h index c58fc5ba..853d9e8a 100644 --- a/include/gfx_rules.h +++ b/include/gfx_rules.h @@ -138,10 +138,32 @@ #ifndef GDISP_CONTROLLER_LIST #error "GDISP Multiple Controllers: You must specify a value for GDISP_CONTROLLER_LIST" #endif + #ifndef GDISP_CONTROLLER_DISPLAYS + #error "GDISP Multiple Controllers: You must specify a value for GDISP_CONTROLLER_DISPLAYS" + #endif #ifndef GDISP_PIXELFORMAT + #error "GDISP Multiple Controllers: You must specify a value for GDISP_PIXELFORMAT" + #endif + #endif + #if GDISP_NEED_AUTOFLUSH && GDISP_NEED_TIMERFLUSH + #if GFX_DISPLAY_RULE_WARNINGS + #warning "GDISP: Both GDISP_NEED_AUTOFLUSH and GDISP_NEED_TIMERFLUSH has been set. GDISP_NEED_TIMERFLUSH has disabled for you." + #endif + #undef GDISP_NEED_TIMERFLUSH + #define GDISP_NEED_TIMERFLUSH FALSE + #endif + #if GDISP_NEED_TIMERFLUSH + #if GDISP_NEED_TIMERFLUSH < 50 || GDISP_NEED_TIMERFLUSH > 1200 + #error "GDISP: GDISP_NEED_TIMERFLUSH has been set to an invalid value (FALSE, 50-1200)." + #endif + #if !GFX_USE_GTIMER #if GFX_DISPLAY_RULE_WARNINGS - #error "GDISP Multiple Controllers: You must specify a value for GDISP_PIXELFORMAT" + #warning "GDISP: GDISP_NEED_TIMERFLUSH has been set but GFX_USE_GTIMER has not been set. It has been turned on for you." #endif + #undef GFX_USE_GTIMER + #define GFX_USE_GTIMER TRUE + #undef GDISP_NEED_MULTITHREAD + #define GDISP_NEED_MULTITHREAD TRUE #endif #endif #if GDISP_NEED_ANTIALIAS && !GDISP_NEED_PIXELREAD @@ -194,9 +216,9 @@ #endif #if GFX_USE_GTIMER - #if GFX_USE_GDISP && !GDISP_NEED_MULTITHREAD && !GDISP_NEED_ASYNC + #if GFX_USE_GDISP && !GDISP_NEED_MULTITHREAD #if GFX_DISPLAY_RULE_WARNINGS - #warning "GTIMER: Neither GDISP_NEED_MULTITHREAD nor GDISP_NEED_ASYNC has been specified." + #warning "GTIMER: GDISP_NEED_MULTITHREAD has not been specified." #warning "GTIMER: Make sure you are not performing any GDISP/GWIN drawing operations in the timer callback!" #endif #endif diff --git a/src/gdisp/gdisp.c b/src/gdisp/gdisp.c index 3d2e6e36..fdda1cff 100644 --- a/src/gdisp/gdisp.c +++ b/src/gdisp/gdisp.c @@ -44,6 +44,11 @@ static const struct GDISPVMT const * ControllerList[GDISP_TOTAL_CONTROLLERS] = {GDISP_CONTROLLER_LIST}; static const unsigned DisplayCountList[GDISP_TOTAL_CONTROLLERS] = {GDISP_CONTROLLER_DISPLAYS}; #endif + +#if GDISP_NEED_TIMERFLUSH + static GTimer FlushTimer; +#endif + static GDisplay GDisplayArray[GDISP_TOTAL_DISPLAYS]; GDisplay *GDISP = GDisplayArray; @@ -509,6 +514,16 @@ static void line_clip(GDisplay *g) { } #endif +#if GDISP_NEED_TIMERFLUSH + static void FlushTimerFn(void *param) { + GDisplay * g; + (void) param; + + for(g = GDisplayArray; g < &GDisplayArray[GDISP_TOTAL_DISPLAYS]; g++) + gdispGFlush(g); + } +#endif + /*===========================================================================*/ /* Driver exported functions. */ /*===========================================================================*/ @@ -521,7 +536,6 @@ void _gdispInit(void) { uint16_t j; #endif - /* Initialise driver */ #if GDISP_TOTAL_CONTROLLERS > 1 for(g = GDisplayArray, j=0; j < GDISP_TOTAL_CONTROLLERS; j++) @@ -587,6 +601,11 @@ void _gdispInit(void) { #endif } #endif + + #if GDISP_NEED_TIMERFLUSH + gtimerInit(&FlushTimer); + gtimerStart(&FlushTimer, FlushTimerFn, 0, TRUE, GDISP_NEED_TIMERFLUSH); + #endif } GDisplay *gdispGetDisplay(unsigned display) {