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 /intern/opencolorio
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 'intern/opencolorio')
-rw-r--r--intern/opencolorio/fallback_impl.cc366
-rw-r--r--intern/opencolorio/gpu_shader_display_transform.glsl42
-rw-r--r--intern/opencolorio/ocio_capi.cc205
-rw-r--r--intern/opencolorio/ocio_capi.h90
-rw-r--r--intern/opencolorio/ocio_impl.cc361
-rw-r--r--intern/opencolorio/ocio_impl.h247
-rw-r--r--intern/opencolorio/ocio_impl_glsl.cc787
7 files changed, 881 insertions, 1217 deletions
diff --git a/intern/opencolorio/fallback_impl.cc b/intern/opencolorio/fallback_impl.cc
index a6b93ac4959..9bbc9843e9d 100644
--- a/intern/opencolorio/fallback_impl.cc
+++ b/intern/opencolorio/fallback_impl.cc
@@ -34,7 +34,7 @@ using std::max;
enum TransformType {
TRANSFORM_LINEAR_TO_SRGB,
TRANSFORM_SRGB_TO_LINEAR,
- TRANSFORM_MATRIX,
+ TRANSFORM_SCALE,
TRANSFORM_EXPONENT,
TRANSFORM_UNKNOWN,
};
@@ -53,147 +53,72 @@ typedef struct OCIO_PackedImageDescription {
} OCIO_PackedImageDescription;
struct FallbackTransform {
- FallbackTransform() : type(TRANSFORM_UNKNOWN), linear_transform(NULL), display_transform(NULL)
+ FallbackTransform() : type(TRANSFORM_UNKNOWN), scale(1.0f), exponent(1.0f)
{
}
virtual ~FallbackTransform()
{
- delete linear_transform;
- delete display_transform;
}
void applyRGB(float *pixel)
{
if (type == TRANSFORM_LINEAR_TO_SRGB) {
- applyLinearRGB(pixel);
+ pixel[0] *= scale;
+ pixel[1] *= scale;
+ pixel[2] *= scale;
+
linearrgb_to_srgb_v3_v3(pixel, pixel);
- applyDisplayRGB(pixel);
+
+ pixel[0] = powf(max(0.0f, pixel[0]), exponent);
+ pixel[1] = powf(max(0.0f, pixel[1]), exponent);
+ pixel[2] = powf(max(0.0f, pixel[2]), exponent);
}
else if (type == TRANSFORM_SRGB_TO_LINEAR) {
srgb_to_linearrgb_v3_v3(pixel, pixel);
}
else if (type == TRANSFORM_EXPONENT) {
- pixel[0] = powf(max(0.0f, pixel[0]), exponent[0]);
- pixel[1] = powf(max(0.0f, pixel[1]), exponent[1]);
- pixel[2] = powf(max(0.0f, pixel[2]), exponent[2]);
+ pixel[0] = powf(max(0.0f, pixel[0]), exponent);
+ pixel[1] = powf(max(0.0f, pixel[1]), exponent);
+ pixel[2] = powf(max(0.0f, pixel[2]), exponent);
}
- else if (type == TRANSFORM_MATRIX) {
- float r = pixel[0];
- float g = pixel[1];
- float b = pixel[2];
- pixel[0] = r * matrix[0] + g * matrix[1] + b * matrix[2];
- pixel[1] = r * matrix[4] + g * matrix[5] + b * matrix[6];
- pixel[2] = r * matrix[8] + g * matrix[9] + b * matrix[10];
- pixel[0] += offset[0];
- pixel[1] += offset[1];
- pixel[2] += offset[2];
+ else if (type == TRANSFORM_SCALE) {
+ pixel[0] *= scale;
+ pixel[1] *= scale;
+ pixel[2] *= scale;
}
}
void applyRGBA(float *pixel)
{
- if (type == TRANSFORM_LINEAR_TO_SRGB) {
- applyLinearRGBA(pixel);
- linearrgb_to_srgb_v4(pixel, pixel);
- applyDisplayRGBA(pixel);
- }
- else if (type == TRANSFORM_SRGB_TO_LINEAR) {
- srgb_to_linearrgb_v4(pixel, pixel);
- }
- else if (type == TRANSFORM_EXPONENT) {
- pixel[0] = powf(max(0.0f, pixel[0]), exponent[0]);
- pixel[1] = powf(max(0.0f, pixel[1]), exponent[1]);
- pixel[2] = powf(max(0.0f, pixel[2]), exponent[2]);
- pixel[3] = powf(max(0.0f, pixel[3]), exponent[3]);
- }
- else if (type == TRANSFORM_MATRIX) {
- float r = pixel[0];
- float g = pixel[1];
- float b = pixel[2];
- float a = pixel[3];
- pixel[0] = r * matrix[0] + g * matrix[1] + b * matrix[2] + a * matrix[3];
- pixel[1] = r * matrix[4] + g * matrix[5] + b * matrix[6] + a * matrix[7];
- pixel[2] = r * matrix[8] + g * matrix[9] + b * matrix[10] + a * matrix[11];
- pixel[3] = r * matrix[12] + g * matrix[13] + b * matrix[14] + a * matrix[15];
- pixel[0] += offset[0];
- pixel[1] += offset[1];
- pixel[2] += offset[2];
- pixel[3] += offset[3];
- }
- }
-
- void applyLinearRGB(float *pixel)
- {
- if (linear_transform != NULL) {
- linear_transform->applyRGB(pixel);
- }
- }
-
- void applyLinearRGBA(float *pixel)
- {
- if (linear_transform != NULL) {
- linear_transform->applyRGBA(pixel);
- }
- }
-
- void applyDisplayRGB(float *pixel)
- {
- if (display_transform != NULL) {
- display_transform->applyRGB(pixel);
- }
- }
-
- void applyDisplayRGBA(float *pixel)
- {
- if (display_transform != NULL) {
- display_transform->applyRGBA(pixel);
- }
+ applyRGB(pixel);
}
TransformType type;
- FallbackTransform *linear_transform;
- FallbackTransform *display_transform;
+ /* Scale transform. */
+ float scale;
/* Exponent transform. */
- float exponent[4];
- /* Matrix transform. */
- float matrix[16];
- float offset[4];
+ float exponent;
MEM_CXX_CLASS_ALLOC_FUNCS("FallbackTransform");
};
-struct FallbackGroupTransform : FallbackTransform {
- ~FallbackGroupTransform()
- {
- for (auto transform : list) {
- delete transform;
- }
- }
- std::vector<FallbackTransform *> list;
-};
-
struct FallbackProcessor {
- FallbackProcessor() : transform(NULL)
+ FallbackProcessor(const FallbackTransform &transform) : transform(transform)
{
}
- ~FallbackProcessor()
- {
- delete transform;
- }
-
void applyRGB(float *pixel)
{
- transform->applyRGB(pixel);
+ transform.applyRGB(pixel);
}
void applyRGBA(float *pixel)
{
- transform->applyRGBA(pixel);
+ transform.applyRGBA(pixel);
}
- FallbackTransform *transform;
+ FallbackTransform transform;
MEM_CXX_CLASS_ALLOC_FUNCS("FallbackProcessor");
};
@@ -403,30 +328,35 @@ OCIO_ConstProcessorRcPtr *FallbackImpl::configGetProcessorWithNames(OCIO_ConstCo
{
OCIO_ConstColorSpaceRcPtr *cs_src = configGetColorSpace(config, srcName);
OCIO_ConstColorSpaceRcPtr *cs_dst = configGetColorSpace(config, dstName);
- FallbackTransform *transform = new FallbackTransform();
+ FallbackTransform transform;
if (cs_src == COLORSPACE_LINEAR && cs_dst == COLORSPACE_SRGB) {
- transform->type = TRANSFORM_LINEAR_TO_SRGB;
+ transform.type = TRANSFORM_LINEAR_TO_SRGB;
}
else if (cs_src == COLORSPACE_SRGB && cs_dst == COLORSPACE_LINEAR) {
- transform->type = TRANSFORM_SRGB_TO_LINEAR;
+ transform.type = TRANSFORM_SRGB_TO_LINEAR;
}
else {
- transform->type = TRANSFORM_UNKNOWN;
+ transform.type = TRANSFORM_UNKNOWN;
}
- FallbackProcessor *processor = new FallbackProcessor();
- processor->transform = transform;
- return (OCIO_ConstProcessorRcPtr *)processor;
+ return (OCIO_ConstProcessorRcPtr *)new FallbackProcessor(transform);
+}
+
+OCIO_ConstCPUProcessorRcPtr *FallbackImpl::processorGetCPUProcessor(
+ OCIO_ConstProcessorRcPtr *processor)
+{
+ /* Just make a copy of the processor so that we are compatible with OCIO
+ * which does need it as a separate object. */
+ FallbackProcessor *fallback_processor = (FallbackProcessor *)processor;
+ return (OCIO_ConstCPUProcessorRcPtr *)new FallbackProcessor(*fallback_processor);
}
-OCIO_ConstProcessorRcPtr *FallbackImpl::configGetProcessor(OCIO_ConstConfigRcPtr * /*config*/,
- OCIO_ConstTransformRcPtr *transform)
+void FallbackImpl::processorRelease(OCIO_ConstProcessorRcPtr *processor)
{
- FallbackProcessor *processor = new FallbackProcessor();
- processor->transform = (FallbackTransform *)transform;
- return (OCIO_ConstProcessorRcPtr *)processor;
+ delete (FallbackProcessor *)(processor);
}
-void FallbackImpl::processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img)
+void FallbackImpl::cpuProcessorApply(OCIO_ConstCPUProcessorRcPtr *cpu_processor,
+ OCIO_PackedImageDesc *img)
{
/* OCIO_TODO stride not respected, channels must be 3 or 4 */
OCIO_PackedImageDescription *desc = (OCIO_PackedImageDescription *)img;
@@ -441,15 +371,15 @@ void FallbackImpl::processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_Pack
float *pixel = pixels + channels * (y * width + x);
if (channels == 4)
- processorApplyRGBA(processor, pixel);
+ cpuProcessorApplyRGBA(cpu_processor, pixel);
else if (channels == 3)
- processorApplyRGB(processor, pixel);
+ cpuProcessorApplyRGB(cpu_processor, pixel);
}
}
}
-void FallbackImpl::processorApply_predivide(OCIO_ConstProcessorRcPtr *processor,
- OCIO_PackedImageDesc *img)
+void FallbackImpl::cpuProcessorApply_predivide(OCIO_ConstCPUProcessorRcPtr *cpu_processor,
+ OCIO_PackedImageDesc *img)
{
/* OCIO_TODO stride not respected, channels must be 3 or 4 */
OCIO_PackedImageDescription *desc = (OCIO_PackedImageDescription *)img;
@@ -464,27 +394,28 @@ void FallbackImpl::processorApply_predivide(OCIO_ConstProcessorRcPtr *processor,
float *pixel = pixels + channels * (y * width + x);
if (channels == 4)
- processorApplyRGBA_predivide(processor, pixel);
+ cpuProcessorApplyRGBA_predivide(cpu_processor, pixel);
else if (channels == 3)
- processorApplyRGB(processor, pixel);
+ cpuProcessorApplyRGB(cpu_processor, pixel);
}
}
}
-void FallbackImpl::processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel)
+void FallbackImpl::cpuProcessorApplyRGB(OCIO_ConstCPUProcessorRcPtr *cpu_processor, float *pixel)
{
- ((FallbackProcessor *)processor)->applyRGB(pixel);
+ ((FallbackProcessor *)cpu_processor)->applyRGB(pixel);
}
-void FallbackImpl::processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel)
+void FallbackImpl::cpuProcessorApplyRGBA(OCIO_ConstCPUProcessorRcPtr *cpu_processor, float *pixel)
{
- ((FallbackProcessor *)processor)->applyRGBA(pixel);
+ ((FallbackProcessor *)cpu_processor)->applyRGBA(pixel);
}
-void FallbackImpl::processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel)
+void FallbackImpl::cpuProcessorApplyRGBA_predivide(OCIO_ConstCPUProcessorRcPtr *cpu_processor,
+ float *pixel)
{
if (pixel[3] == 1.0f || pixel[3] == 0.0f) {
- processorApplyRGBA(processor, pixel);
+ cpuProcessorApplyRGBA(cpu_processor, pixel);
}
else {
float alpha, inv_alpha;
@@ -496,7 +427,7 @@ void FallbackImpl::processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *proces
pixel[1] *= inv_alpha;
pixel[2] *= inv_alpha;
- processorApplyRGBA(processor, pixel);
+ cpuProcessorApplyRGBA(cpu_processor, pixel);
pixel[0] *= alpha;
pixel[1] *= alpha;
@@ -504,9 +435,9 @@ void FallbackImpl::processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *proces
}
}
-void FallbackImpl::processorRelease(OCIO_ConstProcessorRcPtr *processor)
+void FallbackImpl::cpuProcessorRelease(OCIO_ConstCPUProcessorRcPtr *cpu_processor)
{
- delete (FallbackProcessor *)(processor);
+ delete (FallbackProcessor *)(cpu_processor);
}
const char *FallbackImpl::colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs)
@@ -530,54 +461,20 @@ const char *FallbackImpl::colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr * /*cs*/
return "";
}
-OCIO_DisplayTransformRcPtr *FallbackImpl::createDisplayTransform(void)
-{
- FallbackTransform *transform = new FallbackTransform();
- transform->type = TRANSFORM_LINEAR_TO_SRGB;
- return (OCIO_DisplayTransformRcPtr *)transform;
-}
-
-void FallbackImpl::displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr * /*dt*/,
- const char * /*name*/)
-{
-}
-
-void FallbackImpl::displayTransformSetDisplay(OCIO_DisplayTransformRcPtr * /*dt*/,
- const char * /*name*/)
-{
-}
-
-void FallbackImpl::displayTransformSetView(OCIO_DisplayTransformRcPtr * /*dt*/,
- const char * /*name*/)
-{
-}
-
-void FallbackImpl::displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt,
- OCIO_ConstTransformRcPtr *et)
-{
- FallbackTransform *transform = (FallbackTransform *)dt;
- transform->display_transform = (FallbackTransform *)et;
-}
-
-void FallbackImpl::displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt,
- OCIO_ConstTransformRcPtr *et)
-{
- FallbackTransform *transform = (FallbackTransform *)dt;
- transform->linear_transform = (FallbackTransform *)et;
-}
-
-void FallbackImpl::displayTransformSetLooksOverride(OCIO_DisplayTransformRcPtr * /*dt*/,
- const char * /*looks*/)
-{
-}
-
-void FallbackImpl::displayTransformSetLooksOverrideEnabled(OCIO_DisplayTransformRcPtr * /*dt*/,
- bool /*enabled*/)
+OCIO_ConstProcessorRcPtr *FallbackImpl::createDisplayProcessor(OCIO_ConstConfigRcPtr * /*config*/,
+ const char * /*input*/,
+ const char * /*view*/,
+ const char * /*display*/,
+ const char * /*look*/,
+ const float scale,
+ const float exponent)
{
-}
+ FallbackTransform transform;
+ transform.type = TRANSFORM_LINEAR_TO_SRGB;
+ transform.scale = scale;
+ transform.exponent = exponent;
-void FallbackImpl::displayTransformRelease(OCIO_DisplayTransformRcPtr * /*dt*/)
-{
+ return (OCIO_ConstProcessorRcPtr *)new FallbackProcessor(transform);
}
OCIO_PackedImageDesc *FallbackImpl::createOCIO_PackedImageDesc(float *data,
@@ -605,127 +502,6 @@ void FallbackImpl::OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *id)
MEM_freeN(id);
}
-OCIO_GroupTransformRcPtr *FallbackImpl::createGroupTransform(void)
-{
- FallbackTransform *transform = new FallbackGroupTransform();
- transform->type = TRANSFORM_UNKNOWN;
- return (OCIO_GroupTransformRcPtr *)transform;
-}
-
-void FallbackImpl::groupTransformSetDirection(OCIO_GroupTransformRcPtr * /*gt*/,
- const bool /*forward */)
-{
-}
-
-void FallbackImpl::groupTransformPushBack(OCIO_GroupTransformRcPtr *gt,
- OCIO_ConstTransformRcPtr *transform)
-{
- FallbackGroupTransform *group = (FallbackGroupTransform *)gt;
- group->list.push_back((FallbackTransform *)transform);
-}
-
-void FallbackImpl::groupTransformRelease(OCIO_GroupTransformRcPtr * /*gt*/)
-{
-}
-
-OCIO_ColorSpaceTransformRcPtr *FallbackImpl::createColorSpaceTransform(void)
-{
- FallbackTransform *transform = new FallbackTransform();
- transform->type = TRANSFORM_UNKNOWN;
- return (OCIO_ColorSpaceTransformRcPtr *)transform;
-}
-
-void FallbackImpl::colorSpaceTransformSetSrc(OCIO_ColorSpaceTransformRcPtr * /*ct*/,
- const char * /*name*/)
-{
-}
-
-void FallbackImpl::colorSpaceTransformRelease(OCIO_ColorSpaceTransformRcPtr * /*ct*/)
-{
-}
-
-OCIO_ExponentTransformRcPtr *FallbackImpl::createExponentTransform(void)
-{
- FallbackTransform *transform = new FallbackTransform();
- transform->type = TRANSFORM_EXPONENT;
- return (OCIO_ExponentTransformRcPtr *)transform;
-}
-
-void FallbackImpl::exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et,
- const float *exponent)
-{
- FallbackTransform *transform = (FallbackTransform *)et;
- copy_v4_v4(transform->exponent, exponent);
-}
-
-void FallbackImpl::exponentTransformRelease(OCIO_ExponentTransformRcPtr * /*et*/)
-{
-}
-
-OCIO_MatrixTransformRcPtr *FallbackImpl::createMatrixTransform(void)
-{
- FallbackTransform *transform = new FallbackTransform();
- transform->type = TRANSFORM_MATRIX;
- return (OCIO_MatrixTransformRcPtr *)transform;
-}
-
-void FallbackImpl::matrixTransformSetValue(OCIO_MatrixTransformRcPtr *mt,
- const float *m44,
- const float *offset4)
-{
- FallbackTransform *transform = (FallbackTransform *)mt;
- copy_m4_m4((float(*)[4])transform->matrix, (float(*)[4])m44);
- copy_v4_v4(transform->offset, offset4);
-}
-
-void FallbackImpl::matrixTransformRelease(OCIO_MatrixTransformRcPtr * /*mt*/)
-{
-}
-
-void FallbackImpl::matrixTransformScale(float *m44, float *offset4, const float *scale4)
-{
- if (scale4 == NULL) {
- return;
- }
- if (m44 != NULL) {
- memset(m44, 0, 16 * sizeof(float));
- m44[0] = scale4[0];
- m44[5] = scale4[1];
- m44[10] = scale4[2];
- m44[15] = scale4[3];
- }
- if (offset4 != NULL) {
- offset4[0] = 0.0f;
- offset4[1] = 0.0f;
- offset4[2] = 0.0f;
- offset4[3] = 0.0f;
- }
-}
-
-bool FallbackImpl::supportGLSLDraw(void)
-{
- return false;
-}
-
-bool FallbackImpl::setupGLSLDraw(struct OCIO_GLSLDrawState ** /*state_r*/,
- OCIO_ConstProcessorRcPtr * /*ocio_processor_scene_to_ui*/,
- OCIO_ConstProcessorRcPtr * /*ocio_processor_ui_to_display*/,
- OCIO_CurveMappingSettings * /*curve_mapping_settings*/,
- float /*dither*/,
- bool /*predivide*/,
- bool /*overlay*/)
-{
- return false;
-}
-
-void FallbackImpl::finishGLSLDraw(OCIO_GLSLDrawState * /*state*/)
-{
-}
-
-void FallbackImpl::freeGLState(struct OCIO_GLSLDrawState * /*state_r*/)
-{
-}
-
const char *FallbackImpl::getVersionString(void)
{
return "fallback";
diff --git a/intern/opencolorio/gpu_shader_display_transform.glsl b/intern/opencolorio/gpu_shader_display_transform.glsl
index 61da755f02f..ca0d2566ed1 100644
--- a/intern/opencolorio/gpu_shader_display_transform.glsl
+++ b/intern/opencolorio/gpu_shader_display_transform.glsl
@@ -1,17 +1,18 @@
/* Blender OpenColorIO implementation */
-uniform sampler1D curve_mapping_texture;
uniform sampler2D image_texture;
uniform sampler2D overlay_texture;
-uniform sampler3D lut3d_texture;
-uniform sampler3D lut3d_display_texture;
uniform float dither;
+uniform float scale;
+uniform float exponent;
uniform bool predivide;
-uniform bool curve_mapping;
uniform bool overlay;
-layout(std140) uniform OCIO_GLSLCurveMappingParameters
+#ifdef USE_CURVE_MAPPING
+uniform sampler1D curve_mapping_texture;
+
+layout(std140) uniform OCIO_GPUCurveMappingParameters
{
/* Curve mapping parameters
*
@@ -114,6 +115,7 @@ vec4 curvemapping_evaluate_premulRGBF(vec4 col)
result.a = col.a;
return result;
}
+#endif /* USE_CURVE_MAPPING */
/* Using a triangle distribution which gives a more final uniform noise.
* See Banding in Games:A Noisy Rant(revision 5) Mikkel Gjøl, Playdead (slide 27) */
@@ -145,9 +147,9 @@ vec4 apply_dither(vec4 col, vec2 uv)
vec4 OCIO_ProcessColor(vec4 col, vec4 col_overlay, vec2 noise_uv)
{
- if (curve_mapping) {
- col = curvemapping_evaluate_premulRGBF(col);
- }
+#ifdef USE_CURVE_MAPPING
+ col = curvemapping_evaluate_premulRGBF(col);
+#endif
if (predivide) {
if (col.a > 0.0 && col.a < 1.0) {
@@ -160,15 +162,31 @@ vec4 OCIO_ProcessColor(vec4 col, vec4 col_overlay, vec2 noise_uv)
* for straight alpha at this moment
*/
- col = OCIO_to_display_linear_with_look(col, lut3d_texture);
+ /* Convert to scene linear (usually a no-op). */
+ col = OCIO_to_scene_linear(col);
+
+ /* Apply exposure in scene linear. */
+ col.rgb *= scale;
+
+ /* Convert to display space. */
+ col = OCIO_to_display(col);
+ /* Blend with overlay in UI colorspace.
+ *
+ * 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. */
if (overlay) {
+ col.rgb = pow(col.rgb, vec3(exponent * 2.2));
col = clamp(col, 0.0, 1.0);
col *= 1.0 - col_overlay.a;
col += col_overlay; /* Assumed unassociated alpha. */
+ col.rgb = pow(col.rgb, vec3(1.0 / 2.2));
+ }
+ else {
+ col.rgb = pow(col.rgb, vec3(exponent));
}
-
- col = OCIO_to_display_encoded(col, lut3d_display_texture);
if (dither > 0.0) {
col = apply_dither(col, noise_uv);
@@ -189,4 +207,4 @@ void main()
vec2 noise_uv = round_to_pixel(image_texture, texCoord_interp.st);
fragColor = OCIO_ProcessColor(col, col_overlay, noise_uv);
-} \ No newline at end of file
+}
diff --git a/intern/opencolorio/ocio_capi.cc b/intern/opencolorio/ocio_capi.cc
index 84c36de364c..a7416f82b91 100644
--- a/intern/opencolorio/ocio_capi.cc
+++ b/intern/opencolorio/ocio_capi.cc
@@ -194,40 +194,45 @@ OCIO_ConstProcessorRcPtr *OCIO_configGetProcessorWithNames(OCIO_ConstConfigRcPtr
return impl->configGetProcessorWithNames(config, srcName, dstName);
}
-OCIO_ConstProcessorRcPtr *OCIO_configGetProcessor(OCIO_ConstConfigRcPtr *config,
- OCIO_ConstTransformRcPtr *transform)
+void OCIO_processorRelease(OCIO_ConstProcessorRcPtr *processor)
{
- return impl->configGetProcessor(config, transform);
+ impl->processorRelease(processor);
}
-void OCIO_processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img)
+OCIO_ConstCPUProcessorRcPtr *OCIO_processorGetCPUProcessor(OCIO_ConstProcessorRcPtr *processor)
{
- impl->processorApply(processor, img);
+ return impl->processorGetCPUProcessor(processor);
}
-void OCIO_processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img)
+void OCIO_cpuProcessorApply(OCIO_ConstCPUProcessorRcPtr *cpu_processor, OCIO_PackedImageDesc *img)
{
- impl->processorApply_predivide(processor, img);
+ impl->cpuProcessorApply(cpu_processor, img);
}
-void OCIO_processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel)
+void OCIO_cpuProcessorApply_predivide(OCIO_ConstCPUProcessorRcPtr *cpu_processor,
+ OCIO_PackedImageDesc *img)
{
- impl->processorApplyRGB(processor, pixel);
+ impl->cpuProcessorApply_predivide(cpu_processor, img);
}
-void OCIO_processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel)
+void OCIO_cpuProcessorApplyRGB(OCIO_ConstCPUProcessorRcPtr *cpu_processor, float *pixel)
{
- impl->processorApplyRGBA(processor, pixel);
+ impl->cpuProcessorApplyRGB(cpu_processor, pixel);
}
-void OCIO_processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel)
+void OCIO_cpuProcessorApplyRGBA(OCIO_ConstCPUProcessorRcPtr *cpu_processor, float *pixel)
{
- impl->processorApplyRGBA_predivide(processor, pixel);
+ impl->cpuProcessorApplyRGBA(cpu_processor, pixel);
}
-void OCIO_processorRelease(OCIO_ConstProcessorRcPtr *p)
+void OCIO_cpuProcessorApplyRGBA_predivide(OCIO_ConstCPUProcessorRcPtr *processor, float *pixel)
{
- impl->processorRelease(p);
+ impl->cpuProcessorApplyRGBA_predivide(processor, pixel);
+}
+
+void OCIO_cpuProcessorRelease(OCIO_ConstCPUProcessorRcPtr *cpu_processor)
+{
+ impl->cpuProcessorRelease(cpu_processor);
}
const char *OCIO_colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs)
@@ -245,49 +250,15 @@ const char *OCIO_colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *cs)
return impl->colorSpaceGetFamily(cs);
}
-OCIO_DisplayTransformRcPtr *OCIO_createDisplayTransform(void)
-{
- return impl->createDisplayTransform();
-}
-
-void OCIO_displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr *dt, const char *name)
-{
- impl->displayTransformSetInputColorSpaceName(dt, name);
-}
-
-void OCIO_displayTransformSetDisplay(OCIO_DisplayTransformRcPtr *dt, const char *name)
-{
- impl->displayTransformSetDisplay(dt, name);
-}
-
-void OCIO_displayTransformSetView(OCIO_DisplayTransformRcPtr *dt, const char *name)
-{
- impl->displayTransformSetView(dt, name);
-}
-
-void OCIO_displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *t)
-{
- impl->displayTransformSetDisplayCC(dt, t);
-}
-
-void OCIO_displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *t)
+OCIO_ConstProcessorRcPtr *OCIO_createDisplayProcessor(OCIO_ConstConfigRcPtr *config,
+ const char *input,
+ const char *view,
+ const char *display,
+ const char *look,
+ const float scale,
+ const float exponent)
{
- impl->displayTransformSetLinearCC(dt, t);
-}
-
-void OCIO_displayTransformSetLooksOverride(OCIO_DisplayTransformRcPtr *dt, const char *looks)
-{
- impl->displayTransformSetLooksOverride(dt, looks);
-}
-
-void OCIO_displayTransformSetLooksOverrideEnabled(OCIO_DisplayTransformRcPtr *dt, bool enabled)
-{
- impl->displayTransformSetLooksOverrideEnabled(dt, enabled);
-}
-
-void OCIO_displayTransformRelease(OCIO_DisplayTransformRcPtr *dt)
-{
- impl->displayTransformRelease(dt);
+ return impl->createDisplayProcessor(config, input, view, display, look, scale, exponent);
}
OCIO_PackedImageDesc *OCIO_createOCIO_PackedImageDesc(float *data,
@@ -307,108 +278,44 @@ void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *id)
impl->OCIO_PackedImageDescRelease(id);
}
-OCIO_GroupTransformRcPtr *OCIO_createGroupTransform(void)
-{
- return impl->createGroupTransform();
-}
-
-void OCIO_groupTransformSetDirection(OCIO_GroupTransformRcPtr *gt, const bool forward)
-{
- impl->groupTransformSetDirection(gt, forward);
-}
-
-void OCIO_groupTransformPushBack(OCIO_GroupTransformRcPtr *gt, OCIO_ConstTransformRcPtr *tr)
-{
- impl->groupTransformPushBack(gt, tr);
-}
-
-void OCIO_groupTransformRelease(OCIO_GroupTransformRcPtr *gt)
-{
- impl->groupTransformRelease(gt);
-}
-
-OCIO_ColorSpaceTransformRcPtr *OCIO_createColorSpaceTransform(void)
-{
- return impl->createColorSpaceTransform();
-}
-
-void OCIO_colorSpaceTransformSetSrc(OCIO_ColorSpaceTransformRcPtr *ct, const char *name)
-{
- impl->colorSpaceTransformSetSrc(ct, name);
-}
-
-void OCIO_colorSpaceTransformRelease(OCIO_ColorSpaceTransformRcPtr *ct)
-{
- impl->colorSpaceTransformRelease(ct);
-}
-
-OCIO_ExponentTransformRcPtr *OCIO_createExponentTransform(void)
-{
- return impl->createExponentTransform();
-}
-
-void OCIO_exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent)
-{
- impl->exponentTransformSetValue(et, exponent);
-}
-
-void OCIO_exponentTransformRelease(OCIO_ExponentTransformRcPtr *et)
-{
- impl->exponentTransformRelease(et);
-}
-
-OCIO_MatrixTransformRcPtr *OCIO_createMatrixTransform(void)
-{
- return impl->createMatrixTransform();
-}
-
-void OCIO_matrixTransformSetValue(OCIO_MatrixTransformRcPtr *mt,
- const float *m44,
- const float *offset4)
-{
- impl->matrixTransformSetValue(mt, m44, offset4);
-}
-
-void OCIO_matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt)
-{
- impl->matrixTransformRelease(mt);
-}
-
-void OCIO_matrixTransformScale(float *m44, float *offset4, const float *scale4f)
-{
- impl->matrixTransformScale(m44, offset4, scale4f);
-}
-
-int OCIO_supportGLSLDraw(void)
+bool OCIO_supportGPUShader()
{
- return (int)impl->supportGLSLDraw();
+ return impl->supportGPUShader();
}
-int OCIO_setupGLSLDraw(struct OCIO_GLSLDrawState **state_r,
- OCIO_ConstProcessorRcPtr *ocio_processor_scene_to_ui,
- OCIO_ConstProcessorRcPtr *ocio_processor_ui_to_display,
- OCIO_CurveMappingSettings *curve_mapping_settings,
- float dither,
- bool predivide,
- bool overlay)
+bool OCIO_gpuDisplayShaderBind(OCIO_ConstConfigRcPtr *config,
+ const char *input,
+ const char *view,
+ const char *display,
+ const char *look,
+ OCIO_CurveMappingSettings *curve_mapping_settings,
+ const float scale,
+ const float exponent,
+ const float dither,
+ const bool use_predivide,
+ const bool use_overlay)
{
- return (int)impl->setupGLSLDraw(state_r,
- ocio_processor_scene_to_ui,
- ocio_processor_ui_to_display,
- curve_mapping_settings,
- dither,
- predivide,
- overlay);
+ return impl->gpuDisplayShaderBind(config,
+ input,
+ view,
+ display,
+ look,
+ curve_mapping_settings,
+ scale,
+ exponent,
+ dither,
+ use_predivide,
+ use_overlay);
}
-void OCIO_finishGLSLDraw(struct OCIO_GLSLDrawState *state)
+void OCIO_gpuDisplayShaderUnbind(void)
{
- impl->finishGLSLDraw(state);
+ impl->gpuDisplayShaderUnbind();
}
-void OCIO_freeOGLState(struct OCIO_GLSLDrawState *state)
+void OCIO_gpuCacheFree(void)
{
- impl->freeGLState(state);
+ impl->gpuCacheFree();
}
const char *OCIO_getVersionString(void)
diff --git a/intern/opencolorio/ocio_capi.h b/intern/opencolorio/ocio_capi.h
index 57799222788..8b319d4ed68 100644
--- a/intern/opencolorio/ocio_capi.h
+++ b/intern/opencolorio/ocio_capi.h
@@ -24,7 +24,7 @@
extern "C" {
#endif
-struct OCIO_GLSLDrawState;
+typedef struct OCIO_GPUShader OCIO_GPUShader;
#define OCIO_DECLARE_HANDLE(name) \
typedef struct name##__ { \
@@ -42,14 +42,9 @@ struct OCIO_GLSLDrawState;
OCIO_DECLARE_HANDLE(OCIO_ConstConfigRcPtr);
OCIO_DECLARE_HANDLE(OCIO_ConstColorSpaceRcPtr);
OCIO_DECLARE_HANDLE(OCIO_ConstProcessorRcPtr);
+OCIO_DECLARE_HANDLE(OCIO_ConstCPUProcessorRcPtr);
OCIO_DECLARE_HANDLE(OCIO_ConstContextRcPtr);
OCIO_DECLARE_HANDLE(OCIO_PackedImageDesc);
-OCIO_DECLARE_HANDLE(OCIO_DisplayTransformRcPtr);
-OCIO_DECLARE_HANDLE(OCIO_ConstTransformRcPtr);
-OCIO_DECLARE_HANDLE(OCIO_ColorSpaceTransformRcPtr);
-OCIO_DECLARE_HANDLE(OCIO_ExponentTransformRcPtr);
-OCIO_DECLARE_HANDLE(OCIO_MatrixTransformRcPtr);
-OCIO_DECLARE_HANDLE(OCIO_GroupTransformRcPtr);
OCIO_DECLARE_HANDLE(OCIO_ConstLookRcPtr);
/* Standard XYZ to linear sRGB transform, for fallback. */
@@ -163,32 +158,28 @@ void OCIO_lookRelease(OCIO_ConstLookRcPtr *look);
OCIO_ConstProcessorRcPtr *OCIO_configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config,
const char *srcName,
const char *dstName);
-OCIO_ConstProcessorRcPtr *OCIO_configGetProcessor(OCIO_ConstConfigRcPtr *config,
- OCIO_ConstTransformRcPtr *transform);
+void OCIO_processorRelease(OCIO_ConstProcessorRcPtr *cpu_processor);
-void OCIO_processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img);
-void OCIO_processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img);
-void OCIO_processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel);
-void OCIO_processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel);
-void OCIO_processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel);
-
-void OCIO_processorRelease(OCIO_ConstProcessorRcPtr *p);
+OCIO_ConstCPUProcessorRcPtr *OCIO_processorGetCPUProcessor(OCIO_ConstProcessorRcPtr *processor);
+void OCIO_cpuProcessorApply(OCIO_ConstCPUProcessorRcPtr *cpu_processor, OCIO_PackedImageDesc *img);
+void OCIO_cpuProcessorApply_predivide(OCIO_ConstCPUProcessorRcPtr *cpu_processor,
+ OCIO_PackedImageDesc *img);
+void OCIO_cpuProcessorApplyRGB(OCIO_ConstCPUProcessorRcPtr *cpu_processor, float *pixel);
+void OCIO_cpuProcessorApplyRGBA(OCIO_ConstCPUProcessorRcPtr *cpu_processor, float *pixel);
+void OCIO_cpuProcessorApplyRGBA_predivide(OCIO_ConstCPUProcessorRcPtr *cpu_processor, float *pixel);
+void OCIO_cpuProcessorRelease(OCIO_ConstCPUProcessorRcPtr *processor);
const char *OCIO_colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs);
const char *OCIO_colorSpaceGetDescription(OCIO_ConstColorSpaceRcPtr *cs);
const char *OCIO_colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *cs);
-OCIO_DisplayTransformRcPtr *OCIO_createDisplayTransform(void);
-void OCIO_displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr *dt, const char *name);
-void OCIO_displayTransformSetDisplay(OCIO_DisplayTransformRcPtr *dt, const char *name);
-void OCIO_displayTransformSetView(OCIO_DisplayTransformRcPtr *dt, const char *name);
-void OCIO_displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt,
- OCIO_ConstTransformRcPtr *et);
-void OCIO_displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt,
- OCIO_ConstTransformRcPtr *et);
-void OCIO_displayTransformSetLooksOverride(OCIO_DisplayTransformRcPtr *dt, const char *looks);
-void OCIO_displayTransformSetLooksOverrideEnabled(OCIO_DisplayTransformRcPtr *dt, bool enabled);
-void OCIO_displayTransformRelease(OCIO_DisplayTransformRcPtr *dt);
+OCIO_ConstProcessorRcPtr *OCIO_createDisplayProcessor(OCIO_ConstConfigRcPtr *config,
+ const char *input,
+ const char *view,
+ const char *display,
+ const char *look,
+ const float scale,
+ const float exponent);
OCIO_PackedImageDesc *OCIO_createOCIO_PackedImageDesc(float *data,
long width,
@@ -200,37 +191,20 @@ OCIO_PackedImageDesc *OCIO_createOCIO_PackedImageDesc(float *data,
void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p);
-OCIO_GroupTransformRcPtr *OCIO_createGroupTransform(void);
-void OCIO_groupTransformSetDirection(OCIO_GroupTransformRcPtr *gt, const bool forward);
-void OCIO_groupTransformPushBack(OCIO_GroupTransformRcPtr *gt, OCIO_ConstTransformRcPtr *tr);
-void OCIO_groupTransformRelease(OCIO_GroupTransformRcPtr *gt);
-
-OCIO_ColorSpaceTransformRcPtr *OCIO_createColorSpaceTransform(void);
-void OCIO_colorSpaceTransformSetSrc(OCIO_ColorSpaceTransformRcPtr *ct, const char *name);
-void OCIO_colorSpaceTransformRelease(OCIO_ColorSpaceTransformRcPtr *ct);
-
-OCIO_ExponentTransformRcPtr *OCIO_createExponentTransform(void);
-void OCIO_exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent);
-void OCIO_exponentTransformRelease(OCIO_ExponentTransformRcPtr *et);
-
-OCIO_MatrixTransformRcPtr *OCIO_createMatrixTransform(void);
-void OCIO_matrixTransformSetValue(OCIO_MatrixTransformRcPtr *mt,
- const float *m44,
- const float *offset4);
-void OCIO_matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt);
-
-void OCIO_matrixTransformScale(float *m44, float *offset4, const float *scale4);
-
-int OCIO_supportGLSLDraw(void);
-int OCIO_setupGLSLDraw(struct OCIO_GLSLDrawState **state_r,
- OCIO_ConstProcessorRcPtr *ocio_processor_scene_to_ui,
- OCIO_ConstProcessorRcPtr *ocio_processor_ui_to_display,
- OCIO_CurveMappingSettings *curve_mapping_settings,
- float dither,
- bool predivide,
- bool overlay);
-void OCIO_finishGLSLDraw(struct OCIO_GLSLDrawState *state);
-void OCIO_freeOGLState(struct OCIO_GLSLDrawState *state);
+bool OCIO_supportGPUShader(void);
+bool OCIO_gpuDisplayShaderBind(OCIO_ConstConfigRcPtr *config,
+ const char *input,
+ const char *view,
+ const char *display,
+ const char *look,
+ OCIO_CurveMappingSettings *curve_mapping_settings,
+ const float scale,
+ const float exponent,
+ const float dither,
+ const bool use_predivide,
+ const bool use_overlay);
+void OCIO_gpuDisplayShaderUnbind(void);
+void OCIO_gpuCacheFree(void);
const char *OCIO_getVersionString(void);
int OCIO_getVersionHex(void);
diff --git a/intern/opencolorio/ocio_impl.cc b/intern/opencolorio/ocio_impl.cc
index cf3571b4662..69a8d8b17af 100644
--- a/intern/opencolorio/ocio_impl.cc
+++ b/intern/opencolorio/ocio_impl.cc
@@ -17,6 +17,7 @@
* All rights reserved.
*/
+#include <cassert>
#include <iostream>
#include <math.h>
#include <sstream>
@@ -35,7 +36,9 @@ using namespace OCIO_NAMESPACE;
#include "MEM_guardedalloc.h"
+#include "BLI_math.h"
#include "BLI_math_color.h"
+#include "BLI_math_matrix.h"
#include "ocio_impl.h"
@@ -267,7 +270,7 @@ const char *OCIOImpl::configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *conf
const char *view)
{
try {
- return (*(ConstConfigRcPtr *)config)->getDisplayColorSpaceName(display, view);
+ return (*(ConstConfigRcPtr *)config)->getDisplayViewColorSpaceName(display, view);
}
catch (Exception &exception) {
OCIO_reportException(exception);
@@ -279,13 +282,46 @@ const char *OCIOImpl::configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *conf
void OCIOImpl::configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr *config, float *rgb)
{
try {
- (*(ConstConfigRcPtr *)config)->getDefaultLumaCoefs(rgb);
+ double rgb_double[3];
+ (*(ConstConfigRcPtr *)config)->getDefaultLumaCoefs(rgb_double);
+ rgb[0] = rgb_double[0];
+ rgb[1] = rgb_double[1];
+ rgb[2] = rgb_double[2];
}
catch (Exception &exception) {
OCIO_reportException(exception);
}
}
+static bool to_scene_linear_matrix(ConstConfigRcPtr &config,
+ const char *colorspace,
+ float to_scene_linear[3][3])
+{
+ ConstProcessorRcPtr processor;
+ try {
+ processor = config->getProcessor(colorspace, ROLE_SCENE_LINEAR);
+ }
+ catch (Exception &exception) {
+ OCIO_reportException(exception);
+ return false;
+ }
+
+ if (!processor) {
+ return false;
+ }
+
+ ConstCPUProcessorRcPtr cpu_processor = processor->getDefaultCPUProcessor();
+ if (!cpu_processor) {
+ return false;
+ }
+
+ unit_m3(to_scene_linear);
+ cpu_processor->applyRGB(to_scene_linear[0]);
+ cpu_processor->applyRGB(to_scene_linear[1]);
+ cpu_processor->applyRGB(to_scene_linear[2]);
+ return true;
+}
+
void OCIOImpl::configGetXYZtoRGB(OCIO_ConstConfigRcPtr *config_, float xyz_to_rgb[3][3])
{
ConstConfigRcPtr config = (*(ConstConfigRcPtr *)config_);
@@ -293,24 +329,25 @@ void OCIOImpl::configGetXYZtoRGB(OCIO_ConstConfigRcPtr *config_, float xyz_to_rg
/* Default to ITU-BT.709 in case no appropriate transform found. */
memcpy(xyz_to_rgb, OCIO_XYZ_TO_LINEAR_SRGB, sizeof(OCIO_XYZ_TO_LINEAR_SRGB));
- /* Auto estimate from XYZ and scene_linear roles, assumed to be a linear transform. */
- if (config->hasRole("XYZ") && config->hasRole("scene_linear")) {
- ConstProcessorRcPtr to_rgb_processor = config->getProcessor("XYZ", "scene_linear");
- if (to_rgb_processor) {
- xyz_to_rgb[0][0] = 1.0f;
- xyz_to_rgb[0][1] = 0.0f;
- xyz_to_rgb[0][2] = 0.0f;
- xyz_to_rgb[1][0] = 0.0f;
- xyz_to_rgb[1][1] = 1.0f;
- xyz_to_rgb[1][2] = 0.0f;
- xyz_to_rgb[2][0] = 0.0f;
- xyz_to_rgb[2][1] = 0.0f;
- xyz_to_rgb[2][2] = 1.0f;
- to_rgb_processor->applyRGB(xyz_to_rgb[0]);
- to_rgb_processor->applyRGB(xyz_to_rgb[1]);
- to_rgb_processor->applyRGB(xyz_to_rgb[2]);
+ /* Get from OpenColorO config if it has the required roles. */
+ if (!config->hasRole(ROLE_SCENE_LINEAR)) {
+ return;
+ }
+
+ if (config->hasRole("aces_interchange")) {
+ /* Standard OpenColorIO role, defined as ACES2065-1. */
+ const float xyz_to_aces[3][3] = {{1.0498110175f, -0.4959030231f, 0.0f},
+ {0.0f, 1.3733130458f, 0.0f},
+ {-0.0000974845f, 0.0982400361f, 0.9912520182f}};
+ float aces_to_rgb[3][3];
+ if (to_scene_linear_matrix(config, "aces_interchange", aces_to_rgb)) {
+ mul_m3_m3m3(xyz_to_rgb, aces_to_rgb, xyz_to_aces);
}
}
+ else if (config->hasRole("XYZ")) {
+ /* Custom role used before the standard existed. */
+ to_scene_linear_matrix(config, "XYZ", xyz_to_rgb);
+ }
}
int OCIOImpl::configGetNumLooks(OCIO_ConstConfigRcPtr *config)
@@ -431,6 +468,8 @@ void OCIOImpl::colorSpaceIsBuiltin(OCIO_ConstConfigRcPtr *config_,
return;
}
+ ConstCPUProcessorRcPtr cpu_processor = processor->getDefaultCPUProcessor();
+
is_scene_linear = true;
is_srgb = true;
for (int i = 0; i < 256; i++) {
@@ -440,10 +479,10 @@ void OCIOImpl::colorSpaceIsBuiltin(OCIO_ConstConfigRcPtr *config_,
float cG[3] = {0, v, 0};
float cB[3] = {0, 0, v};
float cW[3] = {v, v, v};
- processor->applyRGB(cR);
- processor->applyRGB(cG);
- processor->applyRGB(cB);
- processor->applyRGB(cW);
+ cpu_processor->applyRGB(cR);
+ cpu_processor->applyRGB(cG);
+ cpu_processor->applyRGB(cB);
+ cpu_processor->applyRGB(cW);
/* Make sure that there is no channel crosstalk. */
if (fabsf(cR[1]) > 1e-5f || fabsf(cR[2]) > 1e-5f || fabsf(cG[0]) > 1e-5f ||
@@ -485,62 +524,57 @@ OCIO_ConstProcessorRcPtr *OCIOImpl::configGetProcessorWithNames(OCIO_ConstConfig
const char *srcName,
const char *dstName)
{
- ConstProcessorRcPtr *p = OBJECT_GUARDED_NEW(ConstProcessorRcPtr);
+ ConstProcessorRcPtr *processor = OBJECT_GUARDED_NEW(ConstProcessorRcPtr);
try {
- *p = (*(ConstConfigRcPtr *)config)->getProcessor(srcName, dstName);
+ *processor = (*(ConstConfigRcPtr *)config)->getProcessor(srcName, dstName);
- if (*p)
- return (OCIO_ConstProcessorRcPtr *)p;
+ if (*processor)
+ return (OCIO_ConstProcessorRcPtr *)processor;
}
catch (Exception &exception) {
OCIO_reportException(exception);
}
- OBJECT_GUARDED_DELETE(p, ConstProcessorRcPtr);
+ OBJECT_GUARDED_DELETE(processor, ConstProcessorRcPtr);
return 0;
}
-OCIO_ConstProcessorRcPtr *OCIOImpl::configGetProcessor(OCIO_ConstConfigRcPtr *config,
- OCIO_ConstTransformRcPtr *transform)
+void OCIOImpl::processorRelease(OCIO_ConstProcessorRcPtr *processor)
{
- ConstProcessorRcPtr *p = OBJECT_GUARDED_NEW(ConstProcessorRcPtr);
-
- try {
- *p = (*(ConstConfigRcPtr *)config)->getProcessor(*(ConstTransformRcPtr *)transform);
-
- if (*p)
- return (OCIO_ConstProcessorRcPtr *)p;
- }
- catch (Exception &exception) {
- OCIO_reportException(exception);
- }
-
- OBJECT_GUARDED_DELETE(p, ConstProcessorRcPtr);
+ OBJECT_GUARDED_DELETE(processor, ConstProcessorRcPtr);
+}
- return NULL;
+OCIO_ConstCPUProcessorRcPtr *OCIOImpl::processorGetCPUProcessor(
+ OCIO_ConstProcessorRcPtr *processor)
+{
+ ConstCPUProcessorRcPtr *cpu_processor = OBJECT_GUARDED_NEW(ConstCPUProcessorRcPtr);
+ *cpu_processor = (*(ConstProcessorRcPtr *)processor)->getDefaultCPUProcessor();
+ return (OCIO_ConstCPUProcessorRcPtr *)cpu_processor;
}
-void OCIOImpl::processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img)
+void OCIOImpl::cpuProcessorApply(OCIO_ConstCPUProcessorRcPtr *cpu_processor,
+ OCIO_PackedImageDesc *img)
{
try {
- (*(ConstProcessorRcPtr *)processor)->apply(*(PackedImageDesc *)img);
+ (*(ConstCPUProcessorRcPtr *)cpu_processor)->apply(*(PackedImageDesc *)img);
}
catch (Exception &exception) {
OCIO_reportException(exception);
}
}
-void OCIOImpl::processorApply_predivide(OCIO_ConstProcessorRcPtr *processor,
- OCIO_PackedImageDesc *img_)
+void OCIOImpl::cpuProcessorApply_predivide(OCIO_ConstCPUProcessorRcPtr *cpu_processor,
+ OCIO_PackedImageDesc *img_)
{
try {
PackedImageDesc *img = (PackedImageDesc *)img_;
int channels = img->getNumChannels();
if (channels == 4) {
- float *pixels = img->getData();
+ assert(img->isFloat());
+ float *pixels = (float *)img->getData();
int width = img->getWidth();
int height = img->getHeight();
@@ -549,12 +583,12 @@ void OCIOImpl::processorApply_predivide(OCIO_ConstProcessorRcPtr *processor,
for (int x = 0; x < width; x++) {
float *pixel = pixels + 4 * (y * width + x);
- processorApplyRGBA_predivide(processor, pixel);
+ cpuProcessorApplyRGBA_predivide(cpu_processor, pixel);
}
}
}
else {
- (*(ConstProcessorRcPtr *)processor)->apply(*img);
+ (*(ConstCPUProcessorRcPtr *)cpu_processor)->apply(*img);
}
}
catch (Exception &exception) {
@@ -562,20 +596,21 @@ void OCIOImpl::processorApply_predivide(OCIO_ConstProcessorRcPtr *processor,
}
}
-void OCIOImpl::processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel)
+void OCIOImpl::cpuProcessorApplyRGB(OCIO_ConstCPUProcessorRcPtr *cpu_processor, float *pixel)
{
- (*(ConstProcessorRcPtr *)processor)->applyRGB(pixel);
+ (*(ConstCPUProcessorRcPtr *)cpu_processor)->applyRGB(pixel);
}
-void OCIOImpl::processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel)
+void OCIOImpl::cpuProcessorApplyRGBA(OCIO_ConstCPUProcessorRcPtr *cpu_processor, float *pixel)
{
- (*(ConstProcessorRcPtr *)processor)->applyRGBA(pixel);
+ (*(ConstCPUProcessorRcPtr *)cpu_processor)->applyRGBA(pixel);
}
-void OCIOImpl::processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel)
+void OCIOImpl::cpuProcessorApplyRGBA_predivide(OCIO_ConstCPUProcessorRcPtr *cpu_processor,
+ float *pixel)
{
if (pixel[3] == 1.0f || pixel[3] == 0.0f) {
- (*(ConstProcessorRcPtr *)processor)->applyRGBA(pixel);
+ (*(ConstCPUProcessorRcPtr *)cpu_processor)->applyRGBA(pixel);
}
else {
float alpha, inv_alpha;
@@ -587,7 +622,7 @@ void OCIOImpl::processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor,
pixel[1] *= inv_alpha;
pixel[2] *= inv_alpha;
- (*(ConstProcessorRcPtr *)processor)->applyRGBA(pixel);
+ (*(ConstCPUProcessorRcPtr *)cpu_processor)->applyRGBA(pixel);
pixel[0] *= alpha;
pixel[1] *= alpha;
@@ -595,9 +630,9 @@ void OCIOImpl::processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor,
}
}
-void OCIOImpl::processorRelease(OCIO_ConstProcessorRcPtr *p)
+void OCIOImpl::cpuProcessorRelease(OCIO_ConstCPUProcessorRcPtr *cpu_processor)
{
- OBJECT_GUARDED_DELETE(p, ConstProcessorRcPtr);
+ OBJECT_GUARDED_DELETE(cpu_processor, ConstCPUProcessorRcPtr);
}
const char *OCIOImpl::colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs)
@@ -615,57 +650,85 @@ const char *OCIOImpl::colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *cs)
return (*(ConstColorSpaceRcPtr *)cs)->getFamily();
}
-OCIO_DisplayTransformRcPtr *OCIOImpl::createDisplayTransform(void)
+OCIO_ConstProcessorRcPtr *OCIOImpl::createDisplayProcessor(OCIO_ConstConfigRcPtr *config_,
+ const char *input,
+ const char *view,
+ const char *display,
+ const char *look,
+ const float scale,
+ const float exponent)
+
{
- DisplayTransformRcPtr *dt = OBJECT_GUARDED_NEW(DisplayTransformRcPtr);
+ ConstConfigRcPtr config = *(ConstConfigRcPtr *)config_;
+ GroupTransformRcPtr group = GroupTransform::Create();
- *dt = DisplayTransform::Create();
+ /* Exposure. */
+ if (scale != 1.0f) {
+ /* Always apply exposure in scene linear. */
+ ColorSpaceTransformRcPtr ct = ColorSpaceTransform::Create();
+ ct->setSrc(input);
+ ct->setDst(ROLE_SCENE_LINEAR);
+ group->appendTransform(ct);
- return (OCIO_DisplayTransformRcPtr *)dt;
-}
+ /* Make further transforms aware of the color space change. */
+ input = ROLE_SCENE_LINEAR;
-void OCIOImpl::displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr *dt,
- const char *name)
-{
- (*(DisplayTransformRcPtr *)dt)->setInputColorSpaceName(name);
-}
+ /* Apply scale. */
+ MatrixTransformRcPtr mt = MatrixTransform::Create();
+ const double matrix[16] = {
+ scale, 0.0, 0.0, 0.0, 0.0, scale, 0.0, 0.0, 0.0, 0.0, scale, 0.0, 0.0, 0.0, 0.0, 1.0};
+ mt->setMatrix(matrix);
+ group->appendTransform(mt);
+ }
-void OCIOImpl::displayTransformSetDisplay(OCIO_DisplayTransformRcPtr *dt, const char *name)
-{
- (*(DisplayTransformRcPtr *)dt)->setDisplay(name);
-}
+ /* Add look transform. */
+ const bool use_look = (strlen(look) != 0);
+ if (use_look) {
+ const char *look_output = LookTransform::GetLooksResultColorSpace(
+ config, config->getCurrentContext(), look);
-void OCIOImpl::displayTransformSetView(OCIO_DisplayTransformRcPtr *dt, const char *name)
-{
- (*(DisplayTransformRcPtr *)dt)->setView(name);
-}
+ LookTransformRcPtr lt = LookTransform::Create();
+ lt->setSrc(input);
+ lt->setDst(look_output);
+ lt->setLooks(look);
+ group->appendTransform(lt);
-void OCIOImpl::displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt,
- OCIO_ConstTransformRcPtr *t)
-{
- (*(DisplayTransformRcPtr *)dt)->setDisplayCC(*(ConstTransformRcPtr *)t);
-}
+ /* Make further transforms aware of the color space change. */
+ input = look_output;
+ }
-void OCIOImpl::displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt,
- OCIO_ConstTransformRcPtr *t)
-{
- (*(DisplayTransformRcPtr *)dt)->setLinearCC(*(ConstTransformRcPtr *)t);
-}
+ /* Add view and display transform. */
+ DisplayViewTransformRcPtr dvt = DisplayViewTransform::Create();
+ dvt->setSrc(input);
+ dvt->setLooksBypass(use_look);
+ dvt->setView(view);
+ dvt->setDisplay(display);
+ group->appendTransform(dvt);
-void OCIOImpl::displayTransformSetLooksOverride(OCIO_DisplayTransformRcPtr *dt, const char *looks)
-{
- (*(DisplayTransformRcPtr *)dt)->setLooksOverride(looks);
-}
+ /* Gamma. */
+ if (exponent != 1.0f) {
+ ExponentTransformRcPtr et = ExponentTransform::Create();
+ const double value[4] = {exponent, exponent, exponent, 1.0};
+ et->setValue(value);
+ group->appendTransform(et);
+ }
-void OCIOImpl::displayTransformSetLooksOverrideEnabled(OCIO_DisplayTransformRcPtr *dt,
- bool enabled)
-{
- (*(DisplayTransformRcPtr *)dt)->setLooksOverrideEnabled(enabled);
-}
+ /* Create processor from transform. This is the moment were OCIO validates
+ * the entire transform, no need to check for the validity of inputs above. */
+ ConstProcessorRcPtr *p = OBJECT_GUARDED_NEW(ConstProcessorRcPtr);
-void OCIOImpl::displayTransformRelease(OCIO_DisplayTransformRcPtr *dt)
-{
- OBJECT_GUARDED_DELETE((DisplayTransformRcPtr *)dt, DisplayTransformRcPtr);
+ try {
+ *p = config->getProcessor(group);
+
+ if (*p)
+ return (OCIO_ConstProcessorRcPtr *)p;
+ }
+ catch (Exception &exception) {
+ OCIO_reportException(exception);
+ }
+
+ OBJECT_GUARDED_DELETE(p, ConstProcessorRcPtr);
+ return NULL;
}
OCIO_PackedImageDesc *OCIOImpl::createOCIO_PackedImageDesc(float *data,
@@ -678,8 +741,14 @@ OCIO_PackedImageDesc *OCIOImpl::createOCIO_PackedImageDesc(float *data,
{
try {
void *mem = MEM_mallocN(sizeof(PackedImageDesc), __func__);
- PackedImageDesc *id = new (mem) PackedImageDesc(
- data, width, height, numChannels, chanStrideBytes, xStrideBytes, yStrideBytes);
+ PackedImageDesc *id = new (mem) PackedImageDesc(data,
+ width,
+ height,
+ numChannels,
+ BIT_DEPTH_F32,
+ chanStrideBytes,
+ xStrideBytes,
+ yStrideBytes);
return (OCIO_PackedImageDesc *)id;
}
@@ -695,96 +764,6 @@ void OCIOImpl::OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *id)
OBJECT_GUARDED_DELETE((PackedImageDesc *)id, PackedImageDesc);
}
-OCIO_GroupTransformRcPtr *OCIOImpl::createGroupTransform(void)
-{
- GroupTransformRcPtr *gt = OBJECT_GUARDED_NEW(GroupTransformRcPtr);
-
- *gt = GroupTransform::Create();
-
- return (OCIO_GroupTransformRcPtr *)gt;
-}
-
-void OCIOImpl::groupTransformSetDirection(OCIO_GroupTransformRcPtr *gt, const bool forward)
-{
- TransformDirection dir = forward ? TRANSFORM_DIR_FORWARD : TRANSFORM_DIR_INVERSE;
- (*(GroupTransformRcPtr *)gt)->setDirection(dir);
-}
-
-void OCIOImpl::groupTransformPushBack(OCIO_GroupTransformRcPtr *gt, OCIO_ConstTransformRcPtr *tr)
-{
- (*(GroupTransformRcPtr *)gt)->push_back(*(ConstTransformRcPtr *)tr);
-}
-
-void OCIOImpl::groupTransformRelease(OCIO_GroupTransformRcPtr *gt)
-{
- OBJECT_GUARDED_DELETE((GroupTransformRcPtr *)gt, GroupTransformRcPtr);
-}
-
-OCIO_ColorSpaceTransformRcPtr *OCIOImpl::createColorSpaceTransform(void)
-{
- ColorSpaceTransformRcPtr *ct = OBJECT_GUARDED_NEW(ColorSpaceTransformRcPtr);
-
- *ct = ColorSpaceTransform::Create();
- (*ct)->setDirection(TRANSFORM_DIR_FORWARD);
-
- return (OCIO_ColorSpaceTransformRcPtr *)ct;
-}
-
-void OCIOImpl::colorSpaceTransformSetSrc(OCIO_ColorSpaceTransformRcPtr *ct, const char *name)
-{
- (*(ColorSpaceTransformRcPtr *)ct)->setSrc(name);
-}
-
-void OCIOImpl::colorSpaceTransformRelease(OCIO_ColorSpaceTransformRcPtr *ct)
-{
- OBJECT_GUARDED_DELETE((ColorSpaceTransformRcPtr *)ct, ColorSpaceTransformRcPtr);
-}
-
-OCIO_ExponentTransformRcPtr *OCIOImpl::createExponentTransform(void)
-{
- ExponentTransformRcPtr *et = OBJECT_GUARDED_NEW(ExponentTransformRcPtr);
-
- *et = ExponentTransform::Create();
-
- return (OCIO_ExponentTransformRcPtr *)et;
-}
-
-void OCIOImpl::exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent)
-{
- (*(ExponentTransformRcPtr *)et)->setValue(exponent);
-}
-
-void OCIOImpl::exponentTransformRelease(OCIO_ExponentTransformRcPtr *et)
-{
- OBJECT_GUARDED_DELETE((ExponentTransformRcPtr *)et, ExponentTransformRcPtr);
-}
-
-OCIO_MatrixTransformRcPtr *OCIOImpl::createMatrixTransform(void)
-{
- MatrixTransformRcPtr *mt = OBJECT_GUARDED_NEW(MatrixTransformRcPtr);
-
- *mt = MatrixTransform::Create();
-
- return (OCIO_MatrixTransformRcPtr *)mt;
-}
-
-void OCIOImpl::matrixTransformSetValue(OCIO_MatrixTransformRcPtr *mt,
- const float *m44,
- const float *offset4)
-{
- (*(MatrixTransformRcPtr *)mt)->setValue(m44, offset4);
-}
-
-void OCIOImpl::matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt)
-{
- OBJECT_GUARDED_DELETE((MatrixTransformRcPtr *)mt, MatrixTransformRcPtr);
-}
-
-void OCIOImpl::matrixTransformScale(float *m44, float *offset4, const float *scale4f)
-{
- MatrixTransform::Scale(m44, offset4, scale4f);
-}
-
const char *OCIOImpl::getVersionString(void)
{
return GetVersion();
diff --git a/intern/opencolorio/ocio_impl.h b/intern/opencolorio/ocio_impl.h
index 3ffc0a4a475..0c759a35e15 100644
--- a/intern/opencolorio/ocio_impl.h
+++ b/intern/opencolorio/ocio_impl.h
@@ -76,36 +76,30 @@ class IOCIOImpl {
virtual OCIO_ConstProcessorRcPtr *configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config,
const char *srcName,
const char *dstName) = 0;
- virtual OCIO_ConstProcessorRcPtr *configGetProcessor(OCIO_ConstConfigRcPtr *config,
- OCIO_ConstTransformRcPtr *transform) = 0;
-
- virtual void processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img) = 0;
- virtual void processorApply_predivide(OCIO_ConstProcessorRcPtr *processor,
- OCIO_PackedImageDesc *img) = 0;
- virtual void processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel) = 0;
- virtual void processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel) = 0;
- virtual void processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel) = 0;
-
- virtual void processorRelease(OCIO_ConstProcessorRcPtr *p) = 0;
+ virtual void processorRelease(OCIO_ConstProcessorRcPtr *processor) = 0;
+
+ virtual OCIO_ConstCPUProcessorRcPtr *processorGetCPUProcessor(OCIO_ConstProcessorRcPtr *p) = 0;
+ virtual void cpuProcessorApply(OCIO_ConstCPUProcessorRcPtr *cpu_processor,
+ OCIO_PackedImageDesc *img) = 0;
+ virtual void cpuProcessorApply_predivide(OCIO_ConstCPUProcessorRcPtr *cpu_processor,
+ OCIO_PackedImageDesc *img) = 0;
+ virtual void cpuProcessorApplyRGB(OCIO_ConstCPUProcessorRcPtr *cpu_processor, float *pixel) = 0;
+ virtual void cpuProcessorApplyRGBA(OCIO_ConstCPUProcessorRcPtr *cpu_processor, float *pixel) = 0;
+ virtual void cpuProcessorApplyRGBA_predivide(OCIO_ConstCPUProcessorRcPtr *cpu_processor,
+ float *pixel) = 0;
+ virtual void cpuProcessorRelease(OCIO_ConstCPUProcessorRcPtr *cpu_processor) = 0;
virtual const char *colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs) = 0;
virtual const char *colorSpaceGetDescription(OCIO_ConstColorSpaceRcPtr *cs) = 0;
virtual const char *colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *cs) = 0;
- virtual OCIO_DisplayTransformRcPtr *createDisplayTransform(void) = 0;
- virtual void displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr *dt,
- const char *name) = 0;
- virtual void displayTransformSetDisplay(OCIO_DisplayTransformRcPtr *dt, const char *name) = 0;
- virtual void displayTransformSetView(OCIO_DisplayTransformRcPtr *dt, const char *name) = 0;
- virtual void displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt,
- OCIO_ConstTransformRcPtr *et) = 0;
- virtual void displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt,
- OCIO_ConstTransformRcPtr *et) = 0;
- virtual void displayTransformSetLooksOverride(OCIO_DisplayTransformRcPtr *dt,
- const char *looks) = 0;
- virtual void displayTransformSetLooksOverrideEnabled(OCIO_DisplayTransformRcPtr *dt,
- bool enabled) = 0;
- virtual void displayTransformRelease(OCIO_DisplayTransformRcPtr *dt) = 0;
+ virtual OCIO_ConstProcessorRcPtr *createDisplayProcessor(OCIO_ConstConfigRcPtr *config,
+ const char *input,
+ const char *view,
+ const char *display,
+ const char *look,
+ const float scale,
+ const float exponent) = 0;
virtual OCIO_PackedImageDesc *createOCIO_PackedImageDesc(float *data,
long width,
@@ -117,39 +111,31 @@ class IOCIOImpl {
virtual void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p) = 0;
- virtual OCIO_GroupTransformRcPtr *createGroupTransform(void) = 0;
- virtual void groupTransformSetDirection(OCIO_GroupTransformRcPtr *gt, const bool forward) = 0;
- virtual void groupTransformPushBack(OCIO_GroupTransformRcPtr *gt,
- OCIO_ConstTransformRcPtr *transform) = 0;
- virtual void groupTransformRelease(OCIO_GroupTransformRcPtr *gt) = 0;
-
- virtual OCIO_ColorSpaceTransformRcPtr *createColorSpaceTransform(void) = 0;
- virtual void colorSpaceTransformSetSrc(OCIO_ColorSpaceTransformRcPtr *ct, const char *name) = 0;
- virtual void colorSpaceTransformRelease(OCIO_ColorSpaceTransformRcPtr *ct) = 0;
-
- virtual OCIO_ExponentTransformRcPtr *createExponentTransform(void) = 0;
- virtual void exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et,
- const float *exponent) = 0;
- virtual void exponentTransformRelease(OCIO_ExponentTransformRcPtr *et) = 0;
-
- virtual OCIO_MatrixTransformRcPtr *createMatrixTransform(void) = 0;
- virtual void matrixTransformSetValue(OCIO_MatrixTransformRcPtr *mt,
- const float *m44,
- const float *offset4) = 0;
- virtual void matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt) = 0;
-
- virtual void matrixTransformScale(float *m44, float *offset4, const float *scale4) = 0;
-
- virtual bool supportGLSLDraw(void) = 0;
- virtual bool setupGLSLDraw(struct OCIO_GLSLDrawState **state_r,
- OCIO_ConstProcessorRcPtr *ocio_processor_scene_to_ui,
- OCIO_ConstProcessorRcPtr *ocio_processor_ui_to_display,
- OCIO_CurveMappingSettings *curve_mapping_settings,
- float dither,
- bool predivide,
- bool overlay) = 0;
- virtual void finishGLSLDraw(struct OCIO_GLSLDrawState *state) = 0;
- virtual void freeGLState(struct OCIO_GLSLDrawState *state_r) = 0;
+ /* Optional GPU support. */
+ virtual bool supportGPUShader()
+ {
+ return false;
+ }
+ virtual bool gpuDisplayShaderBind(OCIO_ConstConfigRcPtr * /*config*/,
+ const char * /*input*/,
+ const char * /*view*/,
+ const char * /*display*/,
+ const char * /*look*/,
+ OCIO_CurveMappingSettings * /*curve_mapping_settings*/,
+ const float /*scale*/,
+ const float /*exponent*/,
+ const float /*dither*/,
+ const bool /*use_predivide*/,
+ const bool /*use_overlay*/)
+ {
+ return false;
+ }
+ virtual void gpuDisplayShaderUnbind(void)
+ {
+ }
+ virtual void gpuCacheFree(void)
+ {
+ }
virtual const char *getVersionString(void) = 0;
virtual int getVersionHex(void) = 0;
@@ -206,30 +192,28 @@ class FallbackImpl : public IOCIOImpl {
OCIO_ConstProcessorRcPtr *configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config,
const char *srcName,
const char *dstName);
- OCIO_ConstProcessorRcPtr *configGetProcessor(OCIO_ConstConfigRcPtr *config,
- OCIO_ConstTransformRcPtr *transform);
+ void processorRelease(OCIO_ConstProcessorRcPtr *processor);
- void processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img);
- void processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img);
- void processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel);
- void processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel);
- void processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel);
-
- void processorRelease(OCIO_ConstProcessorRcPtr *p);
+ OCIO_ConstCPUProcessorRcPtr *processorGetCPUProcessor(OCIO_ConstProcessorRcPtr *processor);
+ void cpuProcessorApply(OCIO_ConstCPUProcessorRcPtr *cpu_processor, OCIO_PackedImageDesc *img);
+ void cpuProcessorApply_predivide(OCIO_ConstCPUProcessorRcPtr *cpu_processor,
+ OCIO_PackedImageDesc *img);
+ void cpuProcessorApplyRGB(OCIO_ConstCPUProcessorRcPtr *cpu_processor, float *pixel);
+ void cpuProcessorApplyRGBA(OCIO_ConstCPUProcessorRcPtr *cpu_processor, float *pixel);
+ void cpuProcessorApplyRGBA_predivide(OCIO_ConstCPUProcessorRcPtr *cpu_processor, float *pixel);
+ void cpuProcessorRelease(OCIO_ConstCPUProcessorRcPtr *cpu_processor);
const char *colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs);
const char *colorSpaceGetDescription(OCIO_ConstColorSpaceRcPtr *cs);
const char *colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *cs);
- OCIO_DisplayTransformRcPtr *createDisplayTransform(void);
- void displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr *dt, const char *name);
- void displayTransformSetDisplay(OCIO_DisplayTransformRcPtr *dt, const char *name);
- void displayTransformSetView(OCIO_DisplayTransformRcPtr *dt, const char *name);
- void displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et);
- void displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et);
- void displayTransformSetLooksOverride(OCIO_DisplayTransformRcPtr *dt, const char *looks);
- void displayTransformSetLooksOverrideEnabled(OCIO_DisplayTransformRcPtr *dt, bool enabled);
- void displayTransformRelease(OCIO_DisplayTransformRcPtr *dt);
+ OCIO_ConstProcessorRcPtr *createDisplayProcessor(OCIO_ConstConfigRcPtr *config,
+ const char *input,
+ const char *view,
+ const char *display,
+ const char *look,
+ const float scale,
+ const float exponent);
OCIO_PackedImageDesc *createOCIO_PackedImageDesc(float *data,
long width,
@@ -241,38 +225,6 @@ class FallbackImpl : public IOCIOImpl {
void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p);
- OCIO_GroupTransformRcPtr *createGroupTransform(void);
- void groupTransformSetDirection(OCIO_GroupTransformRcPtr *gt, const bool forward);
- void groupTransformPushBack(OCIO_GroupTransformRcPtr *gt, OCIO_ConstTransformRcPtr *transform);
- void groupTransformRelease(OCIO_GroupTransformRcPtr *gt);
-
- OCIO_ColorSpaceTransformRcPtr *createColorSpaceTransform(void);
- void colorSpaceTransformSetSrc(OCIO_ColorSpaceTransformRcPtr *ct, const char *name);
- void colorSpaceTransformRelease(OCIO_ColorSpaceTransformRcPtr *ct);
-
- OCIO_ExponentTransformRcPtr *createExponentTransform(void);
- void exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent);
- void exponentTransformRelease(OCIO_ExponentTransformRcPtr *et);
-
- OCIO_MatrixTransformRcPtr *createMatrixTransform(void);
- void matrixTransformSetValue(OCIO_MatrixTransformRcPtr *mt,
- const float *m44,
- const float *offset4);
- void matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt);
-
- void matrixTransformScale(float *m44, float *offset4, const float *scale4);
-
- bool supportGLSLDraw(void);
- bool setupGLSLDraw(struct OCIO_GLSLDrawState **state_r,
- OCIO_ConstProcessorRcPtr *ocio_processor_scene_to_ui,
- OCIO_ConstProcessorRcPtr *ocio_processor_ui_to_display,
- OCIO_CurveMappingSettings *curve_mapping_settings,
- float dither,
- bool predivide,
- bool overlay);
- void finishGLSLDraw(struct OCIO_GLSLDrawState *state);
- void freeGLState(struct OCIO_GLSLDrawState *state_r);
-
const char *getVersionString(void);
int getVersionHex(void);
};
@@ -327,30 +279,28 @@ class OCIOImpl : public IOCIOImpl {
OCIO_ConstProcessorRcPtr *configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config,
const char *srcName,
const char *dstName);
- OCIO_ConstProcessorRcPtr *configGetProcessor(OCIO_ConstConfigRcPtr *config,
- OCIO_ConstTransformRcPtr *transform);
-
- void processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img);
- void processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img);
- void processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel);
- void processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel);
- void processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel);
+ void processorRelease(OCIO_ConstProcessorRcPtr *processor);
- void processorRelease(OCIO_ConstProcessorRcPtr *p);
+ OCIO_ConstCPUProcessorRcPtr *processorGetCPUProcessor(OCIO_ConstProcessorRcPtr *processor);
+ void cpuProcessorApply(OCIO_ConstCPUProcessorRcPtr *cpu_processor, OCIO_PackedImageDesc *img);
+ void cpuProcessorApply_predivide(OCIO_ConstCPUProcessorRcPtr *cpu_processor,
+ OCIO_PackedImageDesc *img);
+ void cpuProcessorApplyRGB(OCIO_ConstCPUProcessorRcPtr *cpu_processor, float *pixel);
+ void cpuProcessorApplyRGBA(OCIO_ConstCPUProcessorRcPtr *cpu_processor, float *pixel);
+ void cpuProcessorApplyRGBA_predivide(OCIO_ConstCPUProcessorRcPtr *cpu_processor, float *pixel);
+ void cpuProcessorRelease(OCIO_ConstCPUProcessorRcPtr *cpu_processor);
const char *colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs);
const char *colorSpaceGetDescription(OCIO_ConstColorSpaceRcPtr *cs);
const char *colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr *cs);
- OCIO_DisplayTransformRcPtr *createDisplayTransform(void);
- void displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr *dt, const char *name);
- void displayTransformSetDisplay(OCIO_DisplayTransformRcPtr *dt, const char *name);
- void displayTransformSetView(OCIO_DisplayTransformRcPtr *dt, const char *name);
- void displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et);
- void displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt, OCIO_ConstTransformRcPtr *et);
- void displayTransformSetLooksOverride(OCIO_DisplayTransformRcPtr *dt, const char *looks);
- void displayTransformSetLooksOverrideEnabled(OCIO_DisplayTransformRcPtr *dt, bool enabled);
- void displayTransformRelease(OCIO_DisplayTransformRcPtr *dt);
+ OCIO_ConstProcessorRcPtr *createDisplayProcessor(OCIO_ConstConfigRcPtr *config,
+ const char *input,
+ const char *view,
+ const char *display,
+ const char *look,
+ const float scale,
+ const float exponent);
OCIO_PackedImageDesc *createOCIO_PackedImageDesc(float *data,
long width,
@@ -362,37 +312,20 @@ class OCIOImpl : public IOCIOImpl {
void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p);
- OCIO_GroupTransformRcPtr *createGroupTransform(void);
- void groupTransformSetDirection(OCIO_GroupTransformRcPtr *gt, const bool forward);
- void groupTransformPushBack(OCIO_GroupTransformRcPtr *gt, OCIO_ConstTransformRcPtr *transform);
- void groupTransformRelease(OCIO_GroupTransformRcPtr *gt);
-
- OCIO_ColorSpaceTransformRcPtr *createColorSpaceTransform(void);
- void colorSpaceTransformSetSrc(OCIO_ColorSpaceTransformRcPtr *ct, const char *name);
- void colorSpaceTransformRelease(OCIO_ColorSpaceTransformRcPtr *ct);
-
- OCIO_ExponentTransformRcPtr *createExponentTransform(void);
- void exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et, const float *exponent);
- void exponentTransformRelease(OCIO_ExponentTransformRcPtr *et);
-
- OCIO_MatrixTransformRcPtr *createMatrixTransform(void);
- void matrixTransformSetValue(OCIO_MatrixTransformRcPtr *mt,
- const float *m44,
- const float *offset4);
- void matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt);
-
- void matrixTransformScale(float *m44, float *offset4, const float *scale4);
-
- bool supportGLSLDraw(void);
- bool setupGLSLDraw(struct OCIO_GLSLDrawState **state_r,
- OCIO_ConstProcessorRcPtr *ocio_processor_scene_to_ui,
- OCIO_ConstProcessorRcPtr *ocio_processor_ui_to_display,
- OCIO_CurveMappingSettings *curve_mapping_settings,
- float dither,
- bool predivide,
- bool overlay);
- void finishGLSLDraw(struct OCIO_GLSLDrawState *state);
- void freeGLState(struct OCIO_GLSLDrawState *state_r);
+ bool supportGPUShader();
+ bool gpuDisplayShaderBind(OCIO_ConstConfigRcPtr *config,
+ const char *input,
+ const char *view,
+ const char *display,
+ const char *look,
+ OCIO_CurveMappingSettings *curve_mapping_settings,
+ const float scale,
+ const float exponent,
+ const float dither,
+ const bool use_predivide,
+ const bool use_overlay);
+ void gpuDisplayShaderUnbind(void);
+ void gpuCacheFree(void);
const char *getVersionString(void);
int getVersionHex(void);
diff --git a/intern/opencolorio/ocio_impl_glsl.cc b/intern/opencolorio/ocio_impl_glsl.cc
index 0213646345c..841f1386af1 100644
--- a/intern/opencolorio/ocio_impl_glsl.cc
+++ b/intern/opencolorio/ocio_impl_glsl.cc
@@ -31,8 +31,10 @@
*/
#include <limits>
+#include <list>
#include <sstream>
#include <string.h>
+#include <vector>
#ifdef _MSC_VER
# pragma warning(push)
@@ -53,24 +55,24 @@ using namespace OCIO_NAMESPACE;
#include "ocio_impl.h"
-static const int LUT3D_EDGE_SIZE = 64;
-static const int LUT3D_TEXTURE_SIZE = sizeof(float) * 3 * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE *
- LUT3D_EDGE_SIZE;
-static const int SHADER_CACHE_SIZE = 4;
-
-#define UBO_BIND_LOC 0
-
extern "C" char datatoc_gpu_shader_display_transform_glsl[];
extern "C" char datatoc_gpu_shader_display_transform_vertex_glsl[];
/* **** OpenGL drawing routines using GLSL for color space transform ***** */
+enum OCIO_GPUTextureSlots {
+ TEXTURE_SLOT_IMAGE = 0,
+ TEXTURE_SLOT_OVERLAY = 1,
+ TEXTURE_SLOT_CURVE_MAPPING = 2,
+ TEXTURE_SLOT_LUTS_OFFSET = 3,
+};
+
/* Curve mapping parameters
*
* See documentation for OCIO_CurveMappingSettings to get fields descriptions.
* (this ones pretty much copies stuff from C structure.)
*/
-struct OCIO_GLSLCurveMappingParameters {
+struct OCIO_GPUCurveMappingParameters {
float curve_mapping_mintable[4];
float curve_mapping_range[4];
float curve_mapping_ext_in_x[4];
@@ -89,79 +91,108 @@ struct OCIO_GLSLCurveMappingParameters {
/** WARNING: Needs to be 16byte aligned. Used as UBO data. */
};
-struct OCIO_GLSLShader {
- /** Cache IDs */
- std::string cacheId;
+struct OCIO_GPUShader {
+ /* GPU shader. */
+ struct GPUShader *shader = nullptr;
- struct GPUShader *shader;
/** Uniform locations. */
- int dither_loc;
- int overlay_loc;
- int predivide_loc;
- int curve_mapping_loc;
- int ubo_bind;
- /** Error checking. */
- bool valid;
+ int scale_loc = 0;
+ int exponent_loc = 0;
+ int dither_loc = 0;
+ int overlay_loc = 0;
+ int predivide_loc = 0;
+ int ubo_bind = 0;
+
+ /* Destructor. */
+ ~OCIO_GPUShader()
+ {
+ if (shader) {
+ GPU_shader_free(shader);
+ }
+ }
};
-struct OCIO_GLSLLut3d {
- /** Cache IDs */
- std::string cacheId;
- /** OpenGL Texture handles. NULL if not allocated. */
- GPUTexture *texture;
- GPUTexture *texture_display;
- GPUTexture *texture_dummy;
- /** Error checking. */
- bool valid;
+struct OCIO_GPULutTexture {
+ GPUTexture *texture = nullptr;
+ std::string sampler_name;
+};
+
+struct OCIO_GPUUniform {
+ GpuShaderDesc::UniformData data;
+ std::string name;
+};
+
+struct OCIO_GPUTextures {
+ /** LUT Textures */
+ std::vector<OCIO_GPULutTexture> luts;
+
+ /* Dummy in case of no overlay. */
+ GPUTexture *dummy = nullptr;
+
+ /* Uniforms */
+ std::vector<OCIO_GPUUniform> uniforms;
+
+ /* Destructor. */
+ ~OCIO_GPUTextures()
+ {
+ for (OCIO_GPULutTexture &lut : luts) {
+ GPU_texture_free(lut.texture);
+ }
+ if (dummy) {
+ GPU_texture_free(dummy);
+ }
+ }
};
-struct OCIO_GLSLCurveMappping {
- /** Cache IDs */
- size_t cacheId;
+struct OCIO_GPUCurveMappping {
/** GPU Uniform Buffer handle. 0 if not allocated. */
- GPUUniformBuf *buffer;
+ GPUUniformBuf *buffer = nullptr;
/** OpenGL Texture handles. 0 if not allocated. */
- GPUTexture *texture;
- /** Error checking. */
- bool valid;
-};
+ GPUTexture *texture = nullptr;
+ /* To detect when to update the uniforms and textures. */
+ size_t cache_id = 0;
-struct OCIO_GLSLCacheHandle {
- size_t cache_id;
- void *data;
+ /* Destructor. */
+ ~OCIO_GPUCurveMappping()
+ {
+ if (texture) {
+ GPU_texture_free(texture);
+ }
+ if (buffer) {
+ GPU_uniformbuf_free(buffer);
+ }
+ }
};
-struct OCIO_GLSLDrawState {
- /* Shader Cache */
- OCIO_GLSLCacheHandle shader_cache[SHADER_CACHE_SIZE];
- OCIO_GLSLCacheHandle lut3d_cache[SHADER_CACHE_SIZE];
- OCIO_GLSLCacheHandle curvemap_cache[SHADER_CACHE_SIZE];
+struct OCIO_GPUDisplayShader {
+ OCIO_GPUShader shader;
+ OCIO_GPUTextures textures;
+ OCIO_GPUCurveMappping curvemap;
+
+ /* Cache variables. */
+ std::string input;
+ std::string view;
+ std::string display;
+ std::string look;
+ bool use_curve_mapping = false;
+
+ /** Error checking. */
+ bool valid = false;
};
-static OCIO_GLSLDrawState *allocateOpenGLState(void)
-{
- return (OCIO_GLSLDrawState *)MEM_callocN(sizeof(OCIO_GLSLDrawState), "OCIO OpenGL State struct");
-}
+static const int SHADER_CACHE_MAX_SIZE = 4;
+std::list<OCIO_GPUDisplayShader> SHADER_CACHE;
/* -------------------------------------------------------------------- */
/** \name Shader
* \{ */
-static void updateGLSLShader(OCIO_GLSLShader *shader,
- ConstProcessorRcPtr *processor_scene_to_ui,
- ConstProcessorRcPtr *processpr_ui_to_display,
- GpuShaderDesc *shader_desc,
- const std::string &cache_id)
+static bool createGPUShader(OCIO_GPUShader &shader,
+ OCIO_GPUTextures &textures,
+ const GpuShaderDescRcPtr &shaderdesc_to_scene_linear,
+ const GpuShaderDescRcPtr &shaderdesc_to_display,
+ const bool use_curve_mapping)
{
- if (shader->cacheId == cache_id) {
- return;
- }
-
- /* Delete any previous shader. */
- if (shader->shader) {
- GPU_shader_free(shader->shader);
- }
-
std::ostringstream os;
{
/* Fragment shader */
@@ -170,146 +201,222 @@ static void updateGLSLShader(OCIO_GLSLShader *shader,
os << "#define texture2D texture\n";
os << "#define texture3D texture\n";
- shader_desc->setFunctionName("OCIO_to_display_linear_with_look");
- os << (*processor_scene_to_ui)->getGpuShaderText(*shader_desc) << "\n";
+ if (use_curve_mapping) {
+ os << "#define USE_CURVE_MAPPING\n";
+ }
- shader_desc->setFunctionName("OCIO_to_display_encoded");
- os << (*processpr_ui_to_display)->getGpuShaderText(*shader_desc) << "\n";
+ os << shaderdesc_to_scene_linear->getShaderText() << "\n";
+ os << shaderdesc_to_display->getShaderText() << "\n";
os << datatoc_gpu_shader_display_transform_glsl;
}
- shader->shader = GPU_shader_create(datatoc_gpu_shader_display_transform_vertex_glsl,
- os.str().c_str(),
- NULL,
- NULL,
- NULL,
- "OCIOShader");
+ shader.shader = GPU_shader_create(datatoc_gpu_shader_display_transform_vertex_glsl,
+ os.str().c_str(),
+ nullptr,
+ nullptr,
+ nullptr,
+ "OCIOShader");
- if (shader->shader) {
- shader->dither_loc = GPU_shader_get_uniform(shader->shader, "dither");
- shader->overlay_loc = GPU_shader_get_uniform(shader->shader, "overlay");
- shader->predivide_loc = GPU_shader_get_uniform(shader->shader, "predivide");
- shader->curve_mapping_loc = GPU_shader_get_uniform(shader->shader, "curve_mapping");
- shader->ubo_bind = GPU_shader_get_uniform_block_binding(shader->shader,
- "OCIO_GLSLCurveMappingParameters");
+ if (shader.shader == nullptr) {
+ return false;
+ }
- GPU_shader_bind(shader->shader);
+ shader.scale_loc = GPU_shader_get_uniform(shader.shader, "scale");
+ shader.exponent_loc = GPU_shader_get_uniform(shader.shader, "exponent");
+ shader.dither_loc = GPU_shader_get_uniform(shader.shader, "dither");
+ shader.overlay_loc = GPU_shader_get_uniform(shader.shader, "overlay");
+ shader.predivide_loc = GPU_shader_get_uniform(shader.shader, "predivide");
+ shader.ubo_bind = GPU_shader_get_uniform_block_binding(shader.shader,
+ "OCIO_GPUCurveMappingParameters");
- /* Set texture bind point uniform once. This is saved by the shader. */
- GPUShader *sh = shader->shader;
- GPU_shader_uniform_int(sh, GPU_shader_get_uniform(sh, "image_texture"), 0);
- GPU_shader_uniform_int(sh, GPU_shader_get_uniform(sh, "overlay_texture"), 1);
- GPU_shader_uniform_int(sh, GPU_shader_get_uniform(sh, "lut3d_texture"), 2);
- GPU_shader_uniform_int(sh, GPU_shader_get_uniform(sh, "lut3d_display_texture"), 3);
- GPU_shader_uniform_int(sh, GPU_shader_get_uniform(sh, "curve_mapping_texture"), 4);
- }
+ GPU_shader_bind(shader.shader);
- shader->cacheId = cache_id;
- shader->valid = (shader->shader != NULL);
-}
+ /* Set texture bind point uniform once. This is saved by the shader. */
+ GPUShader *sh = shader.shader;
+ GPU_shader_uniform_int(sh, GPU_shader_get_uniform(sh, "image_texture"), TEXTURE_SLOT_IMAGE);
+ GPU_shader_uniform_int(sh, GPU_shader_get_uniform(sh, "overlay_texture"), TEXTURE_SLOT_OVERLAY);
-static void ensureGLSLShader(OCIO_GLSLShader **shader_ptr,
- ConstProcessorRcPtr *processor_scene_to_ui,
- ConstProcessorRcPtr *processpr_ui_to_display,
- GpuShaderDesc *shader_desc,
- const std::string &cache_id)
-{
- if (*shader_ptr != NULL) {
- return;
+ if (use_curve_mapping) {
+ GPU_shader_uniform_int(
+ sh, GPU_shader_get_uniform(sh, "curve_mapping_texture"), TEXTURE_SLOT_CURVE_MAPPING);
}
- OCIO_GLSLShader *shader = OBJECT_GUARDED_NEW(OCIO_GLSLShader);
-
- updateGLSLShader(shader, processor_scene_to_ui, processpr_ui_to_display, shader_desc, cache_id);
+ /* Set LUT textures. */
+ for (int i = 0; i < textures.luts.size(); i++) {
+ GPU_shader_uniform_int(sh,
+ GPU_shader_get_uniform(sh, textures.luts[i].sampler_name.c_str()),
+ TEXTURE_SLOT_LUTS_OFFSET + i);
+ }
- *shader_ptr = shader;
-}
+ /* Set uniforms. */
+ for (OCIO_GPUUniform &uniform : textures.uniforms) {
+ const GpuShaderDesc::UniformData &data = uniform.data;
+ const char *name = name;
-static void freeGLSLShader(OCIO_GLSLShader *shader)
-{
- if (shader->shader) {
- GPU_shader_free(shader->shader);
+ if (data.m_getDouble) {
+ GPU_shader_uniform_1f(sh, name, (float)data.m_getDouble());
+ }
+ else if (data.m_getBool) {
+ GPU_shader_uniform_1f(sh, name, (float)(data.m_getBool() ? 1.0f : 0.0f));
+ }
+ else if (data.m_getFloat3) {
+ GPU_shader_uniform_3f(sh,
+ name,
+ (float)data.m_getFloat3()[0],
+ (float)data.m_getFloat3()[1],
+ (float)data.m_getFloat3()[2]);
+ }
+ else if (data.m_vectorFloat.m_getSize && data.m_vectorFloat.m_getVector) {
+ GPU_shader_uniform_vector(sh,
+ GPU_shader_get_uniform(sh, name),
+ (int)data.m_vectorFloat.m_getSize(),
+ 1,
+ (float *)data.m_vectorFloat.m_getVector());
+ }
+ else if (data.m_vectorInt.m_getSize && data.m_vectorInt.m_getVector) {
+ GPU_shader_uniform_vector_int(sh,
+ GPU_shader_get_uniform(sh, name),
+ (int)data.m_vectorInt.m_getSize(),
+ 1,
+ (int *)data.m_vectorInt.m_getVector());
+ }
}
- OBJECT_GUARDED_DELETE(shader, OCIO_GLSLShader);
+ return true;
}
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Lut3D
+/** \name Textures
* \{ */
-static void updateGLSLLut3d(OCIO_GLSLLut3d *lut3d,
- ConstProcessorRcPtr *processor_scene_to_ui,
- ConstProcessorRcPtr *processpr_ui_to_display,
- GpuShaderDesc *shader_desc,
- const std::string &cache_id)
+static bool addGPUUniform(OCIO_GPUTextures &textures,
+ const GpuShaderDescRcPtr &shader_desc,
+ int index)
{
- if (lut3d->cacheId == cache_id)
- return;
-
- float *lut_data = (float *)MEM_mallocN(LUT3D_TEXTURE_SIZE, __func__);
+ OCIO_GPUUniform uniform;
+ uniform.name = shader_desc->getUniform(index, uniform.data);
+ if (uniform.data.m_type == UNIFORM_UNKNOWN) {
+ return false;
+ }
- ConstProcessorRcPtr *ocio_processors[2] = {processor_scene_to_ui, processpr_ui_to_display};
+ textures.uniforms.push_back(uniform);
+ return true;
+}
- for (int i = 0; i < 2; i++) {
- ConstProcessorRcPtr *processor = ocio_processors[i];
- GPUTexture *texture = (&lut3d->texture)[i];
+static bool addGPULut2D(OCIO_GPUTextures &textures,
+ const GpuShaderDescRcPtr &shader_desc,
+ int index)
+{
+ const char *texture_name = nullptr;
+ const char *sampler_name = nullptr;
+ unsigned int width = 0;
+ unsigned int height = 0;
+ GpuShaderCreator::TextureType channel = GpuShaderCreator::TEXTURE_RGB_CHANNEL;
+ Interpolation interpolation = INTERP_LINEAR;
+ shader_desc->getTexture(
+ index, texture_name, sampler_name, width, height, channel, interpolation);
+
+ const float *values;
+ shader_desc->getTextureValues(index, values);
+ if (texture_name == nullptr || sampler_name == nullptr || width == 0 || height == 0 ||
+ values == nullptr) {
+ return false;
+ }
- (*processor)->getGpuLut3D(lut_data, *shader_desc);
+ eGPUTextureFormat format = (channel == GpuShaderCreator::TEXTURE_RGB_CHANNEL) ? GPU_RGB16F :
+ GPU_R16F;
- int offset[3] = {0, 0, 0};
- int extent[3] = {LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE};
- GPU_texture_update_sub(texture, GPU_DATA_FLOAT, lut_data, UNPACK3(offset), UNPACK3(extent));
+ OCIO_GPULutTexture lut;
+ lut.texture = GPU_texture_create_2d(texture_name, width, height, 0, format, values);
+ if (lut.texture == nullptr) {
+ return false;
}
- MEM_freeN(lut_data);
+ GPU_texture_filter_mode(lut.texture, interpolation != INTERP_NEAREST);
+ GPU_texture_wrap_mode(lut.texture, false, true);
+
+ lut.sampler_name = sampler_name;
- lut3d->cacheId = cache_id;
+ textures.luts.push_back(lut);
+ return true;
}
-static void ensureGLSLLut3d(OCIO_GLSLLut3d **lut3d_ptr,
- ConstProcessorRcPtr *processor_scene_to_ui,
- ConstProcessorRcPtr *processpr_ui_to_display,
- GpuShaderDesc *shaderDesc,
- const std::string &cache_id)
+static bool addGPULut3D(OCIO_GPUTextures &textures,
+ const GpuShaderDescRcPtr &shader_desc,
+ int index)
{
- if (*lut3d_ptr != NULL) {
- return;
+ const char *texture_name = nullptr;
+ const char *sampler_name = nullptr;
+ unsigned int edgelen = 0;
+ Interpolation interpolation = INTERP_LINEAR;
+ shader_desc->get3DTexture(index, texture_name, sampler_name, edgelen, interpolation);
+
+ const float *values;
+ shader_desc->get3DTextureValues(index, values);
+ if (texture_name == nullptr || sampler_name == nullptr || edgelen == 0 || values == nullptr) {
+ return false;
}
- OCIO_GLSLLut3d *lut3d = OBJECT_GUARDED_NEW(OCIO_GLSLLut3d);
-
- int extent[3] = {LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE};
-
- lut3d->texture = GPU_texture_create_3d(
- "OCIOLut", UNPACK3(extent), 1, GPU_RGB16F, GPU_DATA_FLOAT, NULL);
- GPU_texture_filter_mode(lut3d->texture, true);
- GPU_texture_wrap_mode(lut3d->texture, false, true);
-
- lut3d->texture_display = GPU_texture_create_3d(
- "OCIOLutDisplay", UNPACK3(extent), 1, GPU_RGB16F, GPU_DATA_FLOAT, NULL);
- GPU_texture_filter_mode(lut3d->texture_display, true);
- GPU_texture_wrap_mode(lut3d->texture_display, false, true);
-
- lut3d->texture_dummy = GPU_texture_create_error(2, false);
+ OCIO_GPULutTexture lut;
+ lut.texture = GPU_texture_create_3d(
+ texture_name, edgelen, edgelen, edgelen, 0, GPU_RGB16F, GPU_DATA_FLOAT, values);
+ if (lut.texture == nullptr) {
+ return false;
+ }
- updateGLSLLut3d(lut3d, processor_scene_to_ui, processpr_ui_to_display, shaderDesc, cache_id);
+ GPU_texture_filter_mode(lut.texture, interpolation != INTERP_NEAREST);
+ GPU_texture_wrap_mode(lut.texture, false, true);
- lut3d->valid = (lut3d->texture && lut3d->texture_display);
+ lut.sampler_name = sampler_name;
- *lut3d_ptr = lut3d;
+ textures.luts.push_back(lut);
+ return true;
}
-static void freeGLSLLut3d(OCIO_GLSLLut3d *lut3d)
+static bool createGPUTextures(OCIO_GPUTextures &textures,
+ const GpuShaderDescRcPtr &shaderdesc_to_scene_linear,
+ const GpuShaderDescRcPtr &shaderdesc_to_display)
{
- GPU_texture_free(lut3d->texture);
- GPU_texture_free(lut3d->texture_display);
- GPU_texture_free(lut3d->texture_dummy);
+ textures.dummy = GPU_texture_create_error(2, false);
+
+ textures.luts.clear();
+ textures.uniforms.clear();
+
+ for (int index = 0; index < shaderdesc_to_scene_linear->getNumUniforms(); index++) {
+ if (!addGPUUniform(textures, shaderdesc_to_scene_linear, index)) {
+ return false;
+ }
+ }
+ for (int index = 0; index < shaderdesc_to_scene_linear->getNumTextures(); index++) {
+ if (!addGPULut2D(textures, shaderdesc_to_scene_linear, index)) {
+ return false;
+ }
+ }
+ for (int index = 0; index < shaderdesc_to_scene_linear->getNum3DTextures(); index++) {
+ if (!addGPULut3D(textures, shaderdesc_to_scene_linear, index)) {
+ return false;
+ }
+ }
+ for (int index = 0; index < shaderdesc_to_display->getNumUniforms(); index++) {
+ if (!addGPUUniform(textures, shaderdesc_to_display, index)) {
+ return false;
+ }
+ }
+ for (int index = 0; index < shaderdesc_to_display->getNumTextures(); index++) {
+ if (!addGPULut2D(textures, shaderdesc_to_display, index)) {
+ return false;
+ }
+ }
+ for (int index = 0; index < shaderdesc_to_display->getNum3DTextures(); index++) {
+ if (!addGPULut3D(textures, shaderdesc_to_display, index)) {
+ return false;
+ }
+ }
- OBJECT_GUARDED_DELETE(lut3d, OCIO_GLSLLut3d);
+ return true;
}
/** \} */
@@ -317,72 +424,47 @@ static void freeGLSLLut3d(OCIO_GLSLLut3d *lut3d)
/* -------------------------------------------------------------------- */
/** \name Curve Mapping
* \{ */
-static void allocateCurveMappingTexture(OCIO_GLSLCurveMappping *curvemap,
- OCIO_CurveMappingSettings *curve_mapping_settings)
-{
- int lut_size = curve_mapping_settings ? curve_mapping_settings->lut_size : 1;
- /* Do not initialize. Only if used. */
- curvemap->texture = GPU_texture_create_1d("OCIOCurveMap", lut_size, 1, GPU_RGBA16F, NULL);
- GPU_texture_filter_mode(curvemap->texture, false);
- GPU_texture_wrap_mode(curvemap->texture, false, true);
-}
-/* curve_mapping_settings can be null. In this case we alloc a dummy curvemap. */
-static void ensureGLSLCurveMapping(OCIO_GLSLCurveMappping **curvemap_ptr,
- OCIO_CurveMappingSettings *curve_mapping_settings)
+static bool createGPUCurveMapping(OCIO_GPUCurveMappping &curvemap,
+ OCIO_CurveMappingSettings *curve_mapping_settings)
{
- if (*curvemap_ptr != NULL) {
- return;
- }
-
- OCIO_GLSLCurveMappping *curvemap = OBJECT_GUARDED_NEW(OCIO_GLSLCurveMappping);
+ if (curve_mapping_settings) {
+ int lut_size = curve_mapping_settings->lut_size;
- /* Texture. */
- allocateCurveMappingTexture(curvemap, curve_mapping_settings);
+ curvemap.texture = GPU_texture_create_1d("OCIOCurveMap", lut_size, 1, GPU_RGBA16F, nullptr);
+ GPU_texture_filter_mode(curvemap.texture, false);
+ GPU_texture_wrap_mode(curvemap.texture, false, true);
- /* Uniform buffer object. */
- curvemap->buffer = GPU_uniformbuf_create(sizeof(OCIO_GLSLCurveMappingParameters));
+ curvemap.buffer = GPU_uniformbuf_create(sizeof(OCIO_GPUCurveMappingParameters));
- curvemap->valid = (curvemap->texture != 0);
- curvemap->cacheId = 0;
-
- *curvemap_ptr = curvemap;
-}
-
-static void freeGLSLCurveMapping(OCIO_GLSLCurveMappping *curvemap)
-{
- GPU_texture_free(curvemap->texture);
- GPU_uniformbuf_free(curvemap->buffer);
+ if (curvemap.texture == nullptr || curvemap.buffer == nullptr) {
+ return false;
+ }
+ }
- OBJECT_GUARDED_DELETE(curvemap, OCIO_GLSLCurveMappping);
+ return true;
}
-static void updateGLSLCurveMapping(OCIO_GLSLCurveMappping *curvemap,
- OCIO_CurveMappingSettings *curve_mapping_settings,
- size_t cacheId)
+static void updateGPUCurveMapping(OCIO_GPUCurveMappping &curvemap,
+ OCIO_CurveMappingSettings *curve_mapping_settings)
{
- /* No need to continue if curvemapping is not used. Just use whatever is in this cache. */
- if (curve_mapping_settings == NULL)
+ /* Test if we need to update. The caller ensures the curve_mapping_settings
+ * changes when its contents changes. */
+ if (curve_mapping_settings == nullptr || curvemap.cache_id == curve_mapping_settings->cache_id) {
return;
-
- if (curvemap->cacheId == cacheId)
- return;
-
- if (curvemap->cacheId == 0) {
- /* This cache was previously used as dummy. Recreate the texture. */
- GPU_texture_free(curvemap->texture);
- allocateCurveMappingTexture(curvemap, curve_mapping_settings);
}
+ curvemap.cache_id = curve_mapping_settings->cache_id;
+
/* Update texture. */
int offset[3] = {0, 0, 0};
int extent[3] = {curve_mapping_settings->lut_size, 0, 0};
const float *pixels = curve_mapping_settings->lut;
GPU_texture_update_sub(
- curvemap->texture, GPU_DATA_FLOAT, pixels, UNPACK3(offset), UNPACK3(extent));
+ curvemap.texture, GPU_DATA_FLOAT, pixels, UNPACK3(offset), UNPACK3(extent));
/* Update uniforms. */
- OCIO_GLSLCurveMappingParameters data;
+ OCIO_GPUCurveMappingParameters data;
for (int i = 0; i < 4; i++) {
data.curve_mapping_range[i] = curve_mapping_settings->range[i];
data.curve_mapping_mintable[i] = curve_mapping_settings->mintable[i];
@@ -402,198 +484,193 @@ static void updateGLSLCurveMapping(OCIO_GLSLCurveMappping *curvemap,
data.curve_mapping_lut_size = curve_mapping_settings->lut_size;
data.curve_mapping_use_extend_extrapolate = curve_mapping_settings->use_extend_extrapolate;
- GPU_uniformbuf_update(curvemap->buffer, &data);
-
- curvemap->cacheId = cacheId;
+ GPU_uniformbuf_update(curvemap.buffer, &data);
}
/** \} */
/* -------------------------------------------------------------------- */
-/** \name LRU cache
+/** \name OCIO GPU Shader Implementation
* \{ */
-static size_t hash_string(const char *str)
+bool OCIOImpl::supportGPUShader()
{
- size_t i = 0, c;
- while ((c = *str++)) {
- i = i * 37 + c;
- }
- return i;
+ /* Minimum supported version 3.3 does meet all requirements. */
+ return true;
}
-static OCIO_GLSLCacheHandle *cacheSearch(OCIO_GLSLCacheHandle cache[SHADER_CACHE_SIZE],
- size_t cache_id)
+static OCIO_GPUDisplayShader &getGPUDisplayShader(
+ OCIO_ConstConfigRcPtr *config,
+ const char *input,
+ const char *view,
+ const char *display,
+ const char *look,
+ OCIO_CurveMappingSettings *curve_mapping_settings)
{
- OCIO_GLSLCacheHandle *cached_item = &cache[0];
- for (int i = 0; i < SHADER_CACHE_SIZE; i++, cached_item++) {
- if (cached_item->data == NULL) {
- continue;
- }
- else if (cached_item->cache_id == cache_id) {
- /* LRU cache, so move to front. */
- OCIO_GLSLCacheHandle found_item = *cached_item;
- for (int j = i; j > 0; j--) {
- cache[j] = cache[j - 1];
+ /* Find existing shader in cache. */
+ const bool use_curve_mapping = (curve_mapping_settings != nullptr);
+ for (std::list<OCIO_GPUDisplayShader>::iterator it = SHADER_CACHE.begin();
+ it != SHADER_CACHE.end();
+ it++) {
+ if (it->input == input && it->view == view && it->display == display && it->look == look &&
+ it->use_curve_mapping == use_curve_mapping) {
+ /* Move to front of the cache to mark as most recently used. */
+ if (it != SHADER_CACHE.begin()) {
+ SHADER_CACHE.splice(SHADER_CACHE.begin(), SHADER_CACHE, it);
}
- cache[0] = found_item;
- return &cache[0];
+
+ return *it;
}
}
- /* LRU cache, shift other items back so we can insert at the front. */
- OCIO_GLSLCacheHandle last_item = cache[SHADER_CACHE_SIZE - 1];
- for (int j = SHADER_CACHE_SIZE - 1; j > 0; j--) {
- cache[j] = cache[j - 1];
+
+ /* Remove least recently used element from cache. */
+ if (SHADER_CACHE.size() >= SHADER_CACHE_MAX_SIZE) {
+ SHADER_CACHE.pop_back();
}
- /* Copy last to front and let the caller initialize it. */
- cache[0] = last_item;
- return &cache[0];
-}
-/** \} */
+ /* Create GPU shader. */
+ SHADER_CACHE.emplace_front();
+ OCIO_GPUDisplayShader &display_shader = SHADER_CACHE.front();
+
+ display_shader.input = input;
+ display_shader.view = view;
+ display_shader.display = display;
+ display_shader.look = look;
+ display_shader.use_curve_mapping = use_curve_mapping;
+ display_shader.valid = false;
+
+ /* Create Processors.
+ *
+ * Scale and exponent are handled outside of OCIO shader so we can handle them
+ * as uniforms at the binding stage. OCIO would otherwise bake them into the
+ * shader code, requiring slow recompiles when interactively adjusting them.
+ *
+ * Note that OCIO does have the concept of dynamic properties, however there
+ * is no dynamic gamma and exposure is part of more expensive operations only.
+ *
+ * Since exposure must happen in scene linear, we use two processors. The input
+ * is usually scene linear already and so that conversion is often a no-op.
+ */
+ OCIO_ConstProcessorRcPtr *processor_to_scene_linear = OCIO_configGetProcessorWithNames(
+ config, input, ROLE_SCENE_LINEAR);
+ OCIO_ConstProcessorRcPtr *processor_to_display = OCIO_createDisplayProcessor(
+ config, ROLE_SCENE_LINEAR, view, display, look, 1.0f, 1.0f);
+
+ /* Create shader descriptions. */
+ if (processor_to_scene_linear && processor_to_display) {
+ GpuShaderDescRcPtr shaderdesc_to_scene_linear = GpuShaderDesc::CreateShaderDesc();
+ shaderdesc_to_scene_linear->setLanguage(GPU_LANGUAGE_GLSL_1_3);
+ shaderdesc_to_scene_linear->setFunctionName("OCIO_to_scene_linear");
+ (*(ConstProcessorRcPtr *)processor_to_scene_linear)
+ ->getDefaultGPUProcessor()
+ ->extractGpuShaderInfo(shaderdesc_to_scene_linear);
+ shaderdesc_to_scene_linear->finalize();
+
+ GpuShaderDescRcPtr shaderdesc_to_display = GpuShaderDesc::CreateShaderDesc();
+ shaderdesc_to_display->setLanguage(GPU_LANGUAGE_GLSL_1_3);
+ shaderdesc_to_display->setFunctionName("OCIO_to_display");
+ (*(ConstProcessorRcPtr *)processor_to_display)
+ ->getDefaultGPUProcessor()
+ ->extractGpuShaderInfo(shaderdesc_to_display);
+ shaderdesc_to_display->finalize();
+
+ /* Create GPU shader and textures. */
+ if (createGPUTextures(
+ display_shader.textures, shaderdesc_to_scene_linear, shaderdesc_to_display) &&
+ createGPUCurveMapping(display_shader.curvemap, curve_mapping_settings) &&
+ createGPUShader(display_shader.shader,
+ display_shader.textures,
+ shaderdesc_to_scene_linear,
+ shaderdesc_to_display,
+ use_curve_mapping)) {
+ display_shader.valid = true;
+ }
+ }
-/* -------------------------------------------------------------------- */
-/** \name OCIO GLSL Implementation
- * \{ */
+ /* Free processors. */
+ if (processor_to_scene_linear) {
+ OCIO_processorRelease(processor_to_scene_linear);
+ }
+ if (processor_to_display) {
+ OCIO_processorRelease(processor_to_display);
+ }
-/* Detect if we can support GLSL drawing */
-bool OCIOImpl::supportGLSLDraw()
-{
- /* Minimum supported version 3.3 does meet all requirements. */
- return true;
+ return display_shader;
}
/**
- * Setup OpenGL contexts for a transform defined by processor using GLSL
+ * Setup GPU contexts for a transform defined by processor using GLSL.
* All LUT allocating baking and shader compilation happens here.
*
* Once this function is called, callee could start drawing images
* using regular 2D texture.
*
- * When all drawing is finished, finishGLSLDraw shall be called to
- * restore OpenGL context to its pre-GLSL draw state.
+ * When all drawing is finished, gpuDisplayShaderUnbind must be called to
+ * restore GPU context to its previous state.
*/
-bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r,
- OCIO_ConstProcessorRcPtr *ocio_processor_scene_to_ui,
- OCIO_ConstProcessorRcPtr *ocio_processor_ui_to_display,
- OCIO_CurveMappingSettings *curve_mapping_settings,
- float dither,
- bool use_predivide,
- bool use_overlay)
+bool OCIOImpl::gpuDisplayShaderBind(OCIO_ConstConfigRcPtr *config,
+ const char *input,
+ const char *view,
+ const char *display,
+ const char *look,
+ OCIO_CurveMappingSettings *curve_mapping_settings,
+ const float scale,
+ const float exponent,
+ const float dither,
+ const bool use_predivide,
+ const bool use_overlay)
{
- ConstProcessorRcPtr processor_scene_to_ui = *(ConstProcessorRcPtr *)ocio_processor_scene_to_ui;
- ConstProcessorRcPtr processpr_ui_to_display = *(
- ConstProcessorRcPtr *)ocio_processor_ui_to_display;
- bool use_curve_mapping = curve_mapping_settings != NULL;
-
- if (!processor_scene_to_ui || !processor_scene_to_ui) {
+ /* Get GPU shader from cache or create new one. */
+ OCIO_GPUDisplayShader &display_shader = getGPUDisplayShader(
+ config, input, view, display, look, curve_mapping_settings);
+ if (!display_shader.valid) {
return false;
}
- /* Create state if needed. */
- OCIO_GLSLDrawState *state;
- if (!*state_r)
- *state_r = allocateOpenGLState();
- state = *state_r;
-
- /* Compute cache IDs. */
- GpuShaderDesc shaderDesc;
- shaderDesc.setLanguage(GPU_LANGUAGE_GLSL_1_3);
- shaderDesc.setFunctionName("OCIODisplay");
- shaderDesc.setLut3DEdgeLen(LUT3D_EDGE_SIZE);
-
- const char *shader_cache_str = processor_scene_to_ui->getGpuShaderTextCacheID(shaderDesc);
- const char *lut3d_cache_str = processor_scene_to_ui->getGpuLut3DCacheID(shaderDesc);
- /* Used for comparison. */
- std::string shaderCacheID = shader_cache_str;
- std::string lut3dCacheID = lut3d_cache_str;
-
- size_t shader_cache_id = hash_string(shader_cache_str);
- size_t lut3d_cache_id = hash_string(lut3d_cache_str);
- size_t curvemap_cache_id = curve_mapping_settings ? curve_mapping_settings->cache_id : 0;
-
- OCIO_GLSLCacheHandle *shader_handle = cacheSearch(state->shader_cache, shader_cache_id);
- OCIO_GLSLCacheHandle *lut3d_handle = cacheSearch(state->lut3d_cache, lut3d_cache_id);
- /* We cannot keep more than one cache for curvemap because their cache id is a pointer.
- * The pointer cannot be the same for one update but can be the same after a second update. */
- OCIO_GLSLCacheHandle *curvemap_handle = &state->curvemap_cache[0];
-
- OCIO_GLSLShader **shader_ptr = (OCIO_GLSLShader **)&shader_handle->data;
- OCIO_GLSLLut3d **lut3d_ptr = (OCIO_GLSLLut3d **)&lut3d_handle->data;
- OCIO_GLSLCurveMappping **curvemap_ptr = (OCIO_GLSLCurveMappping **)&curvemap_handle->data;
-
- ensureGLSLShader(
- shader_ptr, &processor_scene_to_ui, &processpr_ui_to_display, &shaderDesc, shaderCacheID);
- ensureGLSLLut3d(
- lut3d_ptr, &processor_scene_to_ui, &processpr_ui_to_display, &shaderDesc, shaderCacheID);
- ensureGLSLCurveMapping(curvemap_ptr, curve_mapping_settings);
-
- OCIO_GLSLShader *shader = (OCIO_GLSLShader *)shader_handle->data;
- OCIO_GLSLLut3d *shader_lut = (OCIO_GLSLLut3d *)lut3d_handle->data;
- OCIO_GLSLCurveMappping *shader_curvemap = (OCIO_GLSLCurveMappping *)curvemap_handle->data;
-
- updateGLSLShader(
- shader, &processor_scene_to_ui, &processpr_ui_to_display, &shaderDesc, shaderCacheID);
- updateGLSLLut3d(
- shader_lut, &processor_scene_to_ui, &processpr_ui_to_display, &shaderDesc, lut3dCacheID);
- updateGLSLCurveMapping(shader_curvemap, curve_mapping_settings, curvemap_cache_id);
-
- /* Update handles cache keys. */
- shader_handle->cache_id = shader_cache_id;
- lut3d_handle->cache_id = lut3d_cache_id;
- curvemap_handle->cache_id = curvemap_cache_id;
-
- if (shader->valid && shader_lut->valid && shader_curvemap->valid) {
- /* Bind textures to sampler units. Texture 0 is set by caller.
- * Uniforms have already been set for texture bind points.*/
-
- if (!use_overlay) {
- /* Avoid missing binds. */
- GPU_texture_bind(shader_lut->texture_dummy, 1);
- }
- GPU_texture_bind(shader_lut->texture, 2);
- GPU_texture_bind(shader_lut->texture_display, 3);
- GPU_texture_bind(shader_curvemap->texture, 4);
+ /* Verify the shader is valid. */
+ OCIO_GPUTextures &textures = display_shader.textures;
+ OCIO_GPUShader &shader = display_shader.shader;
+ OCIO_GPUCurveMappping &curvemap = display_shader.curvemap;
- /* Bind UBO. */
- GPU_uniformbuf_bind(shader_curvemap->buffer, shader->ubo_bind);
+ /* Update and bind curve mapping data. */
+ if (curve_mapping_settings) {
+ updateGPUCurveMapping(curvemap, curve_mapping_settings);
+ GPU_uniformbuf_bind(curvemap.buffer, shader.ubo_bind);
+ GPU_texture_bind(curvemap.texture, TEXTURE_SLOT_CURVE_MAPPING);
+ }
- /* TODO(fclem): remove remains of IMM. */
- immBindShader(shader->shader);
+ /* Bind textures to sampler units. Texture 0 is set by caller.
+ * Uniforms have already been set for texture bind points.*/
+ if (!use_overlay) {
+ /* Avoid missing binds. */
+ GPU_texture_bind(textures.dummy, TEXTURE_SLOT_OVERLAY);
+ }
+ for (int i = 0; i < textures.luts.size(); i++) {
+ GPU_texture_bind(textures.luts[i].texture, TEXTURE_SLOT_LUTS_OFFSET + i);
+ }
- /* Bind Shader and set uniforms. */
- // GPU_shader_bind(shader->shader);
- GPU_shader_uniform_float(shader->shader, shader->dither_loc, dither);
- GPU_shader_uniform_int(shader->shader, shader->overlay_loc, use_overlay);
- GPU_shader_uniform_int(shader->shader, shader->predivide_loc, use_predivide);
- GPU_shader_uniform_int(shader->shader, shader->curve_mapping_loc, use_curve_mapping);
+ /* TODO(fclem): remove remains of IMM. */
+ immBindShader(shader.shader);
- return true;
- }
+ /* Bind Shader and set uniforms. */
+ // GPU_shader_bind(shader.shader);
+ GPU_shader_uniform_float(shader.shader, shader.scale_loc, scale);
+ GPU_shader_uniform_float(shader.shader, shader.exponent_loc, exponent);
+ GPU_shader_uniform_float(shader.shader, shader.dither_loc, dither);
+ GPU_shader_uniform_int(shader.shader, shader.overlay_loc, use_overlay);
+ GPU_shader_uniform_int(shader.shader, shader.predivide_loc, use_predivide);
- return false;
+ return true;
}
-void OCIOImpl::finishGLSLDraw(OCIO_GLSLDrawState * /*state*/)
+void OCIOImpl::gpuDisplayShaderUnbind()
{
immUnbindProgram();
}
-void OCIOImpl::freeGLState(OCIO_GLSLDrawState *state)
+void OCIOImpl::gpuCacheFree()
{
- for (int i = 0; i < SHADER_CACHE_SIZE; i++) {
- if (state->shader_cache[i].data) {
- freeGLSLShader((OCIO_GLSLShader *)state->shader_cache[i].data);
- }
- if (state->lut3d_cache[i].data) {
- freeGLSLLut3d((OCIO_GLSLLut3d *)state->lut3d_cache[i].data);
- }
- if (state->curvemap_cache[i].data) {
- freeGLSLCurveMapping((OCIO_GLSLCurveMappping *)state->curvemap_cache[i].data);
- }
- }
-
- MEM_freeN(state);
+ SHADER_CACHE.clear();
}
/** \} */