bdk-blender/intern/opencolorio/ocio_impl.h
Brecht Van Lommel 1b4961b318 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
2021-02-12 19:06:35 +01:00

336 lines
17 KiB
C++

/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2012 Blender Foundation.
* All rights reserved.
*/
#ifndef __OCIO_IMPL_H__
#define __OCIO_IMPL_H__
#include "ocio_capi.h"
class IOCIOImpl {
public:
virtual ~IOCIOImpl()
{
}
virtual OCIO_ConstConfigRcPtr *getCurrentConfig(void) = 0;
virtual void setCurrentConfig(const OCIO_ConstConfigRcPtr *config) = 0;
virtual OCIO_ConstConfigRcPtr *configCreateFromEnv(void) = 0;
virtual OCIO_ConstConfigRcPtr *configCreateFromFile(const char *filename) = 0;
virtual void configRelease(OCIO_ConstConfigRcPtr *config) = 0;
virtual int configGetNumColorSpaces(OCIO_ConstConfigRcPtr *config) = 0;
virtual const char *configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *config, int index) = 0;
virtual OCIO_ConstColorSpaceRcPtr *configGetColorSpace(OCIO_ConstConfigRcPtr *config,
const char *name) = 0;
virtual int configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name) = 0;
virtual int colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs) = 0;
virtual int colorSpaceIsData(OCIO_ConstColorSpaceRcPtr *cs) = 0;
virtual void colorSpaceIsBuiltin(OCIO_ConstConfigRcPtr *config,
OCIO_ConstColorSpaceRcPtr *cs,
bool &is_scene_linear,
bool &is_srgb) = 0;
virtual void colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs) = 0;
virtual const char *configGetDefaultDisplay(OCIO_ConstConfigRcPtr *config) = 0;
virtual int configGetNumDisplays(OCIO_ConstConfigRcPtr *config) = 0;
virtual const char *configGetDisplay(OCIO_ConstConfigRcPtr *config, int index) = 0;
virtual const char *configGetDefaultView(OCIO_ConstConfigRcPtr *config, const char *display) = 0;
virtual int configGetNumViews(OCIO_ConstConfigRcPtr *config, const char *display) = 0;
virtual const char *configGetView(OCIO_ConstConfigRcPtr *config,
const char *display,
int index) = 0;
virtual const char *configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *config,
const char *display,
const char *view) = 0;
virtual void configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr *config, float *rgb) = 0;
virtual void configGetXYZtoRGB(OCIO_ConstConfigRcPtr *config, float xyz_to_rgb[3][3]) = 0;
virtual int configGetNumLooks(OCIO_ConstConfigRcPtr *config) = 0;
virtual const char *configGetLookNameByIndex(OCIO_ConstConfigRcPtr *config, int index) = 0;
virtual OCIO_ConstLookRcPtr *configGetLook(OCIO_ConstConfigRcPtr *config, const char *name) = 0;
virtual const char *lookGetProcessSpace(OCIO_ConstLookRcPtr *look) = 0;
virtual void lookRelease(OCIO_ConstLookRcPtr *look) = 0;
virtual OCIO_ConstProcessorRcPtr *configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config,
const char *srcName,
const char *dstName) = 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_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,
long height,
long numChannels,
long chanStrideBytes,
long xStrideBytes,
long yStrideBytes) = 0;
virtual void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p) = 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;
};
class FallbackImpl : public IOCIOImpl {
public:
FallbackImpl()
{
}
OCIO_ConstConfigRcPtr *getCurrentConfig(void);
void setCurrentConfig(const OCIO_ConstConfigRcPtr *config);
OCIO_ConstConfigRcPtr *configCreateFromEnv(void);
OCIO_ConstConfigRcPtr *configCreateFromFile(const char *filename);
void configRelease(OCIO_ConstConfigRcPtr *config);
int configGetNumColorSpaces(OCIO_ConstConfigRcPtr *config);
const char *configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *config, int index);
OCIO_ConstColorSpaceRcPtr *configGetColorSpace(OCIO_ConstConfigRcPtr *config, const char *name);
int configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name);
int colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs);
int colorSpaceIsData(OCIO_ConstColorSpaceRcPtr *cs);
void colorSpaceIsBuiltin(OCIO_ConstConfigRcPtr *config,
OCIO_ConstColorSpaceRcPtr *cs,
bool &is_scene_linear,
bool &is_srgb);
void colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs);
const char *configGetDefaultDisplay(OCIO_ConstConfigRcPtr *config);
int configGetNumDisplays(OCIO_ConstConfigRcPtr *config);
const char *configGetDisplay(OCIO_ConstConfigRcPtr *config, int index);
const char *configGetDefaultView(OCIO_ConstConfigRcPtr *config, const char *display);
int configGetNumViews(OCIO_ConstConfigRcPtr *config, const char *display);
const char *configGetView(OCIO_ConstConfigRcPtr *config, const char *display, int index);
const char *configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *config,
const char *display,
const char *view);
void configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr *config, float *rgb);
void configGetXYZtoRGB(OCIO_ConstConfigRcPtr *config, float xyz_to_rgb[3][3]);
int configGetNumLooks(OCIO_ConstConfigRcPtr *config);
const char *configGetLookNameByIndex(OCIO_ConstConfigRcPtr *config, int index);
OCIO_ConstLookRcPtr *configGetLook(OCIO_ConstConfigRcPtr *config, const char *name);
const char *lookGetProcessSpace(OCIO_ConstLookRcPtr *look);
void lookRelease(OCIO_ConstLookRcPtr *look);
OCIO_ConstProcessorRcPtr *configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config,
const char *srcName,
const char *dstName);
void processorRelease(OCIO_ConstProcessorRcPtr *processor);
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_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,
long height,
long numChannels,
long chanStrideBytes,
long xStrideBytes,
long yStrideBytes);
void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p);
const char *getVersionString(void);
int getVersionHex(void);
};
#ifdef WITH_OCIO
class OCIOImpl : public IOCIOImpl {
public:
OCIOImpl(){};
OCIO_ConstConfigRcPtr *getCurrentConfig(void);
void setCurrentConfig(const OCIO_ConstConfigRcPtr *config);
OCIO_ConstConfigRcPtr *configCreateFromEnv(void);
OCIO_ConstConfigRcPtr *configCreateFromFile(const char *filename);
void configRelease(OCIO_ConstConfigRcPtr *config);
int configGetNumColorSpaces(OCIO_ConstConfigRcPtr *config);
const char *configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *config, int index);
OCIO_ConstColorSpaceRcPtr *configGetColorSpace(OCIO_ConstConfigRcPtr *config, const char *name);
int configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name);
int colorSpaceIsInvertible(OCIO_ConstColorSpaceRcPtr *cs);
int colorSpaceIsData(OCIO_ConstColorSpaceRcPtr *cs);
void colorSpaceIsBuiltin(OCIO_ConstConfigRcPtr *config,
OCIO_ConstColorSpaceRcPtr *cs,
bool &is_scene_linear,
bool &is_srgb);
void colorSpaceRelease(OCIO_ConstColorSpaceRcPtr *cs);
const char *configGetDefaultDisplay(OCIO_ConstConfigRcPtr *config);
int configGetNumDisplays(OCIO_ConstConfigRcPtr *config);
const char *configGetDisplay(OCIO_ConstConfigRcPtr *config, int index);
const char *configGetDefaultView(OCIO_ConstConfigRcPtr *config, const char *display);
int configGetNumViews(OCIO_ConstConfigRcPtr *config, const char *display);
const char *configGetView(OCIO_ConstConfigRcPtr *config, const char *display, int index);
const char *configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr *config,
const char *display,
const char *view);
void configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr *config, float *rgb);
void configGetXYZtoRGB(OCIO_ConstConfigRcPtr *config, float xyz_to_rgb[3][3]);
int configGetNumLooks(OCIO_ConstConfigRcPtr *config);
const char *configGetLookNameByIndex(OCIO_ConstConfigRcPtr *config, int index);
OCIO_ConstLookRcPtr *configGetLook(OCIO_ConstConfigRcPtr *config, const char *name);
const char *lookGetProcessSpace(OCIO_ConstLookRcPtr *look);
void lookRelease(OCIO_ConstLookRcPtr *look);
OCIO_ConstProcessorRcPtr *configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config,
const char *srcName,
const char *dstName);
void processorRelease(OCIO_ConstProcessorRcPtr *processor);
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_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,
long height,
long numChannels,
long chanStrideBytes,
long xStrideBytes,
long yStrideBytes);
void OCIO_PackedImageDescRelease(OCIO_PackedImageDesc *p);
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);
};
#endif
#endif /* OCIO_IMPL_H */