mirror of
https://github.com/VincentWei/MiniGUI.git
synced 2026-03-25 01:12:49 +08:00
new function: concurrentTask_Do
This commit is contained in:
@@ -56,6 +56,9 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#ifdef _MGRM_PROCESSES
|
||||
|
||||
#include "minigui.h"
|
||||
#include "constants.h"
|
||||
#include "newgal.h"
|
||||
@@ -63,6 +66,8 @@
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
#include "concurrent-tasks.h"
|
||||
|
||||
typedef void (*task_proc)(void* context, int loop_idx);
|
||||
|
||||
typedef struct _ConcurrentTasksInfo {
|
||||
@@ -71,9 +76,9 @@ typedef struct _ConcurrentTasksInfo {
|
||||
sem_t sem_lock;
|
||||
sem_t sem_sync;
|
||||
|
||||
int nr_loops;
|
||||
task_proc proc;
|
||||
void* ctxt;
|
||||
int nr_loops;
|
||||
CCTaskProc proc;
|
||||
void* ctxt;
|
||||
} ConcurrentTasksInfo;
|
||||
|
||||
static ConcurrentTasksInfo *cctasks_info;
|
||||
@@ -128,7 +133,7 @@ static void* cc_task_entry (void* data)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void split_rect (GAL_Rect* rcs, const GAL_Rect* rc, int count)
|
||||
int concurrentTasks_SplitRect (GAL_Rect* rcs, const GAL_Rect* rc, int count)
|
||||
{
|
||||
if (count == 1) {
|
||||
rcs[0] = *rc;
|
||||
@@ -151,63 +156,76 @@ static void split_rect (GAL_Rect* rcs, const GAL_Rect* rc, int count)
|
||||
rcs[0].h = rc->h >> 2;
|
||||
|
||||
rcs[1].x = rc->x;
|
||||
rcs[1].y = rcs[0].y+ rcs[0].h;
|
||||
rcs[1].y = rcs[0].y + rcs[0].h;
|
||||
rcs[1].w = rc->w;
|
||||
rcs[1].h = rc->h >> 2;
|
||||
|
||||
rcs[2].x = rc->x;
|
||||
rcs[2].y = rcs[1].y+ rcs[1].h;
|
||||
rcs[2].y = rcs[1].y + rcs[1].h;
|
||||
rcs[2].w = rc->w;
|
||||
rcs[2].h = rc->h >> 2;
|
||||
|
||||
rcs[3].x = rc->x;
|
||||
rcs[3].y = rcs[2].y+ rcs[2].h;
|
||||
rcs[3].y = rcs[2].y + rcs[2].h;
|
||||
rcs[3].w = rc->w;
|
||||
rcs[3].h = rc->h - rcs[0].h - rcs[1].h - rcs[2].h;
|
||||
rcs[3].h = rc->h - rcs[0].h * 3;
|
||||
}
|
||||
else if (count == 8) {
|
||||
rcs[0].x = rc->x;
|
||||
rcs[0].y = rc->y;
|
||||
rcs[0].w = rc->w;
|
||||
rcs[0].h = rc->h >> 3;
|
||||
|
||||
rcs[1].x = rc->x;
|
||||
rcs[1].y = rcs[0].y + rcs[0].h;
|
||||
rcs[1].w = rc->w;
|
||||
rcs[1].h = rc->h >> 3;
|
||||
|
||||
rcs[2].x = rc->x;
|
||||
rcs[2].y = rcs[1].y + rcs[1].h;
|
||||
rcs[2].w = rc->w;
|
||||
rcs[2].h = rc->h >> 3;
|
||||
|
||||
rcs[3].x = rc->x;
|
||||
rcs[3].y = rcs[2].y + rcs[2].h;
|
||||
rcs[3].w = rc->w;
|
||||
rcs[3].h = rc->h >> 3;
|
||||
|
||||
rcs[4].x = rc->x;
|
||||
rcs[4].y = rcs[3].y + rcs[3].h;
|
||||
rcs[4].w = rc->w;
|
||||
rcs[4].h = rc->h >> 3;
|
||||
|
||||
rcs[5].x = rc->x;
|
||||
rcs[5].y = rcs[4].y + rcs[4].h;
|
||||
rcs[5].w = rc->w;
|
||||
rcs[5].h = rc->h >> 3;
|
||||
|
||||
rcs[6].x = rc->x;
|
||||
rcs[6].y = rcs[5].y + rcs[5].h;
|
||||
rcs[6].w = rc->w;
|
||||
rcs[6].h = rc->h >> 3;
|
||||
|
||||
rcs[7].x = rc->x;
|
||||
rcs[7].y = rcs[6].y + rcs[6].h;
|
||||
rcs[7].w = rc->w;
|
||||
rcs[7].h = rc->h - rcs[0].h * 7;
|
||||
}
|
||||
else {
|
||||
assert (0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct _ContextBlit {
|
||||
GAL_Surface *src;
|
||||
GAL_Surface *dst;
|
||||
|
||||
GAL_blit real_blit;
|
||||
|
||||
GAL_Rect src_rects [_MGNR_CONCURRENT_TASKS + 1];
|
||||
GAL_Rect dst_rects [_MGNR_CONCURRENT_TASKS + 1];
|
||||
} ContextBlit;
|
||||
|
||||
static void blit_proc (void* context, int loop_idx)
|
||||
{
|
||||
ContextBlit *ctxt = context;
|
||||
|
||||
if (ctxt->src_rects[loop_idx].h > 0) {
|
||||
ctxt->real_blit (ctxt->src, ctxt->src_rects + loop_idx,
|
||||
ctxt->dst, ctxt->dst_rects + loop_idx);
|
||||
}
|
||||
}
|
||||
|
||||
int concurrentTasks_Blit (GAL_blit real_blit,
|
||||
struct GAL_Surface *src, GAL_Rect *srcrect,
|
||||
struct GAL_Surface *dst, GAL_Rect *dstrect)
|
||||
int concurrentTasks_Do (void* context, CCTaskProc proc)
|
||||
{
|
||||
int i;
|
||||
ContextBlit ctxt;
|
||||
|
||||
ctxt.src = src;
|
||||
ctxt.dst = dst;
|
||||
ctxt.real_blit = real_blit;
|
||||
|
||||
split_rect (ctxt.src_rects, srcrect, _MGNR_CONCURRENT_TASKS + 1);
|
||||
split_rect (ctxt.dst_rects, dstrect, _MGNR_CONCURRENT_TASKS + 1);
|
||||
|
||||
if (_MGNR_CONCURRENT_TASKS > 0) {
|
||||
cctasks_info->nr_loops = 1; // reserve 0 for the current thread
|
||||
cctasks_info->proc = blit_proc;
|
||||
cctasks_info->ctxt = &ctxt;
|
||||
cctasks_info->proc = proc;
|
||||
cctasks_info->ctxt = context;
|
||||
}
|
||||
|
||||
// wake up the concurrent task threads
|
||||
@@ -215,7 +233,7 @@ int concurrentTasks_Blit (GAL_blit real_blit,
|
||||
sem_post (&cctasks_info->sem_loop);
|
||||
}
|
||||
|
||||
blit_proc (&ctxt, 0);
|
||||
proc (context, 0);
|
||||
|
||||
// wait for finish of concurrent task threads
|
||||
for (i = 0; i < _MGNR_CONCURRENT_TASKS; i++) {
|
||||
@@ -284,7 +302,7 @@ int concurrentTasks_Term (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (_MGNR_CONCURRENT_TASKS <= 0)
|
||||
if (_MGNR_CONCURRENT_TASKS <= 0 && cctasks_info == NULL)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < _MGNR_CONCURRENT_TASKS; i++) {
|
||||
@@ -302,3 +320,5 @@ int concurrentTasks_Term (void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* _MGRM_PROCESSES */
|
||||
|
||||
|
||||
@@ -58,11 +58,12 @@
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef void (*CCTaskProc)(void* context, int loop_idx);
|
||||
|
||||
int concurrentTasks_Init (void);
|
||||
int concurrentTasks_Term (void);
|
||||
int concurrentTasks_Blit (GAL_blit real_blit,
|
||||
struct GAL_Surface *src, GAL_Rect *srcrect,
|
||||
struct GAL_Surface *dst, GAL_Rect *dstrect);
|
||||
int concurrentTasks_SplitRect (GAL_Rect* rcs, const GAL_Rect* rc, int count);
|
||||
int concurrentTasks_Do (void* context, CCTaskProc proc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -765,10 +765,6 @@ static GAL_Surface *PCXVFB_SetVideoMode (_THIS, GAL_Surface *current,
|
||||
this->hidden->shadow_screen = NULL;
|
||||
}
|
||||
|
||||
if (this->hidden->real_screen) {
|
||||
shadowScreen_InitUpdateThreads(this);
|
||||
}
|
||||
|
||||
/* We're done */
|
||||
return current;
|
||||
}
|
||||
@@ -832,7 +828,6 @@ static void PCXVFB_VideoQuit (_THIS)
|
||||
/* Since 5.0.0 */
|
||||
if (this->hidden->real_screen) {
|
||||
GAL_FreeSurface (this->hidden->real_screen);
|
||||
shadowScreen_TermUpdateThreads(this);
|
||||
}
|
||||
|
||||
#ifdef WIN32 // windows
|
||||
|
||||
@@ -230,18 +230,6 @@ void shadowScreen_UpdateRects (_THIS, int numrects, GAL_Rect *rects)
|
||||
this->hidden->dirty_rc = bound;
|
||||
}
|
||||
|
||||
#if _MGNR_UPDATE_THREADS <= 0
|
||||
|
||||
int shadowScreen_InitUpdateThreads (_THIS)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int shadowScreen_TermUpdateThreads (_THIS)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Blit dirty content from shadow surface to ultimate surface */
|
||||
int shadowScreen_BlitToReal (_THIS)
|
||||
{
|
||||
@@ -297,261 +285,3 @@ int shadowScreen_BlitToReal (_THIS)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* _MGNR_UPDATE_THREADS <= 0 */
|
||||
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
static struct UpdateThreadsInfo {
|
||||
GAL_VideoDevice *device;
|
||||
sem_t sem_loop;
|
||||
sem_t sem_lock;
|
||||
sem_t sem_sync;
|
||||
pthread_t pths[_MGNR_UPDATE_THREADS];
|
||||
|
||||
int nr_loops;
|
||||
RECT bound;
|
||||
} cuth_info;
|
||||
|
||||
static inline void copy_lines (GAL_Surface* src_surf, GAL_Surface* dst_surf,
|
||||
const RECT *rc, int idx)
|
||||
{
|
||||
int y, h = RECTHP (rc);
|
||||
uint8_t *src, *dst;
|
||||
size_t count = src_surf->format->BytesPerPixel * RECTWP (rc);
|
||||
|
||||
if (h <= 0 || count == 0)
|
||||
return;
|
||||
|
||||
src = src_surf->pixels + src_surf->pixels_off;
|
||||
src += src_surf->pitch * (rc->top + idx);
|
||||
src += src_surf->format->BytesPerPixel * rc->left;
|
||||
|
||||
dst = dst_surf->pixels + dst_surf->pixels_off;
|
||||
dst += dst_surf->pitch * (rc->top + idx);
|
||||
dst += dst_surf->format->BytesPerPixel * rc->left;
|
||||
|
||||
for (y = idx; y < h; y += (_MGNR_UPDATE_THREADS + 1)) {
|
||||
memcpy (dst, src, count);
|
||||
src += src_surf->pitch * (_MGNR_UPDATE_THREADS + 1);
|
||||
dst += dst_surf->pitch * (_MGNR_UPDATE_THREADS + 1);
|
||||
}
|
||||
}
|
||||
|
||||
static inline int my_sem_wait (sem_t *sem)
|
||||
{
|
||||
try_again:
|
||||
if (sem_wait (sem) < 0) {
|
||||
if (errno == EINTR)
|
||||
goto try_again;
|
||||
else {
|
||||
_WRN_PRINTF ("NEWGAL>DBLBUFF: failed sem_wait: %s\n", strerror (errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void* task_do_update (void* data)
|
||||
{
|
||||
int task_idx = (int)(intptr_t)data;
|
||||
|
||||
if (pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL))
|
||||
return NULL;
|
||||
|
||||
do {
|
||||
int loop_idx;
|
||||
|
||||
if (my_sem_wait (&cuth_info.sem_loop)) {
|
||||
_ERR_PRINTF ("Update thread %d failed on sem_wait\n", task_idx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
my_sem_wait (&cuth_info.sem_lock);
|
||||
loop_idx = cuth_info.nr_loops++;
|
||||
sem_post (&cuth_info.sem_lock);
|
||||
|
||||
pthread_testcancel ();
|
||||
|
||||
copy_lines (cuth_info.device->hidden->shadow_screen,
|
||||
cuth_info.device->hidden->real_screen,
|
||||
&cuth_info.bound, loop_idx);
|
||||
|
||||
if (sem_post (&cuth_info.sem_sync)) {
|
||||
_ERR_PRINTF ("Update thread %d failed on sem_post\n", task_idx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pthread_testcancel ();
|
||||
|
||||
} while (1);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int shadowScreen_InitUpdateThreads (_THIS)
|
||||
{
|
||||
int i;
|
||||
|
||||
CHECK_VERSION_RETVAL (this, -1);
|
||||
|
||||
assert (this->real_screen && this->shadow_screen);
|
||||
|
||||
if (sem_init (&cuth_info.sem_loop, 0, 0)) {
|
||||
_ERR_PRINTF ("NEWGAL>DBLBUFF: failed to create loop semaphore: %s\n",
|
||||
strerror (errno));
|
||||
goto failed_sem_update;
|
||||
}
|
||||
|
||||
if (sem_init (&cuth_info.sem_sync, 0, 0)) {
|
||||
_ERR_PRINTF ("NEWGAL>DBLBUFF: failed to create sync semaphore: %s\n",
|
||||
strerror (errno));
|
||||
goto failed_sem_sync;
|
||||
}
|
||||
|
||||
if (sem_init (&cuth_info.sem_lock, 0, 1)) {
|
||||
_ERR_PRINTF ("NEWGAL>DBLBUFF: failed to create lock semaphore: %s\n",
|
||||
strerror (errno));
|
||||
goto failed_sem_lock;
|
||||
}
|
||||
|
||||
for (i = 0; i < _MGNR_UPDATE_THREADS; i++) {
|
||||
if (pthread_create (cuth_info.pths + i, NULL, task_do_update,
|
||||
(void*)(intptr_t)(i + 1))) {
|
||||
_ERR_PRINTF ("NEWGAL>DBLBUFF: failed to create update thread (%d): %s\n",
|
||||
i, strerror (errno));
|
||||
goto failed_threads;
|
||||
}
|
||||
}
|
||||
|
||||
cuth_info.device = this;
|
||||
return 0;
|
||||
|
||||
failed_threads:
|
||||
sem_destroy (&cuth_info.sem_lock);
|
||||
|
||||
failed_sem_lock:
|
||||
sem_destroy (&cuth_info.sem_sync);
|
||||
|
||||
failed_sem_sync:
|
||||
sem_destroy (&cuth_info.sem_loop);
|
||||
|
||||
failed_sem_update:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int shadowScreen_TermUpdateThreads (_THIS)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < _MGNR_UPDATE_THREADS; i++) {
|
||||
_WRN_PRINTF ("Cancelling update thread: %d\n", i);
|
||||
/* send cancel request */
|
||||
pthread_cancel (cuth_info.pths [i]);
|
||||
pthread_join (cuth_info.pths [i], NULL);
|
||||
}
|
||||
|
||||
sem_destroy (&cuth_info.sem_sync);
|
||||
sem_destroy (&cuth_info.sem_loop);
|
||||
sem_destroy (&cuth_info.sem_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void split_rect (RECT* rcs, const RECT* rc)
|
||||
{
|
||||
if (_MGNR_UPDATE_THREADS == 1) {
|
||||
rcs[0] = *rc;
|
||||
}
|
||||
else if (_MGNR_UPDATE_THREADS == 2) {
|
||||
rcs[0] = *rc;
|
||||
rcs[0].bottom -= RECTHP (rc) >> 1;
|
||||
|
||||
rcs[1] = *rc;
|
||||
rcs[1].top = rcs[0].bottom;
|
||||
}
|
||||
else if (_MGNR_UPDATE_THREADS == 4) {
|
||||
rcs[0] = *rc;
|
||||
rcs[0].right -= RECTWP (rc) >> 1;
|
||||
rcs[0].bottom -= RECTHP (rc) >> 1;
|
||||
|
||||
rcs[1].top = rcs[0].top;
|
||||
rcs[1].left = rcs[0].right;
|
||||
rcs[1].right = rc->right;
|
||||
rcs[1].bottom = rcs[0].bottom;
|
||||
|
||||
rcs[2].top = rcs[0].bottom;
|
||||
rcs[2].left = rcs[0].left;
|
||||
rcs[2].right = rcs[0].right;
|
||||
rcs[2].bottom = rc->bottom;
|
||||
|
||||
rcs[3].top = rcs[0].bottom;
|
||||
rcs[3].left = rcs[2].right;
|
||||
rcs[3].right = rc->right;
|
||||
rcs[3].bottom = rc->bottom;
|
||||
}
|
||||
else {
|
||||
assert (0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int shadowScreen_BlitToReal (_THIS)
|
||||
{
|
||||
int i, value;
|
||||
|
||||
CHECK_VERSION_RETVAL (this, -1);
|
||||
|
||||
cuth_info.nr_loops = 1; // reserve 0 for the current thread
|
||||
cuth_info.bound = this->hidden->dirty_rc;
|
||||
|
||||
// wake up the concurrent update threads
|
||||
for (i = 0; i < _MGNR_UPDATE_THREADS; i++) {
|
||||
sem_post (&cuth_info.sem_loop);
|
||||
}
|
||||
|
||||
copy_lines (cuth_info.device->hidden->shadow_screen,
|
||||
cuth_info.device->hidden->real_screen,
|
||||
&cuth_info.bound, 0);
|
||||
|
||||
// wait for finish of concurrent update threads
|
||||
for (i = 0; i < _MGNR_UPDATE_THREADS; i++) {
|
||||
if (my_sem_wait (&cuth_info.sem_sync) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef _MGSCHEMA_COMPOSITING
|
||||
if (this->hidden->cursor) {
|
||||
RECT csr_rc, eff_rc;
|
||||
csr_rc.left = boxleft (this);
|
||||
csr_rc.top = boxtop (this);
|
||||
csr_rc.right = csr_rc.left + CURSORWIDTH;
|
||||
csr_rc.bottom = csr_rc.top + CURSORHEIGHT;
|
||||
|
||||
if (IntersectRect (&eff_rc, &csr_rc, &cuth_info.bound)) {
|
||||
GAL_Rect src_rect, dst_rect;
|
||||
|
||||
src_rect.x = eff_rc.left - csr_rc.left;
|
||||
src_rect.y = eff_rc.top - csr_rc.top;
|
||||
src_rect.w = RECTW (eff_rc);
|
||||
src_rect.h = RECTH (eff_rc);
|
||||
|
||||
dst_rect.x = eff_rc.left;
|
||||
dst_rect.y = eff_rc.top;
|
||||
dst_rect.w = src_rect.w;
|
||||
dst_rect.h = src_rect.h;
|
||||
GAL_SetupBlitting (this->hidden->cursor,
|
||||
this->hidden->real_screen, 0);
|
||||
GAL_BlitSurface (this->hidden->cursor, &src_rect,
|
||||
this->hidden->real_screen, &dst_rect);
|
||||
GAL_CleanupBlitting (this->hidden->cursor,
|
||||
this->hidden->real_screen);
|
||||
}
|
||||
}
|
||||
#endif /* _MGSCHEMA_COMPOSITING */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* _MGNR_UPDATE_THREADS > 0 */
|
||||
|
||||
@@ -64,8 +64,6 @@ extern "C" {
|
||||
# define _THIS GAL_VideoDevice *this
|
||||
#endif
|
||||
|
||||
int shadowScreen_InitUpdateThreads (_THIS);
|
||||
int shadowScreen_TermUpdateThreads (_THIS);
|
||||
int shadowScreen_SetCursor (_THIS, GAL_Surface *surface, int hot_x, int hot_y);
|
||||
int shadowScreen_MoveCursor (_THIS, int x, int y);
|
||||
void shadowScreen_UpdateRects (_THIS, int numrects, GAL_Rect *rects);
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "common.h"
|
||||
#include "newgal.h"
|
||||
#include "blit.h"
|
||||
#include "concurrent-tasks.h"
|
||||
|
||||
#define DEFINE_COPY_ROW(name, type) \
|
||||
static void name(type *src, int src_w, type *dst, int dst_w) \
|
||||
@@ -377,6 +378,31 @@ int GAL_CleanupStretchBlit (GAL_Surface *src, GAL_Surface *dst)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef _MGRM_PROCESSES
|
||||
typedef struct _ContextStretch {
|
||||
pixman_op_t op;
|
||||
pixman_image_t *src_img;
|
||||
pixman_image_t *msk_img;
|
||||
pixman_image_t *dst_img;
|
||||
|
||||
GAL_Rect dst_rects [_MGNR_CONCURRENT_TASKS + 1];
|
||||
} ContextStretch;
|
||||
|
||||
static void stretch_proc (void* context, int loop_idx)
|
||||
{
|
||||
ContextStretch *ctxt = context;
|
||||
|
||||
if (ctxt->dst_rects[loop_idx].h > 0) {
|
||||
GAL_Rect* dstrect = ctxt->dst_rects + loop_idx;
|
||||
pixman_image_composite32 (ctxt->op, ctxt->src_img, ctxt->msk_img, ctxt->dst_img,
|
||||
dstrect->x, dstrect->y,
|
||||
0, 0,
|
||||
dstrect->x, dstrect->y,
|
||||
dstrect->w, dstrect->h);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int GAL_StretchBlt (GAL_Surface *src, GAL_Rect *srcrect,
|
||||
GAL_Surface *dst, GAL_Rect *dstrect,
|
||||
const STRETCH_EXTRA_INFO* sei, DWORD ops)
|
||||
@@ -409,11 +435,27 @@ int GAL_StretchBlt (GAL_Surface *src, GAL_Rect *srcrect,
|
||||
dst->clip_rect.x, dst->clip_rect.y, dst->clip_rect.w, dst->clip_rect.h);
|
||||
pixman_image_set_clip_region32 (dst_img, &clip_region);
|
||||
|
||||
#ifdef _MGRM_PROCESSES
|
||||
// we use concurrent tasks only under MiniGUI-Processes.
|
||||
{
|
||||
ContextStretch ctxt;
|
||||
|
||||
ctxt.op = op;
|
||||
ctxt.src_img = src_img;
|
||||
ctxt.msk_img = msk_img;
|
||||
ctxt.dst_img = dst_img;
|
||||
|
||||
concurrentTasks_SplitRect (ctxt.dst_rects, dstrect, _MGNR_CONCURRENT_TASKS + 1);
|
||||
|
||||
concurrentTasks_Do (&ctxt, stretch_proc);
|
||||
}
|
||||
#else
|
||||
pixman_image_composite32 (op, src_img, msk_img, dst_img,
|
||||
dstrect->x, dstrect->y,
|
||||
0, 0,
|
||||
dstrect->x, dstrect->y,
|
||||
dstrect->w, dstrect->h);
|
||||
#endif
|
||||
|
||||
pixman_region32_fini (&clip_region);
|
||||
return 0;
|
||||
|
||||
@@ -56,10 +56,10 @@
|
||||
#include "pixels_c.h"
|
||||
#include "memops.h"
|
||||
#include "leaks.h"
|
||||
#include "concurrent-tasks.h"
|
||||
|
||||
#ifdef _MGRM_PROCESSES
|
||||
#include <sys/mman.h> /* for munmap */
|
||||
#include "concurrent-tasks.h"
|
||||
#endif /* _MGRM_PROCESSES */
|
||||
|
||||
/* Public routines */
|
||||
@@ -494,6 +494,28 @@ static int own_overlapped_bitblit(GAL_blit real_blit, struct GAL_Surface *src, G
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _MGRM_PROCESSES
|
||||
typedef struct _ContextBlit {
|
||||
GAL_Surface *src;
|
||||
GAL_Surface *dst;
|
||||
|
||||
GAL_blit real_blit;
|
||||
|
||||
GAL_Rect src_rects [_MGNR_CONCURRENT_TASKS + 1];
|
||||
GAL_Rect dst_rects [_MGNR_CONCURRENT_TASKS + 1];
|
||||
} ContextBlit;
|
||||
|
||||
static void blit_proc (void* context, int loop_idx)
|
||||
{
|
||||
ContextBlit *ctxt = context;
|
||||
|
||||
if (ctxt->src_rects[loop_idx].h > 0) {
|
||||
ctxt->real_blit (ctxt->src, ctxt->src_rects + loop_idx,
|
||||
ctxt->dst, ctxt->dst_rects + loop_idx);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set up a blit between two surfaces -- split into three parts:
|
||||
* The upper part, GAL_UpperBlit(), performs clipping and rectangle
|
||||
@@ -541,7 +563,18 @@ int GAL_LowerBlit (GAL_Surface *src, GAL_Rect *srcrect,
|
||||
|
||||
#ifdef _MGRM_PROCESSES
|
||||
// we use concurrent tasks only under MiniGUI-Processes.
|
||||
concurrentTasks_Blit (do_blit, src, srcrect, dst, dstrect);
|
||||
{
|
||||
ContextBlit ctxt;
|
||||
|
||||
ctxt.src = src;
|
||||
ctxt.dst = dst;
|
||||
ctxt.real_blit = do_blit;
|
||||
|
||||
concurrentTasks_SplitRect (ctxt.src_rects, srcrect, _MGNR_CONCURRENT_TASKS + 1);
|
||||
concurrentTasks_SplitRect (ctxt.dst_rects, dstrect, _MGNR_CONCURRENT_TASKS + 1);
|
||||
|
||||
concurrentTasks_Do (&ctxt, blit_proc);
|
||||
}
|
||||
#else
|
||||
# ifdef MG_CONFIG_USE_OWN_OVERLAPPED_BITBLIT
|
||||
ret = own_overlapped_bitblit(do_blit, src, srcrect, dst, dstrect);
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
#include "pixels_c.h"
|
||||
#include "license.h"
|
||||
#include "debug.h"
|
||||
#include "concurrent-tasks.h"
|
||||
|
||||
/* Available video drivers */
|
||||
static VideoBootStrap *bootstrap[] = {
|
||||
@@ -288,6 +289,12 @@ int GAL_VideoInit (const char *driver_name, Uint32 flags)
|
||||
|
||||
video->info.vfmt = GAL_VideoSurface->format;
|
||||
|
||||
#ifdef _MGRM_PROCESSES
|
||||
// we use concurrent tasks only under MiniGUI-Processes.
|
||||
if (concurrentTasks_Init ())
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -1154,6 +1161,12 @@ void GAL_VideoQuit (void)
|
||||
DestroyFreeClipRectList (&__mg_free_update_region_list);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _MGRM_PROCESSES
|
||||
// we use concurrent tasks only under MiniGUI-Processes.
|
||||
concurrentTasks_Term ();
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user