diff --git a/src/newgal/commlcd/axlinux_c33l05.c b/src/newgal/commlcd/axlinux_c33l05.c index 41c31b75..feb5bb98 100644 --- a/src/newgal/commlcd/axlinux_c33l05.c +++ b/src/newgal/commlcd/axlinux_c33l05.c @@ -229,7 +229,8 @@ struct commlcd_ops __mg_commlcd_ops = { L2F50113T00_open, L2F50113T00_getscreeninfo, L2F50113T00_close, - L2F50113T00_setpalette + L2F50113T00_setpalette, + NULL }; #endif /* __TARGET_C33L05__ */ diff --git a/src/newgal/commlcd/commlcd.c b/src/newgal/commlcd/commlcd.c index cb01bc0b..32ee4d30 100644 --- a/src/newgal/commlcd/commlcd.c +++ b/src/newgal/commlcd/commlcd.c @@ -76,7 +76,60 @@ static void COMMLCD_DeleteDevice(GAL_VideoDevice *device) free (device); } -static GAL_VideoDevice *COMMLCD_CreateDevice(int devindex) +static void* task_do_update (void* data) +{ + _THIS; + this = data; + + while (1) { + pthread_mutex_lock (&this->hidden->update_lock); + if (this->hidden->dirty) { + __mg_commlcd_ops.update (&this->hidden->ditry_rect); + + SetRect (&this->hidden->ditry_rect, 0, 0, 0, 0); + this->hidden->dirty = FALSE; + } + pthread_mutex_unlock (&this->hidden->update_lock); + usleep (50*1000) /* 50 ms */ + } + + return NULL; +} + +static void COMMLCD_UpdateRects (_THIS, int numrects, GAL_Rect *rects) +{ + int i; + RECT bound; + + if (__mg_commlcd_ops.update == NULL) { + return; + } + + pthread_mutex_lock (&this->hidden->update_lock); + + bound = this->hidden->rc_dirty; + for (i = 0; i < numrects; i++) { + RECT rc; + SetRect (&rc, rects[i].x, rects[i].y, + rects[i].x + rects[i].w, rects[i].y + rects[i].h); + if (IsRectEmpty (&bound)) + bound = rc; + else + GetBoundRect (&bound, &bound, &rc); + } + + if (!IsRectEmpty (&bound)) { + if (IntersectRect (&bound, &bound, &g_rcScr)) { + this->hidden->rc_dirty = bound; + this->hidden->dirty = TRUE; + } + } + + pthread_mutex_unlock (&this->hidden->update_lock); + return; +} + +static GAL_VideoDevice *COMMLCD_CreateDevice (int devindex) { GAL_VideoDevice *device; @@ -111,6 +164,7 @@ static GAL_VideoDevice *COMMLCD_CreateDevice(int devindex) device->SetHWColorKey = NULL; device->SetHWAlpha = NULL; device->FreeHWSurface = COMMLCD_FreeHWSurface; + device->UpdateRects = COMMLCD_UpdateRects; device->free = COMMLCD_DeleteDevice; return device; @@ -175,16 +229,30 @@ static GAL_Surface *COMMLCD_SetVideoMode(_THIS, GAL_Surface *current, current->pitch = this->hidden->pitch; current->pixels = this->hidden->fb; + if (__mg_commlcd_ops.update) { + pthread_attr_t new_attr; + + pthread_attr_init (&new_attr); + pthread_attr_setdetachstate (&new_attr, PTHREAD_CREATE_DETACHED); + ret = pthread_create (&this->hidden->update_th, &new_attr, + task_do_update, this); + pthread_attr_destroy (&new_attr); + } + /* We're done */ return current; } -static void COMMLCD_VideoQuit(_THIS) +static void COMMLCD_VideoQuit (_THIS) { if (this->screen && this->screen->pixels) { this->screen->pixels = NULL; } + if (__mg_commlcd_ops.update) { + /* quit the update task */ + } + if (__mg_commlcd_ops.release) __mg_commlcd_ops.release (); @@ -194,7 +262,7 @@ static void COMMLCD_VideoQuit(_THIS) static GAL_Rect **COMMLCD_ListModes (_THIS, GAL_PixelFormat *format, Uint32 flags) { - return (GAL_Rect **) -1; + return (GAL_Rect **) -1; } /* We don't actually allow hardware surfaces other than the main one */ diff --git a/src/newgal/commlcd/commlcd.h b/src/newgal/commlcd/commlcd.h index 158458ef..1ad019fb 100644 --- a/src/newgal/commlcd/commlcd.h +++ b/src/newgal/commlcd/commlcd.h @@ -49,6 +49,11 @@ extern "C" { struct GAL_PrivateVideoData { int w, h, pitch; void *fb; + + int dirty; + RECT rc_dirty; + pthread_t update_th; + pthread_mutex_t update_lock; }; /* The pixel format defined by depth */ @@ -76,6 +81,8 @@ struct commlcd_ops { int (*release) (void); /* return value: number set, zero on error */ int (*setclut) (int firstcolor, int ncolors, GAL_Color *colors); + /* return value: number set, zero on error */ + int (*update) (const RECT* rc_dirty); }; extern struct commlcd_ops __mg_commlcd_ops; diff --git a/src/newgal/commlcd/ecos_generic.c b/src/newgal/commlcd/ecos_generic.c index 211661db..a1137ee1 100644 --- a/src/newgal/commlcd/ecos_generic.c +++ b/src/newgal/commlcd/ecos_generic.c @@ -71,6 +71,7 @@ struct commlcd_ops __mg_commlcd_ops = { a_init, a_getinfo, NULL, + NULL, NULL }; diff --git a/src/newgal/commlcd/ecos_mv6600.c b/src/newgal/commlcd/ecos_mv6600.c index c413dd0b..9b387c8c 100644 --- a/src/newgal/commlcd/ecos_mv6600.c +++ b/src/newgal/commlcd/ecos_mv6600.c @@ -89,6 +89,7 @@ struct commlcd_ops __mg_commlcd_ops = { a_init, a_getinfo, NULL, + NULL, NULL }; diff --git a/src/newgal/commlcd/extern.c b/src/newgal/commlcd/extern.c index 74785551..97be3541 100644 --- a/src/newgal/commlcd/extern.c +++ b/src/newgal/commlcd/extern.c @@ -55,14 +55,15 @@ extern int __commlcd_drv_init (void); extern int __commlcd_drv_getinfo (struct commlcd_info *li); extern int __commlcd_drv_release (void); -extern int __commlcd_drv_setclut (int firstcolor, - int ncolors, GAL_Color *colors); +extern int __commlcd_drv_setclut (int firstcolor, int ncolors, GAL_Color *colors); +extern int __commlcd_drv_update (const RECT* rc_dirty); struct commlcd_ops __mg_commlcd_ops = { __commlcd_drv_init, __commlcd_drv_getinfo, __commlcd_drv_release, - __commlcd_drv_setclut + __commlcd_drv_setclut, + __commlcd_drv_update }; #endif diff --git a/src/newgal/commlcd/ose_mx21.c b/src/newgal/commlcd/ose_mx21.c index d8ed6500..d1b3445a 100644 --- a/src/newgal/commlcd/ose_mx21.c +++ b/src/newgal/commlcd/ose_mx21.c @@ -110,6 +110,7 @@ struct commlcd_ops __mg_commlcd_ops = { a_init, a_getinfo, NULL, + NULL, NULL }; diff --git a/src/newgal/commlcd/vxworks_i386.c b/src/newgal/commlcd/vxworks_i386.c index 4c4a881a..df33d62f 100644 --- a/src/newgal/commlcd/vxworks_i386.c +++ b/src/newgal/commlcd/vxworks_i386.c @@ -112,14 +112,15 @@ static int a_setclut (int firstcolor, int ncolors, GAL_Color *colors) #endif struct lcd_ops __mg_commlcd_ops = { - a_init, - a_getinfo, - NULL, + a_init, + a_getinfo, + NULL, #ifndef _VESA_SUPPORT - a_setclut + a_setclut, #else - NULL + NULL, #endif + NULL }; #endif /* __VXWORKS__ && __TARGET_VXI386__ */ diff --git a/src/newgal/commlcd/vxworks_ppc.c b/src/newgal/commlcd/vxworks_ppc.c index d347dfbe..c849f3cd 100644 --- a/src/newgal/commlcd/vxworks_ppc.c +++ b/src/newgal/commlcd/vxworks_ppc.c @@ -99,10 +99,11 @@ static int a_release(void) } struct lcd_ops __mg_commlcd_ops = { - a_init, - a_getinfo, - a_release, - NULL + a_init, + a_getinfo, + a_release, + NULL, + NULL }; #endif /* __VXWORKS__ && __TARGET_PPC__ */ diff --git a/src/newgal/commlcd/win_generic.c b/src/newgal/commlcd/win_generic.c index f70f40bc..e2a096ec 100644 --- a/src/newgal/commlcd/win_generic.c +++ b/src/newgal/commlcd/win_generic.c @@ -63,7 +63,8 @@ struct commlcd_ops __mg_commlcd_ops = { wvfb_drv_lcd_init, wvfb_drv_lcd_getinfo, NULL, - wvfb_drv_setclut + wvfb_drv_setclut, + NULL }; #endif /* WIN32 && __TARGET_WVFB__ */