From 07274513e984f0b5544586c74508ccd16e7dcafa Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Sun, 13 Jan 2013 17:29:19 +1000 Subject: Remove EFL, since it's been released now. --- libraries/evas/src/lib/engines/common/evas_pipe.c | 1733 --------------------- 1 file changed, 1733 deletions(-) delete mode 100644 libraries/evas/src/lib/engines/common/evas_pipe.c (limited to 'libraries/evas/src/lib/engines/common/evas_pipe.c') diff --git a/libraries/evas/src/lib/engines/common/evas_pipe.c b/libraries/evas/src/lib/engines/common/evas_pipe.c deleted file mode 100644 index 66085c8..0000000 --- a/libraries/evas/src/lib/engines/common/evas_pipe.c +++ /dev/null @@ -1,1733 +0,0 @@ -// THIS IS DEPRECATED. WILL GO EVENTUALLTY. NO NEED TO SUPPORT ANYMORE - -#include "evas_common.h" -#include - -#ifdef BUILD_PIPE_RENDER - -#ifdef EVAS_FRAME_QUEUING -#define SCALECACHE -static Evas_FrameQ gframeq; // global frameQ - -static Evas_Surface * -evas_common_surface_alloc(void *surface, int x, int y, int w, int h) -{ - Evas_Surface *e_surface; - - e_surface = calloc(1, sizeof(Evas_Surface)); - e_surface->im = surface; - LKL(e_surface->im->cache_entry.ref_fq_add); - e_surface->im->cache_entry.ref_fq[0]++; - LKU(e_surface->im->cache_entry.ref_fq_add); - e_surface->x = x; - e_surface->y = y; - e_surface->w = w; - e_surface->h = h; - - return e_surface; -} - -static void -evas_common_surface_dealloc(Evas_Surface *surface) -{ - Evas_Surface *d_surface; - - while (surface) - { - d_surface = surface; - surface = (Evas_Surface *)eina_inlist_remove(EINA_INLIST_GET(surface), EINA_INLIST_GET(d_surface)); - LKL(d_surface->im->cache_entry.ref_fq_del); - d_surface->im->cache_entry.ref_fq[1]++; - LKU(d_surface->im->cache_entry.ref_fq_del); - free(d_surface); - } -} - -static void -evas_common_surface_add(Evas_Frame *frame, Evas_Surface *surface) -{ - frame->surfaces = (Evas_Surface *)eina_inlist_append(EINA_INLIST_GET(frame->surfaces), EINA_INLIST_GET(surface)); -} - -static Evas_Frame * -evas_common_frame_alloc(void) -{ - Evas_Frame *frame; - - frame = calloc(1, sizeof(Evas_Frame)); - frame->surfaces = NULL; - return frame; -} - -static void -evas_common_frame_dealloc(Evas_Frame *frame) -{ - evas_common_surface_dealloc(frame->surfaces); - free(frame); -} - -static void -evas_common_frame_add(Evas_FrameQ *frameq, Evas_Frame *frame) -{ - Evas_Frame *temp_frame; - - LKL(frameq->mutex); - while ((int)eina_inlist_count(EINA_INLIST_GET(frameq->frames)) >= frameq->frameq_sz) - { - /* wait a worker thread finish previous frame */ - eina_condition_wait(&(frameq->cond_done)); - } - frameq->frames = (Evas_Frame *) eina_inlist_append(EINA_INLIST_GET(frameq->frames), EINA_INLIST_GET(frame)); - - // this frame need not to be scheduled for flushing time - EINA_INLIST_FOREACH(EINA_INLIST_GET(frameq->frames), temp_frame) - { - if (!temp_frame->ready) - { - break; - } - } - if (temp_frame && temp_frame == frame) - frame->dont_schedule = 1; - - LKU(frameq->mutex); - - eina_condition_signal(&(frameq->cond_new)); -} - -EAPI Evas_Surface * -evas_common_frameq_new_surface(void *surface, int x, int y, int w, int h) -{ - return evas_common_surface_alloc(surface, x, y, w, h); -} - -EAPI void -evas_common_frameq_add_surface(Evas_Surface *surface) -{ - evas_common_surface_add(gframeq.cur_frame, surface); -} - -EAPI void -evas_common_frameq_set_frame_data(void *data, - void (*fn_output_redraws_next_update_push) (void *data, void *surface, int x, int y, int w, int h), - void (*fn_output_flush) (void *data), - void (*fn_output_set_priv)(void *data, void *cur, void *prev)) -{ - if (gframeq.cur_frame) - { - gframeq.cur_frame->data = data; - gframeq.cur_frame->output_redraws_next_update_push = fn_output_redraws_next_update_push; - gframeq.cur_frame->output_flush = fn_output_flush; - gframeq.cur_frame->output_set_priv = fn_output_set_priv; - } -} - -EAPI void -evas_common_frameq_prepare_frame(void) -{ - if (!gframeq.cur_frame ) - { - gframeq.cur_frame = evas_common_frame_alloc(); - } -} - -EAPI void -evas_common_frameq_ready_frame(void) -{ - if (gframeq.cur_frame) - { - evas_common_frame_add(&gframeq, gframeq.cur_frame); - gframeq.cur_frame = NULL; // create a new frame for the next frame later - } -} - - -EAPI void -evas_common_frameq_init(void) -{ - gframeq.frames = NULL; - LKI(gframeq.mutex); - eina_condition_new(&(gframeq.cond_new), &(gframeq.mutex)); - eina_condition_new(&(gframeq.cond_ready), &(gframeq.mutex)); - eina_condition_new(&(gframeq.cond_done), &(gframeq.mutex)); - gframeq.initialised = 0; // worker thread are not created yet - gframeq.frameq_sz = 1; // this value ensures the first frame can be enqueued. -} - -EAPI void -evas_common_frameq_destroy(void) -{ -#if 0 // let them destroyed indirectly with program exit - LKL(gframeq.mutex); - eina_condition_free(&(gframeq.cond_new)); - eina_condition_free(&(gframeq.cond_ready)); - eina_condition_free(&(gframeq.cond_done)); - LKU(gframeq.mutex); -#endif - LKD(gframeq.mutex); - - gframeq.frames = NULL; - gframeq.initialised = 0; -} - -EAPI void -evas_common_frameq_flush(void) -{ - if (! evas_common_frameq_enabled()) - return; - - LKL(gframeq.mutex); - while(eina_inlist_count(EINA_INLIST_GET(gframeq.frames)) > 0) - { - /* wait a worker thread finish previous frame */ - eina_condition_wait(&(gframeq.cond_done)); - } - LKU(gframeq.mutex); -} - - -EAPI void -evas_common_frameq_flush_ready(void) -{ - return; -} - -EAPI int -evas_common_frameq_get_frameq_sz(void) -{ - return gframeq.frameq_sz; -} - -EAPI int -evas_common_frameq_enabled(void) -{ - return gframeq.initialised; -} -#endif - -static RGBA_Pipe *evas_common_pipe_add(RGBA_Pipe *pipe, RGBA_Pipe_Op **op); -static void evas_common_pipe_draw_context_copy(RGBA_Draw_Context *dc, RGBA_Pipe_Op *op); -static void evas_common_pipe_op_free(RGBA_Pipe_Op *op); - -/* utils */ -static RGBA_Pipe * -evas_common_pipe_add(RGBA_Pipe *rpipe, RGBA_Pipe_Op **op) -{ - RGBA_Pipe *p; - int first_pipe = 0; - - if (!rpipe) - { - first_pipe = 1; - p = calloc(1, sizeof(RGBA_Pipe)); - if (!p) return NULL; - rpipe = (RGBA_Pipe *)eina_inlist_append(EINA_INLIST_GET(rpipe), EINA_INLIST_GET(p)); - } - p = (RGBA_Pipe *)(EINA_INLIST_GET(rpipe))->last; - if (p->op_num == PIPE_LEN) - { - p = calloc(1, sizeof(RGBA_Pipe)); - if (!p) return NULL; - rpipe = (RGBA_Pipe *)eina_inlist_append(EINA_INLIST_GET(rpipe), EINA_INLIST_GET(p)); - } - p->op_num++; - *op = &(p->op[p->op_num - 1]); - if (first_pipe) - { - /* FIXME: PTHREAD init any thread locks etc */ - } - return rpipe; -} - -static void -evas_common_pipe_draw_context_copy(RGBA_Draw_Context *dc, RGBA_Pipe_Op *op) -{ - memcpy(&(op->context), dc, sizeof(RGBA_Draw_Context)); - if (op->context.cutout.active > 0) - { - op->context.cutout.rects = malloc(sizeof(Cutout_Rect) * op->context.cutout.active); - memcpy(op->context.cutout.rects, dc->cutout.rects, sizeof(Cutout_Rect) * op->context.cutout.active); - } - else - { - op->context.cutout.rects = NULL; - } -} - -static void -evas_common_pipe_op_free(RGBA_Pipe_Op *op) -{ - evas_common_draw_context_apply_clean_cutouts(&op->context.cutout); -} - -#ifdef BUILD_PTHREAD -/* main api calls */ -static void * -evas_common_pipe_thread(void *data) -{ - Thinfo *thinfo; - -// INF("TH [..........."); - thinfo = data; - for (;;) - { - RGBA_Pipe_Thread_Info *info; - RGBA_Pipe *p; - - /* wait for start signal */ -// INF(" TH %i START...", thinfo->thread_num); - pthread_barrier_wait(&(thinfo->barrier[0])); - info = thinfo->info; -// if (info) -// { -// thinfo->info = NULL; -// INF(" TH %i GO", thinfo->thread_num); - EINA_INLIST_FOREACH(EINA_INLIST_GET(info->im->cache_entry.pipe), p) - { - int i; - - for (i = 0; i < p->op_num; i++) - { - if (p->op[i].op_func) - p->op[i].op_func(info->im, &(p->op[i]), info); - } - } - free(info); -// } -// INF(" TH %i DONE", thinfo->thread_num); - /* send finished signal */ - pthread_barrier_wait(&(thinfo->barrier[1])); - } - return NULL; -} - -#ifdef EVAS_FRAME_QUEUING -static void -evas_common_frameq_release(void *data) -{ - Evas_FrameQ *frameq; - Evas_Frameq_Thread_Info *fq_info; - Thinfo *thinfo; - - thinfo = data; - fq_info = (Evas_Frameq_Thread_Info *)(thinfo->fq_info); - frameq = fq_info->frameq; - - /* This thread may or may not own the mutex. - * But there's no way to determine the ownership of the mutex, so release it anyway - */ - LKU(frameq->mutex); -} - -static void * -evas_common_frameq_thread(void *data) -{ - Evas_FrameQ *frameq; - Evas_Frame *frame; - Evas_Surface *surface; - RGBA_Pipe *p; - Thinfo *thinfo; - Evas_Frameq_Thread_Info *fq_info; - RGBA_Pipe_Thread_Info p_info; - - thinfo = data; - fq_info = (Evas_Frameq_Thread_Info *)(thinfo->fq_info); - frameq = fq_info->frameq; - - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); - pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); - /* install thread cancelation cleanup handler */ - pthread_cleanup_push(evas_common_frameq_release, data); - - for (;;) - { - frame = NULL; - - /* 1. pick a frame to draw */ - LKL(frameq->mutex); - while(!frame) - { - EINA_INLIST_FOREACH(EINA_INLIST_GET(frameq->frames), frame) - { - if (!frame->in_process) - { - frame->in_process = 1; - break; - } - } - if (frame) - { - break; - } - pthread_testcancel(); - eina_condition_wait(&(frameq->cond_new)); - } - LKU(frameq->mutex); - - /* 2. draw selected frame */ - EINA_INLIST_FOREACH(EINA_INLIST_GET(frame->surfaces), surface) - { - p_info.im = surface->im; - p_info.x = 0; - p_info.y = 0; - p_info.w = surface->im->cache_entry.w; - p_info.h = surface->im->cache_entry.h; - - EINA_INLIST_FOREACH(EINA_INLIST_GET(p_info.im->cache_entry.pipe), p) - { - int i; - - for (i = 0; i < p->op_num; i++) - { - if (p->op[i].op_func) - { - p->op[i].op_func(p_info.im, &(p->op[i]), &p_info); - } - } - } - - /* push surface out */ - if (! surface->dontpush) - { - frame->output_redraws_next_update_push(frame->data, - surface->im, surface->x, surface->y, surface->w, surface->h); - } - } - - // record frame ready time, will be used in post worker thread, evas_common_frameq_thread_post() - gettimeofday(&frame->ready_time, NULL); - - LKL(frameq->mutex); - frame->ready = 1; - eina_condition_signal(&(frameq->cond_ready)); - LKU(frameq->mutex); - } - - // Remove cleanup handler - pthread_cleanup_pop(0); - return NULL; -} - - -#define INTERVAL_QSIZE 17 // Actual size is 'INTERVAL_QSIZE - 1' because of not using index -#define SATISFACTION_THRESHOLD 4 // 4 ms --> 250 FPS -#define RESET_RATIO 4 // RESET_RATIO * [Average Ready Gap | get_max_interval()] --> Reset Threshold -#define DOUBLE_RESET_TIME_INTERVAL_THRESHOLD 16000 // make it double in case of less 16ms -#define RESET_ABSOLUTE_INTERVAL 600000 // 600 msec - -struct iq_node -{ - long long rt; - long long ri; -}; - -static struct iq_node _IQ[INTERVAL_QSIZE]; -static int _IQ_head = 0, _IQ_tail = 0; -static int _IQ_length = 0; -static long long min_ready, max_ready; -static long long average_interval; - -static int -_IQ_next_index(int i) -{ - return (i + 1) % INTERVAL_QSIZE; -} - -static int -_IQ_previous_index(int i) -{ - if (--i < 0) i += INTERVAL_QSIZE; - return i; -} - -static void -_IQ_init(void) -{ - _IQ_length = _IQ_head = _IQ_tail = 0; - min_ready = LLONG_MAX, max_ready = LLONG_MIN; - average_interval = 0; -} - -static int -_IQ_empty(void) -{ - return (_IQ_head == _IQ_tail) ? 1 : 0; -} - -static int -_IQ_full(void) -{ - return (_IQ_head == ((_IQ_tail + 1) % INTERVAL_QSIZE)) ? 1 : 0; -} - -static void -_IQ_insert(long long ready_time, long long last_interval) -{ - if (_IQ_full()) return; - - if (_IQ_empty()) - { - if (last_interval < 0) - { - last_interval = -last_interval; - } - _IQ[_IQ_tail].rt = ready_time; - _IQ[_IQ_tail].ri = last_interval; - min_ready = ready_time - last_interval; - max_ready = ready_time; - _IQ_tail = _IQ_next_index(_IQ_tail); - _IQ_length++; - } - else - { - if (max_ready < ready_time) - { - _IQ[_IQ_tail].rt = ready_time; - _IQ[_IQ_tail].ri = ready_time - max_ready; - _IQ_tail = _IQ_next_index(_IQ_tail); - _IQ_length++; - max_ready = ready_time; - } - else if (ready_time < min_ready) - { - last_interval = _IQ[_IQ_head].ri; - _IQ[_IQ_head].ri = _IQ[_IQ_head].rt - ready_time; - _IQ_head = _IQ_previous_index(_IQ_head); - _IQ[_IQ_head].rt = ready_time; - _IQ[_IQ_head].ri = last_interval; - min_ready = ready_time; - _IQ_length++; - } - else - { - int i, j, k, l = 0; - for (i = _IQ_head; i != _IQ_tail; i = j) - { - j = _IQ_next_index(i); - if (_IQ[j].rt < ready_time) - { - continue; - } - break; - } - for (k = _IQ_tail; k != j; k = l) - { - l = _IQ_previous_index(k); - _IQ[k] = _IQ[l]; - } - i = _IQ_next_index(j); - _IQ[j].ri -= (_IQ[j].rt - ready_time); - _IQ[j].rt = ready_time; - _IQ[i].ri = _IQ[i].rt - ready_time; - _IQ_tail = _IQ_next_index(_IQ_tail); - _IQ_length++; - } - } - average_interval = (max_ready - min_ready) / _IQ_length; -} - -static long long -_IQ_delete(void) -{ - struct iq_node oldest; - - if (_IQ_empty()) return 0; - oldest = _IQ[_IQ_head]; - _IQ_head = (_IQ_head + 1) % INTERVAL_QSIZE; - if ((--_IQ_length) == 0) - { - _IQ_init(); - } - else - { - min_ready = _IQ[_IQ_head].rt; - average_interval = (max_ready - min_ready) / _IQ_length; - } - - return oldest.ri; -} - -static long long -get_max_interval(void) -{ - int i; - long long max = LLONG_MIN; - - for ( i= _IQ_head ; i != _IQ_tail ; i = _IQ_next_index(i)) - { - if (_IQ[i].ri > max) - { - max = _IQ[i].ri; - } - } - - return max; -} - -static long long -tv_to_long_long(struct timeval *tv) -{ - if (!tv) - { - return 0; - } - - return tv->tv_sec * 1000000LL + tv->tv_usec; -} - -static long long -evas_common_frameq_schedule_flush_time(int frameq_sz, int thread_no, - long long last_ready_time, long long current_ready_time, - long long last_flush_time, int ready_frames_num, - int dont_schedule) -{ - // to get each time and to do others - long long current_time = 0LL; - long long current_ready_interval = 0LL; - long long theshold_time = SATISFACTION_THRESHOLD * 1000LL; // ms -> usec - long long reset_time_interval = 0LL; - long long sleep_time = 0LL; - long long saved_ready_time, saved_ready_interval; - long long time_slept = 0LL; - static long long time_lag = 0; - struct timeval now; - int frameq_full_threshold =0; - int need_reset = 0; - int need_schedule = 0; - - frameq_full_threshold = frameq_sz -thread_no; // Qsize - threads# - - /* 1.5 defer flush time of current frame if need */ - // in case of the first time, just keep ready time only - if (last_ready_time == 0LL) - { - last_ready_time = current_ready_time; - } - else - { - /* 1.5.1 get current ready time & interval */ - saved_ready_time = current_ready_time; - saved_ready_interval = current_ready_interval = current_ready_time - last_ready_time; - // compensate a case which current ready time is older than previous one, - // doesn't work on the interval queue - if (current_ready_interval < 0) - { - current_ready_time = last_ready_time; - current_ready_interval = 0; - } - - /* 1.5.2 get the reset time interval before keeping a new one */ - if (!_IQ_empty()) - { - reset_time_interval = RESET_RATIO * average_interval; - if (average_interval < DOUBLE_RESET_TIME_INTERVAL_THRESHOLD) - { - reset_time_interval *= 2; - } - } - - /* 1.5.3 reset - if too late, discard all saved interval and start from here */ - if (current_ready_interval > RESET_ABSOLUTE_INTERVAL) - { - need_reset = 1; - } - else if (_IQ_length >= thread_no * 2 && current_ready_interval > reset_time_interval) - { - need_reset = 1; - } - else if (_IQ_length >= thread_no && _IQ_length < thread_no * 2 - && current_ready_interval > get_max_interval() * RESET_RATIO) - { - need_reset = 1; - } - - if (need_reset) - { - _IQ_init(); - } - else - { - /* 1.5.4 enqueue - keep a new interval for next average interval */ - if (_IQ_full()) - { - _IQ_delete(); - } - _IQ_insert(saved_ready_time, saved_ready_interval); - - /* 1.5.5 schedule - if faster than average interval, figure out sleep time to meet it */ - if (!dont_schedule) - { - need_schedule = 0; - sleep_time = 0; - if (_IQ_length >= thread_no * 2 && average_interval > theshold_time) - { - need_schedule = 1; - } - // compensate the case that postworker blocks the workers from getting a new fresh frame - // It's actually occurred when during the wait time of postworker, the frame queue is full - // Consequently check the number of currently ready frames and apply some time drop to average time according to the number - if (ready_frames_num >= frameq_full_threshold) - { - need_schedule = 0; - } - if (need_schedule) - { - gettimeofday(&now, NULL); - current_time = tv_to_long_long(&now); - time_lag += (current_time - last_flush_time); - sleep_time = (average_interval < time_lag) ? 0 : (average_interval - time_lag); - } - } - - /* 1.5.6 sleep - actually sleep and get over-slept time (time_lag) for next frame */ - if (sleep_time > 0) - { - sleep_time = sleep_time * 9 / 10; - usleep((unsigned int)sleep_time); - gettimeofday(&now, NULL); - time_slept = tv_to_long_long(&now) - current_time; - time_lag = time_slept - sleep_time; - } - else - { - time_lag = 0; - } - } - last_ready_time = current_ready_time; - } - - return last_ready_time; -} - -static void * -evas_common_frameq_thread_post(void *data) -{ - Evas_FrameQ *frameq; - Evas_Frame *frame; - Evas_Surface *surface; - Thinfo *thinfo; - Evas_Frameq_Thread_Info *fq_info; - Eina_List *pending_writes = NULL; - Eina_List *prev_pending_writes = NULL; - - long long last_ready_time = 0LL; - long long current_ready_time; - Evas_Frame *temp_frame = NULL; - int ready_frames_num; - long long last_flush_time = 0LL; - struct timeval now; - int dont_schedule = 0; - - thinfo = data; - fq_info = (Evas_Frameq_Thread_Info *)(thinfo->fq_info); - frameq = fq_info->frameq; - - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); - pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); - /* install thread cancelation cleanup handler */ - pthread_cleanup_push(evas_common_frameq_release, data); - - _IQ_init(); - - for (;;) - { - /* 1. wait the first frame being done */ - LKL(frameq->mutex); - while(!frameq->frames || !frameq->frames->ready) - { - eina_condition_wait(&(frameq->cond_ready)); - } - frame = frameq->frames; - - /* 1.5. prepare to schedule flush time */ - current_ready_time = tv_to_long_long(&frame->ready_time); - ready_frames_num = 0; - EINA_INLIST_FOREACH(EINA_INLIST_GET(frameq->frames), temp_frame) - { - if (temp_frame->ready == 1) - { - ready_frames_num++; - } - } - dont_schedule = (frame->dont_schedule)?1:0; - LKU(frameq->mutex); - - /* 2. generate pending_writes */ - EINA_INLIST_FOREACH(EINA_INLIST_GET(frame->surfaces), surface) - { - evas_common_pipe_flush(surface->im); - if (! surface->dontpush) - { - pending_writes = eina_list_append(pending_writes, surface->im); - } - } - - /* 2.5. schedule flush time */ - last_ready_time = evas_common_frameq_schedule_flush_time( - frameq->frameq_sz, frameq->thread_num, - last_ready_time, current_ready_time, - last_flush_time, ready_frames_num, dont_schedule); - - /* 3. flush redraws */ - frame->output_set_priv(frame->data, pending_writes, prev_pending_writes); - frame->output_flush(frame->data); - gettimeofday(&now, NULL); - // keep as the last flush time - last_flush_time = now.tv_sec * 1000000LL + now.tv_usec; - - prev_pending_writes = pending_writes; - pending_writes = NULL; - - /* 4. remove this frame from the frame queue */ - LKL(frameq->mutex); - frameq->frames = - (Evas_Frame *)eina_inlist_remove(EINA_INLIST_GET(frameq->frames), - EINA_INLIST_GET(frame)); - - LKU(frameq->mutex); - eina_condition_broadcast(&frameq->cond_done); - evas_common_frame_dealloc(frame); - } - - // Remove cleanup handler - pthread_cleanup_pop(0); - return NULL; -} - -#endif /* EVAS_FRAME_QUEUING */ -#endif - -#ifdef BUILD_PTHREAD -static int thread_num = 0; -static Thinfo thinfo[TH_MAX]; -static pthread_barrier_t thbarrier[2]; -#endif - -static void -evas_common_pipe_begin(RGBA_Image *im) -{ -#ifdef BUILD_PTHREAD - int i, y, h; - -#ifdef EVAS_FRAME_QUEUING - return; -#endif - - if (!im->cache_entry.pipe) return; - if (thread_num == 1) return; - y = 0; - h = im->cache_entry.h / thread_num; - if (h < 1) h = 1; - for (i = 0; i < thread_num; i++) - { - RGBA_Pipe_Thread_Info *info; - -// if (y >= im->cache_entry.h) break; - info = calloc(1, sizeof(RGBA_Pipe_Thread_Info)); - info->im = im; -#ifdef EVAS_SLI - info->x = 0; - info->w = im->cache_entry.w; - info->y = i; - info->h = thread_num; -#else - info->x = 0; - info->y = y; - info->w = im->cache_entry.w; - if (i == (thread_num - 1)) - { - info->h = im->cache_entry.h - y; - } - else - { - info->h = h; - } - y += info->h; -#endif - thinfo[i].info = info; - } - /* tell worker threads to start */ - pthread_barrier_wait(&(thbarrier[0])); -#endif -} - -#ifdef EVAS_FRAME_QUEUING -EAPI void -evas_common_frameq_begin(void) -{ -#ifdef BUILD_PTHREAD - int i; - Evas_Frameq_Thread_Info *fp_info; - pthread_attr_t attr; - cpu_set_t cpu; - - if (!gframeq.initialised) - { - int cpunum, set_cpu_affinity = 0; - - cpunum = eina_cpu_count(); - gframeq.thread_num = cpunum; - gframeq.frameq_sz = cpunum * FRAMEQ_SZ_PER_THREAD; - - eina_threads_init(); - - for (i = 0; i < gframeq.thread_num; i++) - { - - fp_info = calloc(1, sizeof(Evas_Frameq_Thread_Info)); - fp_info->frameq = &gframeq; - - gframeq.thinfo[i].thread_num = i; - gframeq.thinfo[i].fq_info = fp_info; - - pthread_attr_init(&attr); - if (set_cpu_affinity) - { - CPU_ZERO(&cpu); - CPU_SET((i+1) % cpunum, &cpu); - pthread_attr_setaffinity_np(&attr, sizeof(cpu), &cpu); - } - - pthread_create(&(gframeq.thinfo[i].thread_id), &attr, - evas_common_frameq_thread, &(gframeq.thinfo[i])); - - pthread_attr_destroy(&attr); - pthread_detach(gframeq.thinfo[i].thread_id); - } - - { - fp_info = calloc(1, sizeof(Evas_Frameq_Thread_Info)); - fp_info->frameq = &gframeq; - - gframeq.thinfo[i].thread_num = i; - gframeq.thinfo[i].fq_info = fp_info; - - pthread_attr_init(&attr); - if (set_cpu_affinity) - { - CPU_ZERO(&cpu); - CPU_SET((i+1) % cpunum, &cpu); - pthread_attr_setaffinity_np(&attr, sizeof(cpu), &cpu); - } - - pthread_create(&(gframeq.thinfo[i].thread_id), &attr, - evas_common_frameq_thread_post, &(gframeq.thinfo[i])); - pthread_attr_destroy(&attr); - pthread_detach(gframeq.thinfo[i].thread_id); - } - gframeq.initialised = 1; // now worker threads are created. - - INF("initialised"); - DBG("%d cpus, set_cpu_affinity=%d, frameq_sz=%d", - cpunum, set_cpu_affinity, gframeq.frameq_sz); - } -#endif /* BUILD_PTHREAD */ -} - -EAPI void -evas_common_frameq_finish(void) -{ - int i; - - /* 1. cancel all worker threads */ - for (i = 0; i < gframeq.thread_num; i++) - { - pthread_cancel(gframeq.thinfo[i].thread_id); - } - // cancel post-worker thread - pthread_cancel(gframeq.thinfo[i].thread_id); - - /* 2. send signal to worker threads so that they enter to the thread cancelation cleanup handler */ - for (i = 0; i < gframeq.thread_num; i++) - { - eina_condition_signal(&(gframeq.cond_new)); - } - // send signal to post-worker thread - eina_condition_signal(&(gframeq.cond_ready)); - - /* all the workers were created and detached before - * so don't need to join them here. - */ - -} - -#endif /* EVAS_FRAME_QUEUING */ - -EAPI void -evas_common_pipe_flush(RGBA_Image *im) -{ - if (!im->cache_entry.pipe) return; -#ifndef EVAS_FRAME_QUEUING -#ifdef BUILD_PTHREAD - if (thread_num > 1) - { - /* sync worker threads */ - pthread_barrier_wait(&(thbarrier[1])); - } - else -#endif - { - RGBA_Pipe *p; - int i; - - /* process pipe - 1 thead */ - for (p = im->cache_entry.pipe; p; p = (RGBA_Pipe *)(EINA_INLIST_GET(p))->next) - { - for (i = 0; i < p->op_num; i++) - { - if (p->op[i].op_func) - { - p->op[i].op_func(im, &(p->op[i]), NULL); - } - } - } - } -#endif /* !EVAS_FRAME_QUEUING */ - evas_common_cpu_end_opt(); - evas_common_pipe_free(im); -} - -EAPI void -evas_common_pipe_free(RGBA_Image *im) -{ - - RGBA_Pipe *p; - int i; - - if (!im->cache_entry.pipe) return; - /* FIXME: PTHREAD join all threads here (if not finished) */ - - /* free pipe */ - while (im->cache_entry.pipe) - { - p = im->cache_entry.pipe; - for (i = 0; i < p->op_num; i++) - { - if (p->op[i].free_func) - { - p->op[i].free_func(&(p->op[i])); - } - } - im->cache_entry.pipe = (RGBA_Pipe *)eina_inlist_remove(EINA_INLIST_GET(im->cache_entry.pipe), EINA_INLIST_GET(p)); - free(p); - } -} - - - -/* draw ops */ -/**************** RECT ******************/ -static void -evas_common_pipe_rectangle_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info) -{ - if (info) - { - RGBA_Draw_Context context; - - memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context)); -#ifdef EVAS_SLI - evas_common_draw_context_set_sli(&(context), info->y, info->h); -#else - evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h); -#endif - evas_common_rectangle_draw(dst, &(context), - op->op.rect.x, op->op.rect.y, - op->op.rect.w, op->op.rect.h); - } - else - { - evas_common_rectangle_draw(dst, &(op->context), - op->op.rect.x, op->op.rect.y, - op->op.rect.w, op->op.rect.h); - } -} - -EAPI void -evas_common_pipe_rectangle_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, int w, int h) -{ - RGBA_Pipe_Op *op; - - if ((w < 1) || (h < 1)) return; - dst->cache_entry.pipe = evas_common_pipe_add(dst->cache_entry.pipe, &op); - if (!dst->cache_entry.pipe) return; - op->op.rect.x = x; - op->op.rect.y = y; - op->op.rect.w = w; - op->op.rect.h = h; - op->op_func = evas_common_pipe_rectangle_draw_do; - op->free_func = evas_common_pipe_op_free; - evas_common_pipe_draw_context_copy(dc, op); -} - -/**************** LINE ******************/ -static void -evas_common_pipe_line_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info) -{ - if (info) - { - RGBA_Draw_Context context; - - memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context)); -#ifdef EVAS_SLI - evas_common_draw_context_set_sli(&(context), info->y, info->h); -#else - evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h); -#endif - evas_common_line_draw(dst, &(context), - op->op.line.x0, op->op.line.y0, - op->op.line.x1, op->op.line.y1); - } - else - { - evas_common_line_draw(dst, &(op->context), - op->op.line.x0, op->op.line.y0, - op->op.line.x1, op->op.line.y1); - } -} - -EAPI void -evas_common_pipe_line_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, - int x0, int y0, int x1, int y1) -{ - RGBA_Pipe_Op *op; - - dst->cache_entry.pipe = evas_common_pipe_add(dst->cache_entry.pipe, &op); - if (!dst->cache_entry.pipe) return; - op->op.line.x0 = x0; - op->op.line.y0 = y0; - op->op.line.x1 = x1; - op->op.line.y1 = y1; - op->op_func = evas_common_pipe_line_draw_do; - op->free_func = evas_common_pipe_op_free; - evas_common_pipe_draw_context_copy(dc, op); -} - -/**************** POLY ******************/ -static void -evas_common_pipe_op_poly_free(RGBA_Pipe_Op *op) -{ - RGBA_Polygon_Point *p; - - while (op->op.poly.points) - { - p = op->op.poly.points; - op->op.poly.points = (RGBA_Polygon_Point *)eina_inlist_remove(EINA_INLIST_GET(op->op.poly.points), - EINA_INLIST_GET(p)); - free(p); - } - evas_common_pipe_op_free(op); -} - -static void -evas_common_pipe_poly_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info) -{ - if (info) - { - RGBA_Draw_Context context; - - memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context)); -#ifdef EVAS_SLI - evas_common_draw_context_set_sli(&(context), info->y, info->h); -#else - evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h); -#endif - evas_common_polygon_draw(dst, &(context), - op->op.poly.points, 0, 0); - } - else - { - evas_common_polygon_draw(dst, &(op->context), - op->op.poly.points, 0, 0); - } -} - -EAPI void -evas_common_pipe_poly_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, - RGBA_Polygon_Point *points, int x, int y) -{ - RGBA_Pipe_Op *op; - RGBA_Polygon_Point *pts = NULL, *p, *pp; - - if (!points) return; - dst->cache_entry.pipe = evas_common_pipe_add(dst->cache_entry.pipe, &op); - if (!dst->cache_entry.pipe) return; - /* FIXME: copy points - maybe we should refcount? */ - for (p = points; p; p = (RGBA_Polygon_Point *)(EINA_INLIST_GET(p))->next) - { - pp = calloc(1, sizeof(RGBA_Polygon_Point)); - if (pp) - { - pp->x = p->x + x; - pp->y = p->y + y; - pts = (RGBA_Polygon_Point *)eina_inlist_append(EINA_INLIST_GET(pts), EINA_INLIST_GET(pp)); - } - } - op->op.poly.points = pts; - op->op_func = evas_common_pipe_poly_draw_do; - op->free_func = evas_common_pipe_op_poly_free; - evas_common_pipe_draw_context_copy(dc, op); -} - -/**************** TEXT ******************/ -static void -evas_common_pipe_op_text_free(RGBA_Pipe_Op *op) -{ -#ifdef EVAS_FRAME_QUEUING - LKL(op->op.text.font->ref_fq_del); - op->op.text.font->ref_fq[1]++; - LKU(op->op.text.font->ref_fq_del); - eina_condition_signal(&(op->op.text.font->cond_fq_del)); -#else - evas_common_font_free(op->op.text.font); -#endif - evas_common_text_props_content_unref(&(op->op.text.intl_props)); - evas_common_pipe_op_free(op); -} - -#ifdef EVAS_FRAME_QUEUING -/* flush all op using @fn */ -EAPI void -evas_common_pipe_op_text_flush(RGBA_Font *fn) -{ - if (! evas_common_frameq_enabled()) - return; - - LKL(fn->ref_fq_add); - LKL(fn->ref_fq_del); - - while (fn->ref_fq[0] != fn->ref_fq[1]) - eina_condition_wait(&(fn->cond_fq_del)); - - LKU(fn->ref_fq_del); - LKU(fn->ref_fq_add); -} -#endif - -static void -evas_common_pipe_text_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info) -{ - if (info) - { - RGBA_Draw_Context context; - - memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context)); -#ifdef EVAS_SLI - evas_common_draw_context_set_sli(&(context), info->y, info->h); -#else - evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h); -#endif - evas_common_font_draw(dst, &(context), - op->op.text.font, op->op.text.x, op->op.text.y, - &op->op.text.intl_props); - } - else - { - evas_common_font_draw(dst, &(op->context), - op->op.text.font, op->op.text.x, op->op.text.y, - &op->op.text.intl_props); - } -} - -EAPI void -evas_common_pipe_text_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, - RGBA_Font *fn, int x, int y, const Evas_Text_Props *intl_props) -{ - RGBA_Pipe_Op *op; - - if (!fn) return; - dst->cache_entry.pipe = evas_common_pipe_add(dst->cache_entry.pipe, &op); - if (!dst->cache_entry.pipe) return; - op->op.text.x = x; - op->op.text.y = y; - evas_common_text_props_content_copy_and_ref(&(op->op.text.intl_props), - intl_props); -#ifdef EVAS_FRAME_QUEUING - LKL(fn->ref_fq_add); - fn->ref_fq[0]++; - LKU(fn->ref_fq_add); -#else - fn->references++; -#endif - op->op.text.font = fn; - op->op_func = evas_common_pipe_text_draw_do; - op->free_func = evas_common_pipe_op_text_free; - evas_common_pipe_draw_context_copy(dc, op); -} - -/**************** IMAGE *****************/ -static void -evas_common_pipe_op_image_free(RGBA_Pipe_Op *op) -{ -#ifdef EVAS_FRAME_QUEUING - LKL(op->op.image.src->cache_entry.ref_fq_del); - op->op.image.src->cache_entry.ref_fq[1]++; - LKU(op->op.image.src->cache_entry.ref_fq_del); - eina_condition_signal(&(op->op.image.src->cache_entry.cond_fq_del)); -#else - op->op.image.src->ref--; - if (op->op.image.src->ref == 0) - { - evas_cache_image_drop(&op->op.image.src->cache_entry); - } -#endif - evas_common_pipe_op_free(op); -} - -#ifdef EVAS_FRAME_QUEUING -EAPI void -evas_common_pipe_op_image_flush(RGBA_Image *im) -{ - if (! evas_common_frameq_enabled()) - return; - - LKL(im->cache_entry.ref_fq_add); - LKL(im->cache_entry.ref_fq_del); - - while (im->cache_entry.ref_fq[0] != im->cache_entry.ref_fq[1]) - eina_condition_wait(&(im->cache_entry.cond_fq_del)); - - LKU(im->cache_entry.ref_fq_del); - LKU(im->cache_entry.ref_fq_add); -} -#endif - -static void -evas_common_pipe_image_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info) -{ - if (info) - { - RGBA_Draw_Context context; - - memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context)); -#ifdef EVAS_SLI - evas_common_draw_context_set_sli(&(context), info->y, info->h); -#else - evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h); -#endif - -#ifdef SCALECACHE - evas_common_rgba_image_scalecache_do((Image_Entry *)(op->op.image.src), - dst, &(context), - op->op.image.smooth, - op->op.image.sx, - op->op.image.sy, - op->op.image.sw, - op->op.image.sh, - op->op.image.dx, - op->op.image.dy, - op->op.image.dw, - op->op.image.dh); -#else - if (op->op.image.smooth) - { - evas_common_scale_rgba_in_to_out_clip_smooth(op->op.image.src, - dst, &(context), - op->op.image.sx, - op->op.image.sy, - op->op.image.sw, - op->op.image.sh, - op->op.image.dx, - op->op.image.dy, - op->op.image.dw, - op->op.image.dh); - } - else - { - evas_common_scale_rgba_in_to_out_clip_sample(op->op.image.src, - dst, &(context), - op->op.image.sx, - op->op.image.sy, - op->op.image.sw, - op->op.image.sh, - op->op.image.dx, - op->op.image.dy, - op->op.image.dw, - op->op.image.dh); - } -#endif - } - else - { -#ifdef SCALECACHE - evas_common_rgba_image_scalecache_do((Image_Entry *)(op->op.image.src), - dst, &(op->context), - op->op.image.smooth, - op->op.image.sx, - op->op.image.sy, - op->op.image.sw, - op->op.image.sh, - op->op.image.dx, - op->op.image.dy, - op->op.image.dw, - op->op.image.dh); -#else - if (op->op.image.smooth) - { - evas_common_scale_rgba_in_to_out_clip_smooth(op->op.image.src, - dst, &(op->context), - op->op.image.sx, - op->op.image.sy, - op->op.image.sw, - op->op.image.sh, - op->op.image.dx, - op->op.image.dy, - op->op.image.dw, - op->op.image.dh); - } - else - { - evas_common_scale_rgba_in_to_out_clip_sample(op->op.image.src, - dst, &(op->context), - op->op.image.sx, - op->op.image.sy, - op->op.image.sw, - op->op.image.sh, - op->op.image.dx, - op->op.image.dy, - op->op.image.dw, - op->op.image.dh); - } -#endif - } -} - -EAPI void -evas_common_pipe_image_draw(RGBA_Image *src, RGBA_Image *dst, - RGBA_Draw_Context *dc, int smooth, - int src_region_x, int src_region_y, - int src_region_w, int src_region_h, - int dst_region_x, int dst_region_y, - int dst_region_w, int dst_region_h) -{ - RGBA_Pipe_Op *op; - - if (!src) return; -// evas_common_pipe_flush(src); - dst->cache_entry.pipe = evas_common_pipe_add(dst->cache_entry.pipe, &op); - if (!dst->cache_entry.pipe) return; - op->op.image.smooth = smooth; - op->op.image.sx = src_region_x; - op->op.image.sy = src_region_y; - op->op.image.sw = src_region_w; - op->op.image.sh = src_region_h; - op->op.image.dx = dst_region_x; - op->op.image.dy = dst_region_y; - op->op.image.dw = dst_region_w; - op->op.image.dh = dst_region_h; -#ifdef EVAS_FRAME_QUEUING - LKL(src->cache_entry.ref_fq_add); - src->cache_entry.ref_fq[0]++; - LKU(src->cache_entry.ref_fq_add); -#else - src->ref++; -#endif - op->op.image.src = src; - op->op_func = evas_common_pipe_image_draw_do; - op->free_func = evas_common_pipe_op_image_free; - evas_common_pipe_draw_context_copy(dc, op); - -#ifdef EVAS_FRAME_QUEUING - /* laod every src image here. - * frameq utilize all cpu cores already by worker threads - * so another threads and barrier waiting can't be of any benefit. - * therefore, not instantiate loader threads. - */ - if (src->cache_entry.space == EVAS_COLORSPACE_ARGB8888) - evas_cache_image_load_data(&src->cache_entry); - evas_common_image_colorspace_normalize(src); -#else - evas_common_pipe_image_load(src); -#endif -} - -static void -evas_common_pipe_op_map_free(RGBA_Pipe_Op *op) -{ -#ifdef EVAS_FRAME_QUEUING - LKL(op->op.image.src->cache_entry.ref_fq_del); - op->op.image.src->cache_entry.ref_fq[1]++; - LKU(op->op.image.src->cache_entry.ref_fq_del); -#else - op->op.map.src->ref--; - if (op->op.map.src->ref == 0) - evas_cache_image_drop(&op->op.map.src->cache_entry); -#endif - free(op->op.map.p); - evas_common_pipe_op_free(op); -} - -static void -evas_common_pipe_map_draw_do(RGBA_Image *dst, RGBA_Pipe_Op *op, RGBA_Pipe_Thread_Info *info) -{ - if (info) - { - RGBA_Draw_Context context; - - memcpy(&(context), &(op->context), sizeof(RGBA_Draw_Context)); -#ifdef EVAS_SLI - evas_common_draw_context_set_sli(&(context), info->y, info->h); -#else - evas_common_draw_context_clip_clip(&(context), info->x, info->y, info->w, info->h); -#endif - - evas_common_map_rgba(op->op.map.src, dst, - &context, op->op.map.npoints, op->op.map.p, - op->op.map.smooth, op->op.map.level); - } - else - { - evas_common_map_rgba(op->op.map.src, dst, - &(op->context), op->op.map.npoints, op->op.map.p, - op->op.map.smooth, op->op.map.level); - } -} - -EAPI void -evas_common_pipe_map_draw(RGBA_Image *src, RGBA_Image *dst, - RGBA_Draw_Context *dc, int npoints, RGBA_Map_Point *p, - int smooth, int level) -{ - RGBA_Pipe_Op *op; - RGBA_Map_Point *pts_copy; - int i; - - if (!src) return; - pts_copy = malloc(sizeof (RGBA_Map_Point) * 4); - if (!pts_copy) return; - dst->cache_entry.pipe = evas_common_pipe_add(dst->cache_entry.pipe, &op); - if (!dst->cache_entry.pipe) - { - free(pts_copy); - return; - } - - for (i = 0; i < 4; ++i) - pts_copy[i] = p[i]; - - op->op.map.npoints = npoints; - op->op.map.smooth = smooth; - op->op.map.level = level; -#ifdef EVAS_FRAME_QUEUING - LKL(src->cache_entry.ref_fq_add); - src->cache_entry.ref_fq[0]++; - LKU(src->cache_entry.ref_fq_add); -#else - src->ref++; -#endif - op->op.map.src = src; - op->op.map.p = pts_copy; - op->op_func = evas_common_pipe_map_draw_do; - op->free_func = evas_common_pipe_op_map_free; - evas_common_pipe_draw_context_copy(dc, op); - -#ifdef EVAS_FRAME_QUEUING - /* laod every src image here. - * frameq utilize all cpu cores already by worker threads - * so another threads and barrier waiting can't be of any benefit. - * therefore, not instantiate loader threads. - */ - if (src->cache_entry.space == EVAS_COLORSPACE_ARGB8888) - evas_cache_image_load_data(&src->cache_entry); - evas_common_image_colorspace_normalize(src); -#else - evas_common_pipe_image_load(src); -#endif -} - -static void -evas_common_pipe_map_render(RGBA_Image *root) -{ - RGBA_Pipe *p; - int i; - - /* Map imply that we need to process them recursively first. */ - for (p = root->cache_entry.pipe; p; p = (RGBA_Pipe *)(EINA_INLIST_GET(p))->next) - { - for (i = 0; i < p->op_num; i++) - { - if (p->op[i].op_func == evas_common_pipe_map_draw_do) - { - if (p->op[i].op.map.src->cache_entry.pipe) - evas_common_pipe_map_render(p->op[i].op.map.src); - } - else if (p->op[i].op_func == evas_common_pipe_image_draw_do) - { - if (p->op[i].op.image.src->cache_entry.pipe) - evas_common_pipe_map_render(p->op[i].op.image.src); - } - } - } - - evas_common_pipe_begin(root); - evas_common_pipe_flush(root); -} - -#ifdef BUILD_PTHREAD -static Eina_List *task = NULL; -static Thinfo task_thinfo[TH_MAX]; -static pthread_barrier_t task_thbarrier[2]; -static LK(task_mutext); -#endif - -#ifdef BUILD_PTHREAD -static void* -evas_common_pipe_load(void *data) -{ - Thinfo *tinfo; - - tinfo = data; - for (;;) - { - /* wait for start signal */ - pthread_barrier_wait(&(tinfo->barrier[0])); - - while (task) - { - RGBA_Image *im = NULL; - - LKL(task_mutext); - im = eina_list_data_get(task); - task = eina_list_remove_list(task, task); - LKU(task_mutext); - - if (im) - { - if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888) - evas_cache_image_load_data(&im->cache_entry); - evas_common_image_colorspace_normalize(im); - - im->flags &= ~RGBA_IMAGE_TODO_LOAD; - } - } - - /* send finished signal */ - pthread_barrier_wait(&(tinfo->barrier[1])); - } - - return NULL; -} -#endif - -static volatile int bval = 0; - -static void -evas_common_pipe_image_load_do(void) -{ -#ifdef BUILD_PTHREAD - /* Notify worker thread. */ - pthread_barrier_wait(&(task_thbarrier[0])); - - /* sync worker threads */ - pthread_barrier_wait(&(task_thbarrier[1])); -#endif -} - -static Eina_Bool -evas_common_pipe_init(void) -{ -#ifdef BUILD_PTHREAD - if (thread_num == 0) - { - int cpunum; - int i; - - cpunum = eina_cpu_count(); - thread_num = cpunum; -// on single cpu we still want this initted.. otherwise we block forever -// waiting onm pthread barriers for async rendering on a single core! -// if (thread_num == 1) return EINA_FALSE; - - eina_threads_init(); - - LKI(task_mutext); - - pthread_barrier_init(&(thbarrier[0]), NULL, thread_num + 1); - pthread_barrier_init(&(thbarrier[1]), NULL, thread_num + 1); - for (i = 0; i < thread_num; i++) - { - pthread_attr_t attr; - cpu_set_t cpu; - - pthread_attr_init(&attr); - CPU_ZERO(&cpu); - CPU_SET(i % cpunum, &cpu); - pthread_attr_setaffinity_np(&attr, sizeof(cpu), &cpu); - thinfo[i].thread_num = i; - thinfo[i].info = NULL; - thinfo[i].barrier = thbarrier; - /* setup initial locks */ - pthread_create(&(thinfo[i].thread_id), &attr, - evas_common_pipe_thread, &(thinfo[i])); - pthread_attr_destroy(&attr); - } - - pthread_barrier_init(&(task_thbarrier[0]), NULL, thread_num + 1); - pthread_barrier_init(&(task_thbarrier[1]), NULL, thread_num + 1); - for (i = 0; i < thread_num; i++) - { - pthread_attr_t attr; - cpu_set_t cpu; - - pthread_attr_init(&attr); - CPU_ZERO(&cpu); - CPU_SET(i % cpunum, &cpu); - pthread_attr_setaffinity_np(&attr, sizeof(cpu), &cpu); - task_thinfo[i].thread_num = i; - task_thinfo[i].info = NULL; - task_thinfo[i].barrier = task_thbarrier; - /* setup initial locks */ - pthread_create(&(task_thinfo[i].thread_id), &attr, - evas_common_pipe_load, &(task_thinfo[i])); - pthread_attr_destroy(&attr); - } - } - - if (thread_num == 1) return EINA_FALSE; - return EINA_TRUE; -#endif - return EINA_FALSE; -} - -EAPI void -evas_common_pipe_image_load(RGBA_Image *im) -{ - if (im->flags & RGBA_IMAGE_TODO_LOAD) - return ; - - if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888 - && !evas_cache_image_is_loaded(&(im->cache_entry))) - goto add_task; - - if ((!im->cs.data) || ((!im->cs.dirty) && (!(im->flags & RGBA_IMAGE_IS_DIRTY)))) - goto add_task; - - return ; - - add_task: - task = eina_list_append(task, im); - im->flags |= RGBA_IMAGE_TODO_LOAD; -} - -EAPI void -evas_common_pipe_map_begin(RGBA_Image *root) -{ - if (!evas_common_pipe_init()) - { - RGBA_Image *im; - - EINA_LIST_FREE(task, im) - { - if (im->cache_entry.space == EVAS_COLORSPACE_ARGB8888) - evas_cache_image_load_data(&im->cache_entry); - evas_common_image_colorspace_normalize(im); - - im->flags &= ~RGBA_IMAGE_TODO_LOAD; - } - } - - evas_common_pipe_image_load_do(); - - evas_common_pipe_map_render(root); -} - -#endif -- cgit v1.1