Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brecht@blender.org>2021-01-31 21:35:00 +0300
committerBrecht Van Lommel <brecht@blender.org>2021-02-12 21:06:35 +0300
commit1b4961b318f14064bc3c915da7206a74146af95d (patch)
treefd8168e60333efad3dd0433b5229e2f7f9d97131 /source/blender/imbuf/intern/colormanagement.c
parent6b40ee608c5a1dbe67870fab4b83cce4cc4b54f5 (diff)
OpenColorIO: upgrade to version 2.0.0
Ref T84819 Build System ============ This is an API breaking new version, and the updated code only builds with OpenColorIO 2.0 and later. Adding backwards compatibility was too complicated. * Tinyxml was replaced with Expat, adding a new dependency. * Yaml-cpp is now built as a dependency on Unix, as was already done on Windows. * Removed currently unused LCMS code. * Pystring remains built as part of OCIO itself, since it has no good build system. * Linux and macOS check for the OpenColorIO verison, and disable it if too old. Ref D10270 Processors and Transforms ========================= CPU processors now need to be created to do CPU processing. These are cached internally, but the cache lookup is not fast enough to execute per pixel or texture sample, so for performance these are now also exposed in the C API. The C API for transforms will no longer be needed afer all changes, so remove it to simplify the API and fallback implementation. Ref D10271 Display Transforms ================== Needs a bit more manual work constructing the transform. LegacyViewingPipeline could also have been used, but isn't really any simpler and since it's legacy we better not rely on it. We moved more logic into the opencolorio module, to simplify the API. There is no need to wrap a dozen functions just to be able to do this in C rather than C++. It's also tightly coupled to the GPU shader logic, and so should be in the same module. Ref D10271 GPU Display Shader ================== To avoid baking exposure and gamma into the GLSL shader and requiring slow recompiles when tweaking, we manually apply them in the shader. This leads to some logic duplicaton between the CPU and GPU display processor, but it seems unavoidable. Caching was also changed. Previously this was done both on the imbuf and opencolorio module levels. Now it's all done in the opencolorio module by simply matching color space names. We no longer use cacheIDs from OpenColorIO since computing them is expensive, and they are unlikely to match now that more is baked into the shader code. Shaders can now use multiple 2D textures, 3D textures and uniforms, rather than a single 3D texture. So allocating and binding those adds some code. Color space conversions for blending with overlays is now hardcoded in the shader. This was using harcoded numbers anyway, if this every becomes a general OpenColorIO transform it can be changed, but for now there is no point to add code complexity. Ref D10273 CIE XYZ ======= We need standard CIE XYZ values for rendering effects like blackbody emission. The relation to the scene linear role is based on OpenColorIO configuration. In OpenColorIO 2.0 configs roles can no longer have the same name as color spaces, which means our XYZ role and colorspace in the configuration give an error. Instead use the new standard aces_interchange role, which relates scene linear to a known scene referred color space. Compatibility with the old XYZ role is preserved, if the configuration file has no conflicting names. Also includes a non-functional change to the configuraton file to use an XYZ-to-ACES matrix instead of REC709-to-ACES, makes debugging a little easier since the matrix is the same one we have in the code now and that is also found easily in the ACES specs. Ref D10274
Diffstat (limited to 'source/blender/imbuf/intern/colormanagement.c')
-rw-r--r--source/blender/imbuf/intern/colormanagement.c549
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;
}
}