Fixes to gdriver to make uGFXnet displays work

This commit is contained in:
inmarket 2014-09-13 14:50:32 +10:00
parent 0c7c74112e
commit 683ac0ab7f
5 changed files with 146 additions and 63 deletions

View File

@ -12,7 +12,7 @@
#define GDISP_DRIVER_VMT GDISPVMT_uGFXnet #define GDISP_DRIVER_VMT GDISPVMT_uGFXnet
#include "drivers/multiple/uGFXnet/gdisp_lld_config.h" #include "drivers/multiple/uGFXnet/gdisp_lld_config.h"
#include "src/gdisp/driver.h" #include "src/gdisp/driver.h"
#include "drivers/multiple/uGFXnet/uGFXnetProtocol.h" #include "uGFXnetProtocol.h"
#ifndef GDISP_SCREEN_WIDTH #ifndef GDISP_SCREEN_WIDTH
#define GDISP_SCREEN_WIDTH 640 #define GDISP_SCREEN_WIDTH 640
@ -47,6 +47,7 @@
#if defined(WIN32) || GFX_USE_OS_WIN32 #if defined(WIN32) || GFX_USE_OS_WIN32
#include <winsock.h> #include <winsock.h>
#define SOCKET_TYPE SOCKET #define SOCKET_TYPE SOCKET
#define socklen_t int
static void StopSockets(void) { static void StopSockets(void) {
WSACleanup(); WSACleanup();

View File

@ -36,6 +36,17 @@
* @name GDISP hardware accelerated support * @name GDISP hardware accelerated support
* @{ * @{
*/ */
/**
* @brief The display hardware can benefit from being de-initialized when usage is complete.
* @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
*
* @note HARDWARE_AUTODETECT is only meaningful when GDISP_TOTAL_CONTROLLERS > 1
* @note This is most useful for displays such as remote network displays.
*/
#ifndef GDISP_HARDWARE_DEINIT
#define GDISP_HARDWARE_DEINIT HARDWARE_DEFAULT
#endif
/** /**
* @brief The display hardware can benefit from being flushed. * @brief The display hardware can benefit from being flushed.
* @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT * @details Can be set to TRUE, FALSE or HARDWARE_AUTODETECT
@ -215,7 +226,7 @@
struct GDisplay { struct GDisplay {
struct GDriver d; // This must be the first element struct GDriver d; // This must be the first element
#define gvmt(g) ((const GDISPVMT const *)(g)->d.vmt) // For ease of access to the vmt member #define gvmt(g) ((const GDISPVMT const *)((g)->d.vmt)) // For ease of access to the vmt member
struct GDISPControl { struct GDISPControl {
coord_t Width; coord_t Width;
@ -278,6 +289,7 @@ struct GDisplay {
typedef struct GDISPVMT { typedef struct GDISPVMT {
GDriverVMT vmtdriver; GDriverVMT vmtdriver;
bool_t (*init)(GDisplay *g); bool_t (*init)(GDisplay *g);
void (*deinit)(GDisplay *g);
void (*writestart)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy void (*writestart)(GDisplay *g); // Uses p.x,p.y p.cx,p.cy
void (*writepos)(GDisplay *g); // Uses p.x,p.y void (*writepos)(GDisplay *g); // Uses p.x,p.y
void (*writecolor)(GDisplay *g); // Uses p.color void (*writecolor)(GDisplay *g); // Uses p.color
@ -318,6 +330,17 @@ typedef struct GDISPVMT {
*/ */
LLDSPEC bool_t gdisp_lld_init(GDisplay *g); LLDSPEC bool_t gdisp_lld_init(GDisplay *g);
#if GDISP_HARDWARE_DEINIT || defined(__DOXYGEN__)
/**
* @brief The driver is being de-initialized
* @pre GDISP_HARDWARE_FLUSH is TRUE
*
* @param[in] g The driver structure
*
*/
LLDSPEC void gdisp_lld_deinit(GDisplay *g);
#endif
#if GDISP_HARDWARE_FLUSH || defined(__DOXYGEN__) #if GDISP_HARDWARE_FLUSH || defined(__DOXYGEN__)
/** /**
* @brief Flush the current drawing operations to the display * @brief Flush the current drawing operations to the display
@ -559,6 +582,7 @@ typedef struct GDISPVMT {
#else #else
#define gdisp_lld_init(g) gvmt(g)->init(g) #define gdisp_lld_init(g) gvmt(g)->init(g)
#define gdisp_lld_deinit(g) gvmt(g)->deinit(g)
#define gdisp_lld_flush(g) gvmt(g)->flush(g) #define gdisp_lld_flush(g) gvmt(g)->flush(g)
#define gdisp_lld_write_start(g) gvmt(g)->writestart(g) #define gdisp_lld_write_start(g) gvmt(g)->writestart(g)
#define gdisp_lld_write_pos(g) gvmt(g)->writepos(g) #define gdisp_lld_write_pos(g) gvmt(g)->writepos(g)
@ -594,12 +618,18 @@ typedef struct GDISPVMT {
// Routines needed by the general driver VMT // Routines needed by the general driver VMT
bool_t _gdispInitDriver(GDriver *g, int driverinstance, int systeminstance); bool_t _gdispInitDriver(GDriver *g, int driverinstance, int systeminstance);
void _gdispDeinitDriver(GDriver *g); void _gdispPostInitDriver(GDriver *g);
void _gdispDeInitDriver(GDriver *g);
// Build the VMT // Build the VMT
const GDISPVMT const GDISP_DRIVER_VMT[1] = {{ const GDISPVMT const GDISP_DRIVER_VMT[1] = {{
{ GDRIVER_TYPE_DISPLAY, 0, sizeof(GDisplay), _gdispInitDriver, _gdispDeinitDriver }, { GDRIVER_TYPE_DISPLAY, 0, sizeof(GDisplay), _gdispInitDriver, _gdispPostInitDriver, _gdispDeInitDriver },
gdisp_lld_init, gdisp_lld_init,
#if GDISP_HARDWARE_DEINIT
gdisp_lld_deinit,
#else
0,
#endif
#if GDISP_HARDWARE_STREAM_WRITE #if GDISP_HARDWARE_STREAM_WRITE
gdisp_lld_write_start, gdisp_lld_write_start,
#if GDISP_HARDWARE_STREAM_POS #if GDISP_HARDWARE_STREAM_POS

View File

@ -55,10 +55,12 @@ GDisplay *GDISP;
#define MUTEX_INIT(g) gfxMutexInit(&(g)->mutex) #define MUTEX_INIT(g) gfxMutexInit(&(g)->mutex)
#define MUTEX_ENTER(g) gfxMutexEnter(&(g)->mutex) #define MUTEX_ENTER(g) gfxMutexEnter(&(g)->mutex)
#define MUTEX_EXIT(g) gfxMutexExit(&(g)->mutex) #define MUTEX_EXIT(g) gfxMutexExit(&(g)->mutex)
#define MUTEX_DEINIT(g) gfxMutexDestroy(&(g)->mutex)
#else #else
#define MUTEX_INIT(g) #define MUTEX_INIT(g)
#define MUTEX_ENTER(g) #define MUTEX_ENTER(g)
#define MUTEX_EXIT(g) #define MUTEX_EXIT(g)
#define MUTEX_DEINIT(g)
#endif #endif
#define NEED_CLIPPING (GDISP_HARDWARE_CLIP != TRUE && (GDISP_NEED_VALIDATION || GDISP_NEED_CLIP)) #define NEED_CLIPPING (GDISP_HARDWARE_CLIP != TRUE && (GDISP_NEED_VALIDATION || GDISP_NEED_CLIP))
@ -564,18 +566,68 @@ static void line_clip(GDisplay *g) {
void _gdispInit(void) void _gdispInit(void)
{ {
// Both GDISP_CONTROLLER_LIST and GDISP_CONTROLLER_DISPLAYS are defined - create the required numbers of each controller
#if defined(GDISP_CONTROLLER_LIST) && defined(GDISP_CONTROLLER_DISPLAYS)
{
int i, cnt;
extern GDriverVMTList GDISP_CONTROLLER_LIST;
static const struct GDriverVMT const * dclist[GDISP_TOTAL_CONTROLLERS] = {GDISP_CONTROLLER_LIST};
static const unsigned dnlist[GDISP_TOTAL_CONTROLLERS] = {GDISP_CONTROLLER_DISPLAYS};
for(i = 0; i < GDISP_TOTAL_CONTROLLERS; i++) {
for(cnt = dnlist[i]; cnt; cnt--)
gdriverRegister(dclist[i]);
}
}
// Only GDISP_CONTROLLER_LIST is defined - create one of each controller
#elif defined(GDISP_CONTROLLER_LIST)
{
int i;
extern GDriverVMTList GDISP_CONTROLLER_LIST;
static const struct GDriverVMT const * dclist[GDISP_TOTAL_CONTROLLERS] = {GDISP_CONTROLLER_LIST};
for(i = 0; i < GDISP_TOTAL_CONTROLLERS; i++)
gdriverRegister(dclist[i]);
}
// Only GDISP_TOTAL_DISPLAYS is defined - create the required number of the one controller
#elif GDISP_TOTAL_DISPLAYS > 1
{
int cnt;
extern GDriverVMTList GDISPVMT_OnlyOne;
for(cnt = 0; cnt < GDISP_TOTAL_DISPLAYS; cnt++)
gdriverRegister(GDISPVMT_OnlyOne);
}
// One and only one display
#else
{
extern GDriverVMTList GDISPVMT_OnlyOne;
gdriverRegister(GDISPVMT_OnlyOne);
}
#endif
// Re-clear the display after the timeout if we added the logo // Re-clear the display after the timeout if we added the logo
#if GDISP_STARTUP_LOGO_TIMEOUT > 0 #if GDISP_STARTUP_LOGO_TIMEOUT > 0
GDisplay *g; {
GDisplay *g;
gfxSleepMilliseconds(GDISP_STARTUP_LOGO_TIMEOUT); gfxSleepMilliseconds(GDISP_STARTUP_LOGO_TIMEOUT);
initDone = TRUE;
for(g = (GDisplay *)gdriverGetNext(GDRIVER_TYPE_DISPLAY, 0); g; g = (GDisplay *)gdriverGetNext(GDRIVER_TYPE_DISPLAY, (GDriver *)g)) { for(g = (GDisplay *)gdriverGetNext(GDRIVER_TYPE_DISPLAY, 0); g; g = (GDisplay *)gdriverGetNext(GDRIVER_TYPE_DISPLAY, (GDriver *)g)) {
gdispGClear(g, GDISP_STARTUP_COLOR); gdispGClear(g, GDISP_STARTUP_COLOR);
#if GDISP_HARDWARE_FLUSH #if GDISP_HARDWARE_FLUSH
gdispGFlush(g); gdispGFlush(g);
#endif #endif
}
initDone = TRUE;
} }
#endif #endif
@ -605,22 +657,32 @@ bool_t _gdispInitDriver(GDriver *g, int driverinstance, int systeminstance) {
MUTEX_ENTER(gd); MUTEX_ENTER(gd);
ret = gdisp_lld_init(gd); ret = gdisp_lld_init(gd);
MUTEX_EXIT(gd); MUTEX_EXIT(gd);
if (!ret) return FALSE; return ret;
// Set orientation, clip, blankscreen, startup logo and then flush #undef gd
}
void _gdispPostInitDriver(GDriver *g) {
#define gd ((GDisplay *)g)
// Set orientation, clip
#if defined(GDISP_DEFAULT_ORIENTATION) && GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL #if defined(GDISP_DEFAULT_ORIENTATION) && GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
gdispGControl(gd, GDISP_CONTROL_ORIENTATION, (void *)GDISP_DEFAULT_ORIENTATION); gdispGControl(gd, GDISP_CONTROL_ORIENTATION, (void *)GDISP_DEFAULT_ORIENTATION);
#endif #endif
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
gdispGSetClip(gd, 0, 0, gd->g.Width, gd->g.Height); gdispGSetClip(gd, 0, 0, gd->g.Width, gd->g.Height);
#endif #endif
// Clear the Screen
gdispGClear(gd, GDISP_STARTUP_COLOR); gdispGClear(gd, GDISP_STARTUP_COLOR);
// Display the startup logo if this is a static initialised display
#if GDISP_STARTUP_LOGO_TIMEOUT > 0 #if GDISP_STARTUP_LOGO_TIMEOUT > 0
if (!initDone) if (!initDone)
StartupLogoDisplay(gd); StartupLogoDisplay(gd);
#endif #endif
// Flush
#if GDISP_HARDWARE_FLUSH #if GDISP_HARDWARE_FLUSH
gdispGFlush(gd); gdispGFlush(gd);
#endif #endif
@ -629,14 +691,28 @@ bool_t _gdispInitDriver(GDriver *g, int driverinstance, int systeminstance) {
if (!GDISP) if (!GDISP)
GDISP = gd; GDISP = gd;
return TRUE;
#undef gd #undef gd
} }
void _gdispDeinitDriver(GDriver *g) { void _gdispDeInitDriver(GDriver *g) {
(void) g; #define gd ((GDisplay *)g)
// For now do nothing
if (GDISP == gd)
GDISP = (GDisplay *)gdriverGetInstance(GDRIVER_TYPE_DISPLAY, 0);
#if GDISP_HARDWARE_DEINIT
#if GDISP_HARDWARE_DEINIT == HARDWARE_AUTODETECT
if (gvmt(gd)->deinit)
#endif
{
MUTEX_ENTER(gd);
gdisp_lld_deinit(gd);
MUTEX_EXIT(gd);
}
#endif
MUTEX_DEINIT(gd);
#undef gd
} }
GDisplay *gdispGetDisplay(unsigned display) { GDisplay *gdispGetDisplay(unsigned display) {

View File

@ -14,51 +14,8 @@
// Define the tables to hold the driver instances. // Define the tables to hold the driver instances.
static GDriver *dhead; static GDriver *dhead;
// Definition that allows getting addresses of structures
typedef const struct GDriverVMT const VMT_EL[1];
// The system initialization. // The system initialization.
void _gdriverInit(void) { void _gdriverInit(void) {
#if GFX_USE_GDISP
{
// Both GDISP_CONTROLLER_LIST and GDISP_CONTROLLER_DISPLAYS are defined - create the required numbers of each controller
#if defined(GDISP_CONTROLLER_LIST) && defined(GDISP_CONTROLLER_DISPLAYS)
int i, cnt;
extern VMT_EL GDISP_CONTROLLER_LIST;
static const struct GDriverVMT const * dclist[GDISP_TOTAL_CONTROLLERS] = {GDISP_CONTROLLER_LIST};
static const unsigned dnlist[GDISP_TOTAL_CONTROLLERS] = {GDISP_CONTROLLER_DISPLAYS};
for(i = 0; i < GDISP_TOTAL_CONTROLLERS; i++) {
for(cnt = dnlist[i]; cnt; cnt--)
gdriverRegister(dclist[i]);
}
// Only GDISP_CONTROLLER_LIST is defined - create one of each controller
#elif defined(GDISP_CONTROLLER_LIST)
int i;
extern VMT_EL GDISP_CONTROLLER_LIST;
static const struct GDriverVMT const * dclist[GDISP_TOTAL_CONTROLLERS] = {GDISP_CONTROLLER_LIST};
for(i = 0; i < GDISP_TOTAL_CONTROLLERS; i++)
gdriverRegister(dclist[i]);
// Only GDISP_TOTAL_DISPLAYS is defined - create the required number of the one controller
#elif GDISP_TOTAL_DISPLAYS > 1
int cnt;
extern VMT_EL GDISPVMT_OnlyOne;
for(cnt = 0; cnt < GDISP_TOTAL_DISPLAYS; cnt++)
gdriverRegister(GDISPVMT_OnlyOne);
// One and only one display
#else
extern VMT_EL GDISPVMT_OnlyOne;
gdriverRegister(GDISPVMT_OnlyOne);
#endif
}
#endif
// Drivers not loaded yet // Drivers not loaded yet
// GINPUT_NEED_MOUSE // GINPUT_NEED_MOUSE
@ -107,6 +64,10 @@ GDriver *gdriverRegister(const GDriverVMT *vmt) {
else else
dhead = pd; dhead = pd;
// Do the post init
if (vmt->postinit)
vmt->postinit(pd);
return pd; return pd;
} }

View File

@ -67,12 +67,27 @@ typedef struct GDriverVMT {
uint16_t type; // @< What type of driver this is uint16_t type; // @< What type of driver this is
uint16_t flags; // @< Flags for the driver. Meaning is specific to each driver type. uint16_t flags; // @< Flags for the driver. Meaning is specific to each driver type.
uint32_t objsize; // @< How big the runtime driver structure is uint32_t objsize; // @< How big the runtime driver structure is
bool_t (*init)(GDriver *driver, int driverinstance, int systeminstance); // @< Initialise the driver. bool_t (*init)(GDriver *driver, int driverinstance, int systeminstance); // @< Initialise the driver. Returns TRUE if OK.
// driverinstance is the instance 0..n of this driver. // driverinstance is the instance 0..n of this driver.
// systeminstance is the instance 0..n of this type of device. // systeminstance is the instance 0..n of this type of device.
void (*postinit)(GDriver *driver); // @< Called once the driver is registered.
void (*deinit)(GDriver *driver); // @< De-initialise the driver void (*deinit)(GDriver *driver); // @< De-initialise the driver
} GDriverVMT; } GDriverVMT;
/**
* @brief A definition that allows getting addresses of GDriverVMT structures to put into a list.
* @note eg. <code>
* const MyDriverVMTtype a[1] = {{...}};
* const MyDriverVMTtype b[1] = {{...}};
* ...
* #define DRIVER_LIST a, b
* extern GDriverVMTList DRIVER_LIST; // Now treated as single element arrays of GDriverVMT
* const GDriverVMT const * mylist = { DRIVER_LIST };
* </code>
*
*/
typedef const struct GDriverVMT const GDriverVMTList[1];
/*===========================================================================*/ /*===========================================================================*/
/* External declarations. */ /* External declarations. */
/*===========================================================================*/ /*===========================================================================*/