diff options
Diffstat (limited to 'source/blender/imbuf/intern/colormanagement.c')
-rw-r--r-- | source/blender/imbuf/intern/colormanagement.c | 549 |
1 files changed, 230 insertions, 319 deletions
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index 046e233fd05..8f8c12aa3b4 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -101,40 +101,26 @@ static float imbuf_linear_srgb_to_xyz[3][3] = {{0.0f}}; static pthread_mutex_t processor_lock = BLI_MUTEX_INITIALIZER; typedef struct ColormanageProcessor { - OCIO_ConstProcessorRcPtr *processor; + OCIO_ConstCPUProcessorRcPtr *cpu_processor; CurveMapping *curve_mapping; bool is_data_result; } ColormanageProcessor; -static struct global_glsl_state { - /* Actual processor used for GLSL baked LUTs. */ - /* UI colorspace here refers to the display linear color space, - * i.e: The linear color space w.r.t. display chromaticity and radiometry. - * We separate the colormanagement process into two steps to be able to - * merge UI using alpha blending in the correct color space. */ - OCIO_ConstProcessorRcPtr *processor_scene_to_ui; - OCIO_ConstProcessorRcPtr *processor_ui_to_display; - - /* Settings of processor for comparison. */ - char look[MAX_COLORSPACE_NAME]; - char view[MAX_COLORSPACE_NAME]; - char display[MAX_COLORSPACE_NAME]; - char input[MAX_COLORSPACE_NAME]; - float exposure, gamma; +static struct global_gpu_state { + /* GPU shader currently bound. */ + bool gpu_shader_bound; + /* Curve mapping. */ CurveMapping *curve_mapping, *orig_curve_mapping; bool use_curve_mapping; int curve_mapping_timestamp; OCIO_CurveMappingSettings curve_mapping_settings; - - /* Container for GLSL state needed for OCIO module. */ - struct OCIO_GLSLDrawState *ocio_glsl_state; -} global_glsl_state = {NULL}; +} global_gpu_state = {NULL}; static struct global_color_picking_state { /* Cached processor for color picking conversion. */ - OCIO_ConstProcessorRcPtr *processor_to; - OCIO_ConstProcessorRcPtr *processor_from; + OCIO_ConstCPUProcessorRcPtr *cpu_processor_to; + OCIO_ConstCPUProcessorRcPtr *cpu_processor_from; bool failed; } global_color_picking_state = {NULL}; @@ -609,11 +595,10 @@ static void colormanage_free_config(void) /* free precomputer processors */ if (colorspace->to_scene_linear) { - OCIO_processorRelease((OCIO_ConstProcessorRcPtr *)colorspace->to_scene_linear); + OCIO_cpuProcessorRelease((OCIO_ConstCPUProcessorRcPtr *)colorspace->to_scene_linear); } - if (colorspace->from_scene_linear) { - OCIO_processorRelease((OCIO_ConstProcessorRcPtr *)colorspace->from_scene_linear); + OCIO_cpuProcessorRelease((OCIO_ConstCPUProcessorRcPtr *)colorspace->from_scene_linear); } /* free color space itself */ @@ -631,11 +616,10 @@ static void colormanage_free_config(void) /* free precomputer processors */ if (display->to_scene_linear) { - OCIO_processorRelease((OCIO_ConstProcessorRcPtr *)display->to_scene_linear); + OCIO_cpuProcessorRelease((OCIO_ConstCPUProcessorRcPtr *)display->to_scene_linear); } - if (display->from_scene_linear) { - OCIO_processorRelease((OCIO_ConstProcessorRcPtr *)display->from_scene_linear); + OCIO_cpuProcessorRelease((OCIO_ConstCPUProcessorRcPtr *)display->from_scene_linear); } /* free list of views */ @@ -727,35 +711,25 @@ void colormanagement_init(void) void colormanagement_exit(void) { - if (global_glsl_state.processor_scene_to_ui) { - OCIO_processorRelease(global_glsl_state.processor_scene_to_ui); - } - - if (global_glsl_state.processor_ui_to_display) { - OCIO_processorRelease(global_glsl_state.processor_ui_to_display); - } - - if (global_glsl_state.curve_mapping) { - BKE_curvemapping_free(global_glsl_state.curve_mapping); - } + OCIO_gpuCacheFree(); - if (global_glsl_state.curve_mapping_settings.lut) { - MEM_freeN(global_glsl_state.curve_mapping_settings.lut); + if (global_gpu_state.curve_mapping) { + BKE_curvemapping_free(global_gpu_state.curve_mapping); } - if (global_glsl_state.ocio_glsl_state) { - OCIO_freeOGLState(global_glsl_state.ocio_glsl_state); + if (global_gpu_state.curve_mapping_settings.lut) { + MEM_freeN(global_gpu_state.curve_mapping_settings.lut); } - if (global_color_picking_state.processor_to) { - OCIO_processorRelease(global_color_picking_state.processor_to); + if (global_color_picking_state.cpu_processor_to) { + OCIO_cpuProcessorRelease(global_color_picking_state.cpu_processor_to); } - if (global_color_picking_state.processor_from) { - OCIO_processorRelease(global_color_picking_state.processor_from); + if (global_color_picking_state.cpu_processor_from) { + OCIO_cpuProcessorRelease(global_color_picking_state.cpu_processor_from); } - memset(&global_glsl_state, 0, sizeof(global_glsl_state)); + memset(&global_gpu_state, 0, sizeof(global_gpu_state)); memset(&global_color_picking_state, 0, sizeof(global_color_picking_state)); colormanage_free_config(); @@ -777,6 +751,12 @@ static bool colormanage_compatible_look(ColorManagedLook *look, const char *view return (look->view[0] == 0 || (view_name && STREQ(look->view, view_name))); } +static bool colormanage_use_look(const char *look, const char *view_name) +{ + ColorManagedLook *look_descr = colormanage_look_get_named(look); + return (look_descr->is_noop == false && colormanage_compatible_look(look_descr, view_name)); +} + void colormanage_cache_free(ImBuf *ibuf) { if (ibuf->display_buffer_flags) { @@ -852,95 +832,31 @@ static ColorSpace *display_transform_get_colorspace( return NULL; } -static OCIO_ConstProcessorRcPtr *create_display_buffer_processor(const char *look, - const char *view_transform, - const char *display, - float exposure, - float gamma, - const char *from_colorspace, - const bool linear_output) +static OCIO_ConstCPUProcessorRcPtr *create_display_buffer_processor(const char *look, + const char *view_transform, + const char *display, + float exposure, + float gamma, + const char *from_colorspace) { OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig(); - OCIO_DisplayTransformRcPtr *dt; - OCIO_ConstProcessorRcPtr *processor; - ColorManagedLook *look_descr = colormanage_look_get_named(look); - - dt = OCIO_createDisplayTransform(); - - OCIO_displayTransformSetInputColorSpaceName(dt, from_colorspace); - OCIO_displayTransformSetView(dt, view_transform); - OCIO_displayTransformSetDisplay(dt, display); - - if (look_descr->is_noop == false && colormanage_compatible_look(look_descr, view_transform)) { - OCIO_displayTransformSetLooksOverrideEnabled(dt, true); - OCIO_displayTransformSetLooksOverride(dt, look); - } - - /* fstop exposure control */ - if (exposure != 0.0f) { - OCIO_MatrixTransformRcPtr *mt; - float gain = powf(2.0f, exposure); - const float scale4f[] = {gain, gain, gain, 1.0f}; - float m44[16], offset4[4]; - - OCIO_matrixTransformScale(m44, offset4, scale4f); - mt = OCIO_createMatrixTransform(); - OCIO_matrixTransformSetValue(mt, m44, offset4); - OCIO_displayTransformSetLinearCC(dt, (OCIO_ConstTransformRcPtr *)mt); - - OCIO_matrixTransformRelease(mt); - } - - /* post-display gamma transform */ - if (gamma != 1.0f) { - OCIO_ExponentTransformRcPtr *et; - float exponent = 1.0f / MAX2(FLT_EPSILON, gamma); - const float exponent4f[] = {exponent, exponent, exponent, exponent}; + const bool use_look = colormanage_use_look(look, view_transform); + const float scale = (exposure == 0.0f) ? 1.0f : powf(2.0f, exposure); + const float exponent = (gamma == 1.0f) ? 1.0f : 1.0f / max_ff(FLT_EPSILON, gamma); - et = OCIO_createExponentTransform(); - OCIO_exponentTransformSetValue(et, exponent4f); - OCIO_displayTransformSetDisplayCC(dt, (OCIO_ConstTransformRcPtr *)et); + OCIO_ConstProcessorRcPtr *processor = OCIO_createDisplayProcessor( + config, from_colorspace, view_transform, display, (use_look) ? look : "", scale, exponent); - OCIO_exponentTransformRelease(et); - } - - OCIO_GroupTransformRcPtr *gt = OCIO_createGroupTransform(); - OCIO_groupTransformSetDirection(gt, true); - OCIO_groupTransformPushBack(gt, (OCIO_ConstTransformRcPtr *)dt); - - if (linear_output) { - /* TODO use correct function display. */ - OCIO_ExponentTransformRcPtr *et = OCIO_createExponentTransform(); - OCIO_exponentTransformSetValue(et, (float[4]){2.2f, 2.2f, 2.2f, 1.0f}); - OCIO_groupTransformPushBack(gt, (OCIO_ConstTransformRcPtr *)et); - OCIO_exponentTransformRelease(et); - } - - processor = OCIO_configGetProcessor(config, (OCIO_ConstTransformRcPtr *)gt); - - OCIO_groupTransformRelease(gt); - OCIO_displayTransformRelease(dt); OCIO_configRelease(config); - return processor; -} - -static OCIO_ConstProcessorRcPtr *create_display_encoded_buffer_processor( - const char *UNUSED(display)) -{ - OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig(); - OCIO_ConstProcessorRcPtr *processor; - - /* TODO use correct function display. */ - OCIO_ExponentTransformRcPtr *et = OCIO_createExponentTransform(); - OCIO_exponentTransformSetValue(et, (float[4]){1.0f / 2.2f, 1.0f / 2.2f, 1.0f / 2.2f, 1.0f}); - - processor = OCIO_configGetProcessor(config, (OCIO_ConstTransformRcPtr *)et); + if (processor == NULL) { + return NULL; + } - OCIO_exponentTransformRelease(et); - OCIO_configRelease(config); + OCIO_ConstCPUProcessorRcPtr *cpu_processor = OCIO_processorGetCPUProcessor(processor); + OCIO_processorRelease(processor); - return processor; + return cpu_processor; } static OCIO_ConstProcessorRcPtr *create_colorspace_transform_processor(const char *from_colorspace, @@ -956,43 +872,54 @@ static OCIO_ConstProcessorRcPtr *create_colorspace_transform_processor(const cha return processor; } -static OCIO_ConstProcessorRcPtr *colorspace_to_scene_linear_processor(ColorSpace *colorspace) +static OCIO_ConstCPUProcessorRcPtr *colorspace_to_scene_linear_cpu_processor( + ColorSpace *colorspace) { if (colorspace->to_scene_linear == NULL) { BLI_mutex_lock(&processor_lock); if (colorspace->to_scene_linear == NULL) { - OCIO_ConstProcessorRcPtr *to_scene_linear; - to_scene_linear = create_colorspace_transform_processor(colorspace->name, - global_role_scene_linear); - colorspace->to_scene_linear = (struct OCIO_ConstProcessorRcPtr *)to_scene_linear; + OCIO_ConstProcessorRcPtr *processor = create_colorspace_transform_processor( + colorspace->name, global_role_scene_linear); + + if (processor != NULL) { + colorspace->to_scene_linear = (struct OCIO_ConstCPUProcessorRcPtr *) + OCIO_processorGetCPUProcessor(processor); + OCIO_processorRelease(processor); + } } BLI_mutex_unlock(&processor_lock); } - return (OCIO_ConstProcessorRcPtr *)colorspace->to_scene_linear; + return (OCIO_ConstCPUProcessorRcPtr *)colorspace->to_scene_linear; } -static OCIO_ConstProcessorRcPtr *colorspace_from_scene_linear_processor(ColorSpace *colorspace) +static OCIO_ConstCPUProcessorRcPtr *colorspace_from_scene_linear_cpu_processor( + ColorSpace *colorspace) { if (colorspace->from_scene_linear == NULL) { BLI_mutex_lock(&processor_lock); if (colorspace->from_scene_linear == NULL) { - OCIO_ConstProcessorRcPtr *from_scene_linear; - from_scene_linear = create_colorspace_transform_processor(global_role_scene_linear, - colorspace->name); - colorspace->from_scene_linear = (struct OCIO_ConstProcessorRcPtr *)from_scene_linear; + OCIO_ConstProcessorRcPtr *processor = create_colorspace_transform_processor( + global_role_scene_linear, colorspace->name); + + if (processor != NULL) { + colorspace->from_scene_linear = (struct OCIO_ConstCPUProcessorRcPtr *) + OCIO_processorGetCPUProcessor(processor); + OCIO_processorRelease(processor); + } } BLI_mutex_unlock(&processor_lock); } - return (OCIO_ConstProcessorRcPtr *)colorspace->from_scene_linear; + return (OCIO_ConstCPUProcessorRcPtr *)colorspace->from_scene_linear; } -static OCIO_ConstProcessorRcPtr *display_from_scene_linear_processor(ColorManagedDisplay *display) +static OCIO_ConstCPUProcessorRcPtr *display_from_scene_linear_processor( + ColorManagedDisplay *display) { if (display->from_scene_linear == NULL) { BLI_mutex_lock(&processor_lock); @@ -1011,16 +938,20 @@ static OCIO_ConstProcessorRcPtr *display_from_scene_linear_processor(ColorManage OCIO_configRelease(config); } - display->from_scene_linear = (struct OCIO_ConstProcessorRcPtr *)processor; + if (processor != NULL) { + display->from_scene_linear = (struct OCIO_ConstCPUProcessorRcPtr *) + OCIO_processorGetCPUProcessor(processor); + OCIO_processorRelease(processor); + } } BLI_mutex_unlock(&processor_lock); } - return (OCIO_ConstProcessorRcPtr *)display->from_scene_linear; + return (OCIO_ConstCPUProcessorRcPtr *)display->from_scene_linear; } -static OCIO_ConstProcessorRcPtr *display_to_scene_linear_processor(ColorManagedDisplay *display) +static OCIO_ConstCPUProcessorRcPtr *display_to_scene_linear_processor(ColorManagedDisplay *display) { if (display->to_scene_linear == NULL) { BLI_mutex_lock(&processor_lock); @@ -1039,13 +970,17 @@ static OCIO_ConstProcessorRcPtr *display_to_scene_linear_processor(ColorManagedD OCIO_configRelease(config); } - display->to_scene_linear = (struct OCIO_ConstProcessorRcPtr *)processor; + if (processor != NULL) { + display->to_scene_linear = (struct OCIO_ConstCPUProcessorRcPtr *) + OCIO_processorGetCPUProcessor(processor); + OCIO_processorRelease(processor); + } } BLI_mutex_unlock(&processor_lock); } - return (OCIO_ConstProcessorRcPtr *)display->to_scene_linear; + return (OCIO_ConstCPUProcessorRcPtr *)display->to_scene_linear; } void IMB_colormanagement_init_default_view_settings( @@ -2168,7 +2103,7 @@ void IMB_colormanagement_transform_v4(float pixel[4], */ void IMB_colormanagement_colorspace_to_scene_linear_v3(float pixel[3], ColorSpace *colorspace) { - OCIO_ConstProcessorRcPtr *processor; + OCIO_ConstCPUProcessorRcPtr *processor; if (!colorspace) { /* should never happen */ @@ -2176,17 +2111,17 @@ void IMB_colormanagement_colorspace_to_scene_linear_v3(float pixel[3], ColorSpac return; } - processor = colorspace_to_scene_linear_processor(colorspace); + processor = colorspace_to_scene_linear_cpu_processor(colorspace); - if (processor) { - OCIO_processorApplyRGB(processor, pixel); + if (processor != NULL) { + OCIO_cpuProcessorApplyRGB(processor, pixel); } } /* same as above, but converts colors in opposite direction */ void IMB_colormanagement_scene_linear_to_colorspace_v3(float pixel[3], ColorSpace *colorspace) { - OCIO_ConstProcessorRcPtr *processor; + OCIO_ConstCPUProcessorRcPtr *processor; if (!colorspace) { /* should never happen */ @@ -2194,10 +2129,10 @@ void IMB_colormanagement_scene_linear_to_colorspace_v3(float pixel[3], ColorSpac return; } - processor = colorspace_from_scene_linear_processor(colorspace); + processor = colorspace_from_scene_linear_cpu_processor(colorspace); - if (processor) { - OCIO_processorApplyRGB(processor, pixel); + if (processor != NULL) { + OCIO_cpuProcessorApplyRGB(processor, pixel); } } @@ -2205,7 +2140,7 @@ void IMB_colormanagement_colorspace_to_scene_linear_v4(float pixel[4], bool predivide, ColorSpace *colorspace) { - OCIO_ConstProcessorRcPtr *processor; + OCIO_ConstCPUProcessorRcPtr *processor; if (!colorspace) { /* should never happen */ @@ -2213,14 +2148,14 @@ void IMB_colormanagement_colorspace_to_scene_linear_v4(float pixel[4], return; } - processor = colorspace_to_scene_linear_processor(colorspace); + processor = colorspace_to_scene_linear_cpu_processor(colorspace); - if (processor) { + if (processor != NULL) { if (predivide) { - OCIO_processorApplyRGBA_predivide(processor, pixel); + OCIO_cpuProcessorApplyRGBA_predivide(processor, pixel); } else { - OCIO_processorApplyRGBA(processor, pixel); + OCIO_cpuProcessorApplyRGBA(processor, pixel); } } } @@ -2232,7 +2167,7 @@ void IMB_colormanagement_colorspace_to_scene_linear(float *buffer, struct ColorSpace *colorspace, bool predivide) { - OCIO_ConstProcessorRcPtr *processor; + OCIO_ConstCPUProcessorRcPtr *processor; if (!colorspace) { /* should never happen */ @@ -2240,9 +2175,9 @@ void IMB_colormanagement_colorspace_to_scene_linear(float *buffer, return; } - processor = colorspace_to_scene_linear_processor(colorspace); + processor = colorspace_to_scene_linear_cpu_processor(colorspace); - if (processor) { + if (processor != NULL) { OCIO_PackedImageDesc *img; img = OCIO_createOCIO_PackedImageDesc(buffer, @@ -2254,10 +2189,10 @@ void IMB_colormanagement_colorspace_to_scene_linear(float *buffer, (size_t)channels * sizeof(float) * width); if (predivide) { - OCIO_processorApply_predivide(processor, img); + OCIO_cpuProcessorApply_predivide(processor, img); } else { - OCIO_processorApply(processor, img); + OCIO_cpuProcessorApply(processor, img); } OCIO_PackedImageDescRelease(img); @@ -2278,10 +2213,10 @@ void IMB_colormanagement_imbuf_to_byte_texture(unsigned char *out_buffer, * without precision or performance loss at minimal memory usage. */ BLI_assert(ibuf->rect && ibuf->rect_float == NULL); - OCIO_ConstProcessorRcPtr *processor = NULL; + OCIO_ConstCPUProcessorRcPtr *processor = NULL; if (compress_as_srgb && ibuf->rect_colorspace && !IMB_colormanagement_space_is_srgb(ibuf->rect_colorspace)) { - processor = colorspace_to_scene_linear_processor(ibuf->rect_colorspace); + processor = colorspace_to_scene_linear_cpu_processor(ibuf->rect_colorspace); } /* TODO(brecht): make this multi-threaded, or at least process in batches. */ @@ -2294,12 +2229,12 @@ void IMB_colormanagement_imbuf_to_byte_texture(unsigned char *out_buffer, const unsigned char *in = in_buffer + in_offset * 4; unsigned char *out = out_buffer + out_offset * 4; - if (processor) { + if (processor != NULL) { /* Convert to scene linear, to sRGB and premultiply. */ for (int x = 0; x < width; x++, in += 4, out += 4) { float pixel[4]; rgba_uchar_to_float(pixel, in); - OCIO_processorApplyRGB(processor, pixel); + OCIO_cpuProcessorApplyRGB(processor, pixel); linearrgb_to_srgb_v3_v3(pixel, pixel); if (use_premultiply) { mul_v3_fl(pixel, pixel[3]); @@ -2390,15 +2325,19 @@ void IMB_colormanagement_imbuf_to_float_texture(float *out_buffer, */ void IMB_colormanagement_scene_linear_to_color_picking_v3(float pixel[3]) { - if (!global_color_picking_state.processor_to && !global_color_picking_state.failed) { + if (!global_color_picking_state.cpu_processor_to && !global_color_picking_state.failed) { /* Create processor if none exists. */ BLI_mutex_lock(&processor_lock); - if (!global_color_picking_state.processor_to && !global_color_picking_state.failed) { - global_color_picking_state.processor_to = create_colorspace_transform_processor( + if (!global_color_picking_state.cpu_processor_to && !global_color_picking_state.failed) { + OCIO_ConstProcessorRcPtr *processor = create_colorspace_transform_processor( global_role_scene_linear, global_role_color_picking); - if (!global_color_picking_state.processor_to) { + if (processor != NULL) { + global_color_picking_state.cpu_processor_to = OCIO_processorGetCPUProcessor(processor); + OCIO_processorRelease(processor); + } + else { global_color_picking_state.failed = true; } } @@ -2406,22 +2345,26 @@ void IMB_colormanagement_scene_linear_to_color_picking_v3(float pixel[3]) BLI_mutex_unlock(&processor_lock); } - if (global_color_picking_state.processor_to) { - OCIO_processorApplyRGB(global_color_picking_state.processor_to, pixel); + if (global_color_picking_state.cpu_processor_to) { + OCIO_cpuProcessorApplyRGB(global_color_picking_state.cpu_processor_to, pixel); } } void IMB_colormanagement_color_picking_to_scene_linear_v3(float pixel[3]) { - if (!global_color_picking_state.processor_from && !global_color_picking_state.failed) { + if (!global_color_picking_state.cpu_processor_from && !global_color_picking_state.failed) { /* Create processor if none exists. */ BLI_mutex_lock(&processor_lock); - if (!global_color_picking_state.processor_from && !global_color_picking_state.failed) { - global_color_picking_state.processor_from = create_colorspace_transform_processor( + if (!global_color_picking_state.cpu_processor_from && !global_color_picking_state.failed) { + OCIO_ConstProcessorRcPtr *processor = create_colorspace_transform_processor( global_role_color_picking, global_role_scene_linear); - if (!global_color_picking_state.processor_from) { + if (processor != NULL) { + global_color_picking_state.cpu_processor_from = OCIO_processorGetCPUProcessor(processor); + OCIO_processorRelease(processor); + } + else { global_color_picking_state.failed = true; } } @@ -2429,8 +2372,8 @@ void IMB_colormanagement_color_picking_to_scene_linear_v3(float pixel[3]) BLI_mutex_unlock(&processor_lock); } - if (global_color_picking_state.processor_from) { - OCIO_processorApplyRGB(global_color_picking_state.processor_from, pixel); + if (global_color_picking_state.cpu_processor_from) { + OCIO_cpuProcessorApplyRGB(global_color_picking_state.cpu_processor_from, pixel); } } @@ -2456,24 +2399,20 @@ void IMB_colormanagement_srgb_to_scene_linear_v3(float pixel[3]) */ void IMB_colormanagement_scene_linear_to_display_v3(float pixel[3], ColorManagedDisplay *display) { - OCIO_ConstProcessorRcPtr *processor; - - processor = display_from_scene_linear_processor(display); + OCIO_ConstCPUProcessorRcPtr *processor = display_from_scene_linear_processor(display); - if (processor) { - OCIO_processorApplyRGB(processor, pixel); + if (processor != NULL) { + OCIO_cpuProcessorApplyRGB(processor, pixel); } } /* same as above, but converts color in opposite direction */ void IMB_colormanagement_display_to_scene_linear_v3(float pixel[3], ColorManagedDisplay *display) { - OCIO_ConstProcessorRcPtr *processor; + OCIO_ConstCPUProcessorRcPtr *processor = display_to_scene_linear_processor(display); - processor = display_to_scene_linear_processor(display); - - if (processor) { - OCIO_processorApplyRGB(processor, pixel); + if (processor != NULL) { + OCIO_cpuProcessorApplyRGB(processor, pixel); } } @@ -3833,13 +3772,13 @@ ColormanageProcessor *IMB_colormanagement_display_processor_new( cm_processor->is_data_result = display_space->is_data; } - cm_processor->processor = create_display_buffer_processor(applied_view_settings->look, - applied_view_settings->view_transform, - display_settings->display_device, - applied_view_settings->exposure, - applied_view_settings->gamma, - global_role_scene_linear, - false); + cm_processor->cpu_processor = create_display_buffer_processor( + applied_view_settings->look, + applied_view_settings->view_transform, + display_settings->display_device, + applied_view_settings->exposure, + applied_view_settings->gamma, + global_role_scene_linear); if (applied_view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) { cm_processor->curve_mapping = BKE_curvemapping_copy(applied_view_settings->curve_mapping); @@ -3860,7 +3799,12 @@ ColormanageProcessor *IMB_colormanagement_colorspace_processor_new(const char *f color_space = colormanage_colorspace_get_named(to_colorspace); cm_processor->is_data_result = color_space->is_data; - cm_processor->processor = create_colorspace_transform_processor(from_colorspace, to_colorspace); + OCIO_ConstProcessorRcPtr *processor = create_colorspace_transform_processor(from_colorspace, + to_colorspace); + if (processor != NULL) { + cm_processor->cpu_processor = OCIO_processorGetCPUProcessor(processor); + } + OCIO_processorRelease(processor); return cm_processor; } @@ -3871,8 +3815,8 @@ void IMB_colormanagement_processor_apply_v4(ColormanageProcessor *cm_processor, BKE_curvemapping_evaluate_premulRGBF(cm_processor->curve_mapping, pixel, pixel); } - if (cm_processor->processor) { - OCIO_processorApplyRGBA(cm_processor->processor, pixel); + if (cm_processor->cpu_processor) { + OCIO_cpuProcessorApplyRGBA(cm_processor->cpu_processor, pixel); } } @@ -3883,8 +3827,8 @@ void IMB_colormanagement_processor_apply_v4_predivide(ColormanageProcessor *cm_p BKE_curvemapping_evaluate_premulRGBF(cm_processor->curve_mapping, pixel, pixel); } - if (cm_processor->processor) { - OCIO_processorApplyRGBA_predivide(cm_processor->processor, pixel); + if (cm_processor->cpu_processor) { + OCIO_cpuProcessorApplyRGBA_predivide(cm_processor->cpu_processor, pixel); } } @@ -3894,8 +3838,8 @@ void IMB_colormanagement_processor_apply_v3(ColormanageProcessor *cm_processor, BKE_curvemapping_evaluate_premulRGBF(cm_processor->curve_mapping, pixel, pixel); } - if (cm_processor->processor) { - OCIO_processorApplyRGB(cm_processor->processor, pixel); + if (cm_processor->cpu_processor) { + OCIO_cpuProcessorApplyRGB(cm_processor->cpu_processor, pixel); } } @@ -3940,7 +3884,7 @@ void IMB_colormanagement_processor_apply(ColormanageProcessor *cm_processor, } } - if (cm_processor->processor && channels >= 3) { + if (cm_processor->cpu_processor && channels >= 3) { OCIO_PackedImageDesc *img; /* apply OCIO processor */ @@ -3953,10 +3897,10 @@ void IMB_colormanagement_processor_apply(ColormanageProcessor *cm_processor, (size_t)channels * sizeof(float) * width); if (predivide) { - OCIO_processorApply_predivide(cm_processor->processor, img); + OCIO_cpuProcessorApply_predivide(cm_processor->cpu_processor, img); } else { - OCIO_processorApply(cm_processor->processor, img); + OCIO_cpuProcessorApply(cm_processor->cpu_processor, img); } OCIO_PackedImageDescRelease(img); @@ -3986,8 +3930,8 @@ void IMB_colormanagement_processor_free(ColormanageProcessor *cm_processor) if (cm_processor->curve_mapping) { BKE_curvemapping_free(cm_processor->curve_mapping); } - if (cm_processor->processor) { - OCIO_processorRelease(cm_processor->processor); + if (cm_processor->cpu_processor) { + OCIO_cpuProcessorRelease(cm_processor->cpu_processor); } MEM_freeN(cm_processor); @@ -3995,19 +3939,6 @@ void IMB_colormanagement_processor_free(ColormanageProcessor *cm_processor) /* **** OpenGL drawing routines using GLSL for color space transform ***** */ -static bool check_glsl_display_processor_changed( - const ColorManagedViewSettings *view_settings, - const ColorManagedDisplaySettings *display_settings, - const char *from_colorspace) -{ - return !(global_glsl_state.exposure == view_settings->exposure && - global_glsl_state.gamma == view_settings->gamma && - STREQ(global_glsl_state.look, view_settings->look) && - STREQ(global_glsl_state.view, view_settings->view_transform) && - STREQ(global_glsl_state.display, display_settings->display_device) && - STREQ(global_glsl_state.input, from_colorspace)); -} - static void curve_mapping_to_ocio_settings(CurveMapping *curve_mapping, OCIO_CurveMappingSettings *curve_mapping_settings) { @@ -4041,94 +3972,60 @@ static void curve_mapping_to_ocio_settings(CurveMapping *curve_mapping, curve_mapping_settings->cache_id = (size_t)curve_mapping + curve_mapping->changed_timestamp; } -static void update_glsl_display_processor(const ColorManagedViewSettings *view_settings, - const ColorManagedDisplaySettings *display_settings, - const char *from_colorspace) +static OCIO_CurveMappingSettings *update_glsl_curve_mapping( + const ColorManagedViewSettings *view_settings) { - bool use_curve_mapping = (view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) != 0; - bool need_update = false; - - need_update = global_glsl_state.processor_scene_to_ui == NULL || - check_glsl_display_processor_changed( - view_settings, display_settings, from_colorspace) || - use_curve_mapping != global_glsl_state.use_curve_mapping; - - if (use_curve_mapping && need_update == false) { - need_update |= view_settings->curve_mapping->changed_timestamp != - global_glsl_state.curve_mapping_timestamp || - view_settings->curve_mapping != global_glsl_state.orig_curve_mapping; + /* Using curve mapping? */ + const bool use_curve_mapping = (view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) != 0; + if (!use_curve_mapping) { + return NULL; } - /* Update state if there's no processor yet or - * processor settings has been changed. - */ - if (need_update) { - OCIO_CurveMappingSettings *curve_mapping_settings = &global_glsl_state.curve_mapping_settings; - CurveMapping *new_curve_mapping = NULL; - - /* Store settings of processor for further comparison. */ - BLI_strncpy(global_glsl_state.look, view_settings->look, MAX_COLORSPACE_NAME); - BLI_strncpy(global_glsl_state.view, view_settings->view_transform, MAX_COLORSPACE_NAME); - BLI_strncpy(global_glsl_state.display, display_settings->display_device, MAX_COLORSPACE_NAME); - BLI_strncpy(global_glsl_state.input, from_colorspace, MAX_COLORSPACE_NAME); - global_glsl_state.exposure = view_settings->exposure; - global_glsl_state.gamma = view_settings->gamma; - - /* We're using curve mapping's address as a cache ID, - * so we need to make sure re-allocation gives new address here. - * We do this by allocating new curve mapping before freeing old one. */ - if (use_curve_mapping) { - new_curve_mapping = BKE_curvemapping_copy(view_settings->curve_mapping); - } - - if (global_glsl_state.curve_mapping) { - BKE_curvemapping_free(global_glsl_state.curve_mapping); - MEM_freeN(curve_mapping_settings->lut); - global_glsl_state.curve_mapping = NULL; - curve_mapping_settings->lut = NULL; - } - - /* Fill in OCIO's curve mapping settings. */ - if (use_curve_mapping) { - curve_mapping_to_ocio_settings(new_curve_mapping, &global_glsl_state.curve_mapping_settings); + /* Already up to date? */ + OCIO_CurveMappingSettings *curve_mapping_settings = &global_gpu_state.curve_mapping_settings; + if (view_settings->curve_mapping->changed_timestamp == + global_gpu_state.curve_mapping_timestamp && + view_settings->curve_mapping == global_gpu_state.orig_curve_mapping) { + return curve_mapping_settings; + } - global_glsl_state.curve_mapping = new_curve_mapping; - global_glsl_state.curve_mapping_timestamp = view_settings->curve_mapping->changed_timestamp; - global_glsl_state.orig_curve_mapping = view_settings->curve_mapping; - global_glsl_state.use_curve_mapping = true; - } - else { - global_glsl_state.orig_curve_mapping = NULL; - global_glsl_state.use_curve_mapping = false; - } + /* Need to update. */ + CurveMapping *new_curve_mapping = NULL; - /* Free old processor, if any. */ - if (global_glsl_state.processor_scene_to_ui) { - OCIO_processorRelease(global_glsl_state.processor_scene_to_ui); - } + /* We're using curve mapping's address as a cache ID, + * so we need to make sure re-allocation gives new address here. + * We do this by allocating new curve mapping before freeing old one. */ + if (use_curve_mapping) { + new_curve_mapping = BKE_curvemapping_copy(view_settings->curve_mapping); + } - if (global_glsl_state.processor_ui_to_display) { - OCIO_processorRelease(global_glsl_state.processor_ui_to_display); - } + if (global_gpu_state.curve_mapping) { + BKE_curvemapping_free(global_gpu_state.curve_mapping); + MEM_freeN(curve_mapping_settings->lut); + global_gpu_state.curve_mapping = NULL; + curve_mapping_settings->lut = NULL; + } - /* We're using display OCIO processor, no RGB curves yet. */ - global_glsl_state.processor_scene_to_ui = create_display_buffer_processor( - global_glsl_state.look, - global_glsl_state.view, - global_glsl_state.display, - global_glsl_state.exposure, - global_glsl_state.gamma, - global_glsl_state.input, - true); + /* Fill in OCIO's curve mapping settings. */ + if (use_curve_mapping) { + curve_mapping_to_ocio_settings(new_curve_mapping, &global_gpu_state.curve_mapping_settings); - global_glsl_state.processor_ui_to_display = create_display_encoded_buffer_processor( - global_glsl_state.display); + global_gpu_state.curve_mapping = new_curve_mapping; + global_gpu_state.curve_mapping_timestamp = view_settings->curve_mapping->changed_timestamp; + global_gpu_state.orig_curve_mapping = view_settings->curve_mapping; + global_gpu_state.use_curve_mapping = true; } + else { + global_gpu_state.orig_curve_mapping = NULL; + global_gpu_state.use_curve_mapping = false; + } + + return curve_mapping_settings; } bool IMB_colormanagement_support_glsl_draw(const ColorManagedViewSettings *UNUSED(view_settings)) { - return OCIO_supportGLSLDraw(); + return OCIO_supportGPUShader(); } /** @@ -4165,27 +4062,40 @@ bool IMB_colormanagement_setup_glsl_draw_from_space( applied_view_settings = &default_view_settings; } - /* Make sure OCIO processor is up-to-date. */ - update_glsl_display_processor(applied_view_settings, - display_settings, - from_colorspace ? from_colorspace->name : - global_role_scene_linear); + /* Ensure curve mapping is up to data. */ + OCIO_CurveMappingSettings *curve_mapping_settings = update_glsl_curve_mapping( + applied_view_settings); - if (global_glsl_state.processor_scene_to_ui == NULL) { - /* Happens when requesting non-existing color space or LUT in the - * configuration file does not exist. - */ - return false; - } + /* GPU shader parameters. */ + const char *input = from_colorspace ? from_colorspace->name : global_role_scene_linear; + const char *view = applied_view_settings->view_transform; + const char *display = display_settings->display_device; + const bool use_look = colormanage_use_look(applied_view_settings->look, + applied_view_settings->view_transform); + const char *look = (use_look) ? applied_view_settings->look : ""; + const float exposure = applied_view_settings->exposure; + const float gamma = applied_view_settings->gamma; + const float scale = (exposure == 0.0f) ? 1.0f : powf(2.0f, exposure); + const float exponent = (gamma == 1.0f) ? 1.0f : 1.0f / max_ff(FLT_EPSILON, gamma); + + OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig(); + + /* Bind shader. Internally GPU shaders are created and cached on demand. */ + global_gpu_state.gpu_shader_bound = OCIO_gpuDisplayShaderBind(config, + input, + view, + display, + look, + curve_mapping_settings, + scale, + exponent, + dither, + predivide, + do_overlay_merge); + + OCIO_configRelease(config); - return OCIO_setupGLSLDraw( - &global_glsl_state.ocio_glsl_state, - global_glsl_state.processor_scene_to_ui, - global_glsl_state.processor_ui_to_display, - global_glsl_state.use_curve_mapping ? &global_glsl_state.curve_mapping_settings : NULL, - dither, - predivide, - do_overlay_merge); + return global_gpu_state.gpu_shader_bound; } /* Configures GLSL shader for conversion from scene linear to display space */ @@ -4225,8 +4135,9 @@ bool IMB_colormanagement_setup_glsl_draw_ctx(const bContext *C, float dither, bo /* Finish GLSL-based display space conversion */ void IMB_colormanagement_finish_glsl_draw(void) { - if (global_glsl_state.ocio_glsl_state != NULL) { - OCIO_finishGLSLDraw(global_glsl_state.ocio_glsl_state); + if (global_gpu_state.gpu_shader_bound) { + OCIO_gpuDisplayShaderUnbind(); + global_gpu_state.gpu_shader_bound = false; } } |