From c795d31a1faf15853a1e8315bb60f73f9a534df5 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 5 May 2016 13:15:51 +0200 Subject: Simplify scanline threaded processor used by GPU_verify_image Just avoid some unneeded initialization functions when the threaded processor is simple enough to only depend on current chunk start scanline and number of scanlines. --- source/blender/gpu/intern/gpu_draw.c | 41 +++++--------------- source/blender/imbuf/IMB_imbuf.h | 8 ++++ source/blender/imbuf/intern/imageprocess.c | 61 ++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 32 deletions(-) (limited to 'source/blender') diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 2be392acde1..e5d51772bb2 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -509,16 +509,9 @@ static void gpu_verify_reflection(Image *ima) } } -typedef struct VerifyThreadInitData { - ImBuf *ibuf; - float *srgb_frect; -} VerifyThreadInitData; - typedef struct VerifyThreadData { ImBuf *ibuf; float *srgb_frect; - int start_line; - int height; } VerifyThreadData; static void gpu_verify_high_bit_srgb_buffer_slice(float *srgb_frect, @@ -541,27 +534,15 @@ static void gpu_verify_high_bit_srgb_buffer_slice(float *srgb_frect, IMB_buffer_float_clamp(current_srgb_frect, ibuf->x, height); } -static void verify_thread_init(void *data_v, - int start_line, - int height, - void *init_data_v) -{ - VerifyThreadData *data = (VerifyThreadData *) data_v; - VerifyThreadInitData *init_data = (VerifyThreadInitData *) init_data_v; - data->ibuf = init_data->ibuf; - data->srgb_frect = init_data->srgb_frect; - data->start_line = start_line; - data->height = height; -} - -static void *verify_thread_do(void *data_v) +static void verify_thread_do(void *data_v, + int start_scanline, + int num_scanlines) { VerifyThreadData *data = (VerifyThreadData *)data_v; gpu_verify_high_bit_srgb_buffer_slice(data->srgb_frect, data->ibuf, - data->start_line, - data->height); - return NULL; + start_scanline, + num_scanlines); } static void gpu_verify_high_bit_srgb_buffer(float *srgb_frect, @@ -573,14 +554,10 @@ static void gpu_verify_high_bit_srgb_buffer(float *srgb_frect, 0, ibuf->y); } else { - VerifyThreadInitData init_data; - init_data.ibuf = ibuf; - init_data.srgb_frect = srgb_frect; - IMB_processor_apply_threaded(ibuf->y, - sizeof(VerifyThreadData), - &init_data, - verify_thread_init, - verify_thread_do); + VerifyThreadData data; + data.ibuf = ibuf; + data.srgb_frect = srgb_frect; + IMB_processor_apply_threaded_scanlines(ibuf->y, verify_thread_do, &data); } } diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index 043f1602a76..bd19271ff65 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -580,6 +580,14 @@ void IMB_processor_apply_threaded(int buffer_lines, int handle_size, void *init_ void *customdata), void *(do_thread) (void *)); +typedef void (*ScanlineThreadFunc) (void *custom_data, + int start_scanline, + int num_scanlines); +void IMB_processor_apply_threaded_scanlines(int buffer_lines, + ScanlineThreadFunc do_thread, + void *custom_data); + + /* ffmpeg */ void IMB_ffmpeg_init(void); const char *IMB_ffmpeg_last_error(void); diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c index 9e4bb957f66..ebcd6e088f4 100644 --- a/source/blender/imbuf/intern/imageprocess.c +++ b/source/blender/imbuf/intern/imageprocess.c @@ -374,6 +374,67 @@ void IMB_processor_apply_threaded(int buffer_lines, int handle_size, void *init_ BLI_task_pool_free(task_pool); } +typedef struct ScanlineGlobalData { + void *custom_data; + ScanlineThreadFunc do_thread; +} ScanlineGlobalData; + +typedef struct ScanlineTask { + int start_scanline; + int num_scanlines; +} ScanlineTask; + +static void processor_apply_scanline_func(TaskPool * __restrict pool, + void *taskdata, + int UNUSED(threadid)) +{ + ScanlineTask *task = (ScanlineTask *)taskdata; + ScanlineGlobalData *data = (ScanlineGlobalData*)BLI_task_pool_userdata(pool); + data->do_thread(data->custom_data, + task->start_scanline, + task->num_scanlines); +} + +void IMB_processor_apply_threaded_scanlines(int buffer_lines, + ScanlineThreadFunc do_thread, + void *custom_data) +{ + ScanlineGlobalData data; + data.custom_data = custom_data; + data.do_thread = do_thread; + const int lines_per_task = 64; + const int total_tasks = (buffer_lines + lines_per_task - 1) / lines_per_task; + TaskScheduler *task_scheduler = BLI_task_scheduler_get(); + TaskPool *task_pool = BLI_task_pool_create(task_scheduler, &data); + ScanlineTask *handles = MEM_mallocN(sizeof(ScanlineTask) * total_tasks, + "processor apply threaded handles"); + for (int i = 0, start_line = 0; i < total_tasks; i++) { + ScanlineTask *handle = &handles[i]; + handle->start_scanline = start_line; + if (i < total_tasks - 1) { + handle->num_scanlines = lines_per_task; + } + else { + handle->num_scanlines = buffer_lines - start_line; + } + + BLI_task_pool_push(task_pool, + processor_apply_scanline_func, + handle, + false, + TASK_PRIORITY_LOW); + + start_line += lines_per_task; + } + + /* work and wait until tasks are done */ + BLI_task_pool_work_and_wait(task_pool); + + /* Free memory. */ + MEM_freeN(handles); + BLI_task_pool_free(task_pool); +} + /* Alpha-under */ void IMB_alpha_under_color_float(float *rect_float, int x, int y, float backcol[3]) -- cgit v1.2.3