diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2016-05-05 12:25:31 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2016-05-05 12:28:50 +0300 |
commit | 9aff51661c93c249fb83478a2ed2fe5e8e92f3b0 (patch) | |
tree | 4bb638f887b3d2ff243b029bcbac03f1b0758092 /source/blender/gpu/intern | |
parent | 8c3c669c2d6f342bc27b0c8b130f8518f6b432f4 (diff) |
Optimization for initial display of high res textures in viewport
Multi-thread all the color space conversion operations.
Gives speedup from 0.8 to 0.1 seconds on a model with 4k etxture on it.
Diffstat (limited to 'source/blender/gpu/intern')
-rw-r--r-- | source/blender/gpu/intern/gpu_draw.c | 99 |
1 files changed, 82 insertions, 17 deletions
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 1c22c89abf9..c6c898a4b96 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -509,6 +509,81 @@ static void gpu_verify_reflection(Image *ima) } } +typedef struct VerifyTreadInitData { + ImBuf *ibuf; + float *srgb_frect; +} VerifyTreadInitData; + +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, + ImBuf *ibuf, + const int start_line, + const int height) +{ + size_t offset = ibuf->channels * start_line * ibuf->x; + float *current_srgb_frect = srgb_frect + offset; + float *current_rect_float = ibuf->rect_float + offset; + IMB_buffer_float_from_float(current_srgb_frect, + current_rect_float, + ibuf->channels, + IB_PROFILE_SRGB, + IB_PROFILE_LINEAR_RGB, true, + ibuf->x, height, + ibuf->x, ibuf->x); + IMB_buffer_float_unpremultiply(current_srgb_frect, ibuf->x, height); + /* Clamp buffer colors to 1.0 to avoid artifacts due to glu for hdr images. */ + 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; + VerifyTreadInitData *init_data = (VerifyTreadInitData *) 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) +{ + VerifyThreadData *data = (VerifyThreadData *)data_v; + gpu_verify_high_bit_srgb_buffer_slice(data->srgb_frect, + data->ibuf, + data->start_line, + data->height); + return NULL; +} + +static void gpu_verify_high_bit_srgb_buffer(float *srgb_frect, + ImBuf *ibuf) +{ + if (ibuf->y < 64) { + gpu_verify_high_bit_srgb_buffer_slice(srgb_frect, + ibuf, + 0, ibuf->y); + } + else { + VerifyTreadInitData 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); + } +} + int GPU_verify_image(Image *ima, ImageUser *iuser, int textarget, int tftile, bool compare, bool mipmap, bool is_data) { unsigned int *bind = NULL; @@ -575,17 +650,18 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int textarget, int tftile, bo * a high precision format only if it is available */ use_high_bit_depth = true; } + else if (ibuf->rect == NULL) { + IMB_rect_from_float(ibuf); + } /* we may skip this in high precision, but if not, we need to have a valid buffer here */ else if (ibuf->userflags & IB_RECT_INVALID) { IMB_rect_from_float(ibuf); } /* TODO unneeded when float images are correctly treated as linear always */ - if (!is_data) + if (!is_data) { do_color_management = true; - - if (ibuf->rect == NULL) - IMB_rect_from_float(ibuf); + } } /* currently, tpage refresh is used by ima sequences */ @@ -622,12 +698,7 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int textarget, int tftile, bo if (use_high_bit_depth) { if (do_color_management) { srgb_frect = MEM_mallocN(ibuf->x * ibuf->y * sizeof(float) * 4, "floar_buf_col_cor"); - IMB_buffer_float_from_float(srgb_frect, ibuf->rect_float, - ibuf->channels, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, true, - ibuf->x, ibuf->y, ibuf->x, ibuf->x); - IMB_buffer_float_unpremultiply(srgb_frect, ibuf->x, ibuf->y); - /* clamp buffer colors to 1.0 to avoid artifacts due to glu for hdr images */ - IMB_buffer_float_clamp(srgb_frect, ibuf->x, ibuf->y); + gpu_verify_high_bit_srgb_buffer(srgb_frect, ibuf); frect = srgb_frect + texwinsy * ibuf->x + texwinsx; } else { @@ -650,13 +721,7 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int textarget, int tftile, bo if (use_high_bit_depth) { if (do_color_management) { frect = srgb_frect = MEM_mallocN(ibuf->x * ibuf->y * sizeof(*srgb_frect) * 4, "floar_buf_col_cor"); - IMB_buffer_float_from_float( - srgb_frect, ibuf->rect_float, - ibuf->channels, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, true, - ibuf->x, ibuf->y, ibuf->x, ibuf->x); - IMB_buffer_float_unpremultiply(srgb_frect, ibuf->x, ibuf->y); - /* clamp buffer colors to 1.0 to avoid artifacts due to glu for hdr images */ - IMB_buffer_float_clamp(srgb_frect, ibuf->x, ibuf->y); + gpu_verify_high_bit_srgb_buffer(srgb_frect, ibuf); } else frect = ibuf->rect_float; |