diff options
30 files changed, 1329 insertions, 1713 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 51308850d3a..b6fb6dbd9dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -728,8 +728,9 @@ set_and_warn_dependency(WITH_TBB WITH_MOD_FLUID OFF) # NanoVDB requires OpenVDB to convert the data structure set_and_warn_dependency(WITH_OPENVDB WITH_NANOVDB OFF) -# OpenVDB uses 'half' type from OpenEXR & fails to link without OpenEXR enabled. +# OpenVDB and OpenColorIO uses 'half' type from OpenEXR set_and_warn_dependency(WITH_IMAGE_OPENEXR WITH_OPENVDB OFF) +set_and_warn_dependency(WITH_IMAGE_OPENEXR WITH_OPENCOLORIO OFF) # Haru needs `TIFFFaxBlackCodes` & `TIFFFaxWhiteCodes` symbols from TIFF. set_and_warn_dependency(WITH_IMAGE_TIFF WITH_HARU OFF) diff --git a/build_files/build_environment/CMakeLists.txt b/build_files/build_environment/CMakeLists.txt index 672f5820a16..8d6fd3ab4c3 100644 --- a/build_files/build_environment/CMakeLists.txt +++ b/build_files/build_environment/CMakeLists.txt @@ -70,7 +70,6 @@ include(cmake/cuew.cmake) include(cmake/opensubdiv.cmake) include(cmake/sdl.cmake) include(cmake/opencollada.cmake) -include(cmake/opencolorio.cmake) include(cmake/llvm.cmake) include(cmake/clang.cmake) if(APPLE) @@ -105,18 +104,15 @@ if(NOT APPLE) include(cmake/xr_openxr.cmake) endif() +# OpenColorIO and dependencies. +include(cmake/expat.cmake) +include(cmake/yamlcpp.cmake) +include(cmake/opencolorio.cmake) + if(WITH_WEBP) include(cmake/webp.cmake) endif() -if(WIN32) - # OCIO deps - include(cmake/tinyxml.cmake) - include(cmake/yamlcpp.cmake) - # LCMS is an OCIO dep, but only if you build the apps, leaving it here for convenience - # include(cmake/lcms.cmake) -endif() - if(NOT WIN32 OR ENABLE_MINGW64) include(cmake/gmp.cmake) include(cmake/openjpeg.cmake) diff --git a/build_files/build_environment/cmake/lcms.cmake b/build_files/build_environment/cmake/expat.cmake index c7019bc645e..001f3941de1 100644 --- a/build_files/build_environment/cmake/lcms.cmake +++ b/build_files/build_environment/cmake/expat.cmake @@ -16,16 +16,20 @@ # # ***** END GPL LICENSE BLOCK ***** -set(LCMS_EXTRA_ARGS +set(EXPAT_EXTRA_ARGS + -DEXPAT_BUILD_DOCS=OFF + -DEXPAT_BUILD_EXAMPLES=OFF + -DEXPAT_BUILD_TESTS=OFF + -DEXPAT_BUILD_TOOLS=OFF + -DEXPAT_SHARED_LIBS=OFF ) -ExternalProject_Add(external_lcms - URL ${LCMS_URI} +ExternalProject_Add(external_expat + URL ${EXPAT_URI} DOWNLOAD_DIR ${DOWNLOAD_DIR} - URL_HASH MD5=${LCMS_HASH} - PREFIX ${BUILD_DIR}/lcms - # Patch taken from ocio. - PATCH_COMMAND ${CMAKE_COMMAND} -E copy ${PATCH_DIR}/cmakelists_lcms.txt ${BUILD_DIR}/lcms/src/external_lcms/CMakeLists.txt - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/lcms ${DEFAULT_CMAKE_FLAGS} ${LCMS_EXTRA_ARGS} - INSTALL_DIR ${LIBDIR}/lcms + URL_HASH MD5=${EXPAT_HASH} + PREFIX ${BUILD_DIR}/expat + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/expat ${DEFAULT_CMAKE_FLAGS} ${EXPAT_EXTRA_ARGS} + INSTALL_DIR ${LIBDIR}/expat + SOURCE_SUBDIR expat ) diff --git a/build_files/build_environment/cmake/nasm.cmake b/build_files/build_environment/cmake/nasm.cmake index 6eadfc5e4f0..37a57273bfe 100644 --- a/build_files/build_environment/cmake/nasm.cmake +++ b/build_files/build_environment/cmake/nasm.cmake @@ -22,8 +22,8 @@ ExternalProject_Add(external_nasm URL_HASH SHA256=${NASM_HASH} PREFIX ${BUILD_DIR}/nasm PATCH_COMMAND ${PATCH_CMD} --verbose -p 1 -N -d ${BUILD_DIR}/nasm/src/external_nasm < ${PATCH_DIR}/nasm.diff - CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/nasm/src/external_nasm/ && ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/nasm - BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/nasm/src/external_nasm/ && make -j${MAKE_THREADS} + CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/nasm/src/external_nasm/ && ./autogen.sh && ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/nasm + BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/nasm/src/external_nasm/ && make -j${MAKE_THREADS} && make manpages INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/nasm/src/external_nasm/ && make install INSTALL_DIR ${LIBDIR}/nasm ) diff --git a/build_files/build_environment/cmake/opencolorio.cmake b/build_files/build_environment/cmake/opencolorio.cmake index 4ad401800d0..7622a2afdaa 100644 --- a/build_files/build_environment/cmake/opencolorio.cmake +++ b/build_files/build_environment/cmake/opencolorio.cmake @@ -18,16 +18,22 @@ set(OPENCOLORIO_EXTRA_ARGS -DOCIO_BUILD_APPS=OFF - -DOCIO_BUILD_PYGLUE=OFF + -DOCIO_BUILD_PYTHON=OFF -DOCIO_BUILD_NUKE=OFF - -DOCIO_USE_BOOST_PTR=OFF - -DOCIO_BUILD_STATIC=ON - -DOCIO_BUILD_SHARED=OFF - -DOCIO_BUILD_TRUELIGHT=OFF + -DOCIO_BUILD_JAVA=OFF + -DBUILD_SHARED_LIBS=OFF -DOCIO_BUILD_DOCS=OFF - -DOCIO_BUILD_PYGLUE=OFF - -DOCIO_BUILD_JNIGLUE=OFF - -DOCIO_STATIC_JNIGLUE=OFF + -DOCIO_BUILD_TESTS=OFF + -DOCIO_BUILD_GPU_TESTS=OFF + -DOCIO_USE_SSE=ON + + # Manually build ext packages except for pystring, which does not have + # a CMake or autotools build system that we can easily use. + -DOCIO_INSTALL_EXT_PACKAGES=MISSING + -DHalf_ROOT=${LIBDIR}/openexr + -DHalf_STATIC_LIBRARY=ON + -Dexpat_ROOT=${LIBDIR}/expat + -Dyaml-cpp_ROOT=${LIBDIR}/yamlcpp ) if(APPLE AND NOT("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "x86_64")) @@ -41,24 +47,7 @@ if(WIN32) set(OCIO_PATCH opencolorio_win.diff) set(OPENCOLORIO_EXTRA_ARGS ${OPENCOLORIO_EXTRA_ARGS} - -DOCIO_BUILD_TESTS=OFF - -DOCIO_USE_SSE=ON -DOCIO_INLINES_HIDDEN=OFF - -DOCIO_PYGLUE_LINK=OFF - -DOCIO_PYGLUE_RESPECT_ABI=OFF - -DOCIO_PYGLUE_SONAME=OFF - -DOCIO_PYGLUE_LIB_PREFIX=OFF - -DUSE_EXTERNAL_TINYXML=ON - -DTINYXML_INCLUDE_DIR=${LIBDIR}/tinyxml/include - -DTINYXML_LIBRARY=${LIBDIR}/tinyxml/lib/tinyxml${libext} - -DUSE_EXTERNAL_YAML=ON - -DYAML_CPP_FOUND=ON - -DYAML_CPP_VERSION=${YAMLCPP_VERSION} - -DUSE_EXTERNAL_LCMS=ON - -DINC_1=${LIBDIR}/tinyxml/include - -DINC_2=${LIBDIR}/yamlcpp/include - # Lie because ocio cmake is demanding boost even though it is not needed. - -DYAML_CPP_VERSION=0.5.0 ) else() set(OCIO_PATCH opencolorio.diff) @@ -72,48 +61,42 @@ ExternalProject_Add(external_opencolorio DOWNLOAD_DIR ${DOWNLOAD_DIR} URL_HASH MD5=${OPENCOLORIO_HASH} PREFIX ${BUILD_DIR}/opencolorio - PATCH_COMMAND ${PATCH_CMD} -p 1 -N -d ${BUILD_DIR}/opencolorio/src/external_opencolorio < ${PATCH_DIR}/${OCIO_PATCH} CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/opencolorio ${DEFAULT_CMAKE_FLAGS} ${OPENCOLORIO_EXTRA_ARGS} INSTALL_DIR ${LIBDIR}/opencolorio ) -if(NOT WIN32) - add_custom_command( - OUTPUT ${LIBDIR}/opencolorio/lib/libtinyxml.a - COMMAND cp ${BUILD_DIR}/opencolorio/src/external_opencolorio-build/ext/dist/lib/libtinyxml.a ${LIBDIR}/opencolorio/lib/libtinyxml.a - COMMAND cp ${BUILD_DIR}/opencolorio/src/external_opencolorio-build/ext/dist/lib/libyaml-cpp.a ${LIBDIR}/opencolorio/lib/libyaml-cpp.a - ) - add_custom_target(external_opencolorio_extra ALL DEPENDS external_opencolorio ${LIBDIR}/opencolorio/lib/libtinyxml.a) -endif() - add_dependencies( external_opencolorio - external_boost + external_yamlcpp + external_expat + external_openexr ) if(WIN32) - add_dependencies( - external_opencolorio - external_tinyxml - external_yamlcpp - - ) if(BUILD_MODE STREQUAL Release) ExternalProject_Add_Step(external_opencolorio after_install COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/opencolorio/include ${HARVEST_TARGET}/opencolorio/include - COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/opencolorio/lib/static ${HARVEST_TARGET}/opencolorio/lib + COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/opencolorio/lib ${HARVEST_TARGET}/opencolorio/lib COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/yamlcpp/lib/libyaml-cppmd.lib ${HARVEST_TARGET}/opencolorio/lib/libyaml-cpp.lib - COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/tinyxml/lib/tinyxml.lib ${HARVEST_TARGET}/opencolorio/lib/tinyxml.lib + COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/expat/lib/libexpatMD.lib ${HARVEST_TARGET}/opencolorio/lib/libexpatMD.lib + COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/opencolorio/src/external_opencolorio-build/ext/dist/lib/pystring.lib ${HARVEST_TARGET}/opencolorio/lib/pystring.lib DEPENDEES install ) endif() if(BUILD_MODE STREQUAL Debug) ExternalProject_Add_Step(external_opencolorio after_install - COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/opencolorio/lib/static/Opencolorio.lib ${HARVEST_TARGET}/opencolorio/lib/OpencolorIO_d.lib + COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/opencolorio/lib/Opencolorio.lib ${HARVEST_TARGET}/opencolorio/lib/OpencolorIO_d.lib COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/yamlcpp/lib/libyaml-cppmdd.lib ${HARVEST_TARGET}/opencolorio/lib/libyaml-cpp_d.lib - COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/tinyxml/lib/tinyxml.lib ${HARVEST_TARGET}/opencolorio/lib/tinyxml_d.lib + COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/expat/lib/libexpatdMD.lib ${HARVEST_TARGET}/opencolorio/lib/libexpatdMD.lib + COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/opencolorio/src/external_opencolorio-build/ext/dist/lib/pystring.lib ${HARVEST_TARGET}/opencolorio/lib/pystring_d.lib DEPENDEES install ) endif() - +else() + ExternalProject_Add_Step(external_opencolorio after_install + COMMAND cp ${LIBDIR}/yamlcpp/lib/libyaml-cpp.a ${LIBDIR}/opencolorio/lib/ + COMMAND cp ${LIBDIR}/expat/lib/libexpat.a ${LIBDIR}/opencolorio/lib/ + COMMAND cp ${BUILD_DIR}/opencolorio/src/external_opencolorio-build/ext/dist/lib/libpystring.a ${LIBDIR}/opencolorio/lib/ + DEPENDEES install + ) endif() diff --git a/build_files/build_environment/cmake/tinyxml.cmake b/build_files/build_environment/cmake/tinyxml.cmake deleted file mode 100644 index 763fd959d24..00000000000 --- a/build_files/build_environment/cmake/tinyxml.cmake +++ /dev/null @@ -1,31 +0,0 @@ -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# 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. -# -# ***** END GPL LICENSE BLOCK ***** - -set(TINYXML_EXTRA_ARGS -) - -ExternalProject_Add(external_tinyxml - URL ${TINYXML_URI} - DOWNLOAD_DIR ${DOWNLOAD_DIR} - URL_HASH MD5=${TINYXML_HASH} - PREFIX ${BUILD_DIR}/tinyxml - # patch taken from ocio - PATCH_COMMAND ${PATCH_CMD} -p 1 -N -d ${BUILD_DIR}/tinyxml/src/external_tinyxml < ${PATCH_DIR}/tinyxml.diff - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/tinyxml ${DEFAULT_CMAKE_FLAGS} ${TINYXML_EXTRA_ARGS} - INSTALL_DIR ${LIBDIR}/tinyxml -) diff --git a/build_files/build_environment/cmake/versions.cmake b/build_files/build_environment/cmake/versions.cmake index 76417b59bb3..3a44977e4d3 100644 --- a/build_files/build_environment/cmake/versions.cmake +++ b/build_files/build_environment/cmake/versions.cmake @@ -109,9 +109,9 @@ set(OPENCOLLADA_VERSION v1.6.68) set(OPENCOLLADA_URI https://github.com/KhronosGroup/OpenCOLLADA/archive/${OPENCOLLADA_VERSION}.tar.gz) set(OPENCOLLADA_HASH ee7dae874019fea7be11613d07567493) -set(OPENCOLORIO_VERSION 1.1.1) +set(OPENCOLORIO_VERSION 2.0.0) set(OPENCOLORIO_URI https://github.com/AcademySoftwareFoundation/OpenColorIO/archive/v${OPENCOLORIO_VERSION}.tar.gz) -set(OPENCOLORIO_HASH 23d8b9ac81599305539a5a8674b94a3d) +set(OPENCOLORIO_HASH 1a2e3478b6cd9a1549f24e1b2205e3f0) set(LLVM_VERSION 9.0.1) set(LLVM_URI https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVM_VERSION}/llvm-${LLVM_VERSION}.src.tar.xz) @@ -257,9 +257,9 @@ set(YAMLCPP_VERSION 0.6.3) set(YAMLCPP_URI https://codeload.github.com/jbeder/yaml-cpp/tar.gz/yaml-cpp-${YAMLCPP_VERSION}) set(YAMLCPP_HASH b45bf1089a382e81f6b661062c10d0c2) -set(LCMS_VERSION 2.9) -set(LCMS_URI https://nchc.dl.sourceforge.net/project/lcms/lcms/${LCMS_VERSION}/lcms2-${LCMS_VERSION}.tar.gz) -set(LCMS_HASH 8de1b7724f578d2995c8fdfa35c3ad0e) +set(EXPAT_VERSION 2_2_10) +set(EXPAT_URI https://github.com/libexpat/libexpat/archive/R_${EXPAT_VERSION}.tar.gz) +set(EXPAT_HASH 7ca5f09959fcb9a57618368deb627b9f) set(PUGIXML_VERSION 1.10) set(PUGIXML_URI https://github.com/zeux/pugixml/archive/v${PUGIXML_VERSION}.tar.gz) @@ -314,8 +314,8 @@ set(MESA_URI ftp://ftp.freedesktop.org/pub/mesa/mesa-${MESA_VERSION}.tar.xz) set(MESA_HASH d60828056d77bfdbae0970f9b15fb1be) set(NASM_VERSION 2.15.02) -set(NASM_URI https://www.nasm.us/pub/nasm/releasebuilds/${NASM_VERSION}/nasm-${NASM_VERSION}.tar.xz) -set(NASM_HASH f4fd1329b1713e1ccd34b2fc121c4bcd278c9f91cc4cb205ae8fcd2e4728dd14) +set(NASM_URI https://github.com/netwide-assembler/nasm/archive/nasm-${NASM_VERSION}.tar.gz) +set(NASM_HASH aded8b796c996a486a56e0515c83e414116decc3b184d88043480b32eb0a8589) set(XR_OPENXR_SDK_VERSION 1.0.8) set(XR_OPENXR_SDK_URI https://github.com/KhronosGroup/OpenXR-SDK/archive/release-${XR_OPENXR_SDK_VERSION}.tar.gz) diff --git a/build_files/build_environment/cmake/yamlcpp.cmake b/build_files/build_environment/cmake/yamlcpp.cmake index 3d3639593ad..d56a3e4a63a 100644 --- a/build_files/build_environment/cmake/yamlcpp.cmake +++ b/build_files/build_environment/cmake/yamlcpp.cmake @@ -17,13 +17,18 @@ # ***** END GPL LICENSE BLOCK ***** set(YAMLCPP_EXTRA_ARGS - -DBUILD_GMOCK=OFF -DYAML_CPP_BUILD_TESTS=OFF -DYAML_CPP_BUILD_TOOLS=OFF -DYAML_CPP_BUILD_CONTRIB=OFF - -DYAML_MSVC_SHARED_RT=ON ) +if(WIN32) + set(YAMLCPP_EXTRA_ARGS + ${YAMLCPP_EXTRA_ARGS} + -DBUILD_GMOCK=OFF + -DYAML_MSVC_SHARED_RT=ON) +endif() + ExternalProject_Add(external_yamlcpp URL ${YAMLCPP_URI} DOWNLOAD_DIR ${DOWNLOAD_DIR} diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh index da2a6535142..318da4f6183 100755 --- a/build_files/build_environment/install_deps.sh +++ b/build_files/build_environment/install_deps.sh @@ -454,10 +454,10 @@ TBB_FORCE_BUILD=false TBB_FORCE_REBUILD=false TBB_SKIP=false -OCIO_VERSION="1.1.1" -OCIO_VERSION_SHORT="1.1" -OCIO_VERSION_MIN="1.0" -OCIO_VERSION_MAX="1.2" +OCIO_VERSION="2.0.0" +OCIO_VERSION_SHORT="2.0" +OCIO_VERSION_MIN="2.0" +OCIO_VERSION_MAX="3.0" OCIO_FORCE_BUILD=false OCIO_FORCE_REBUILD=false OCIO_SKIP=false @@ -1787,8 +1787,8 @@ compile_OCIO() { cmake_d="$cmake_d -D CMAKE_PREFIX_PATH=$_inst" cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst" cmake_d="$cmake_d -D OCIO_BUILD_APPS=OFF" - cmake_d="$cmake_d -D OCIO_BUILD_PYGLUE=OFF" - cmake_d="$cmake_d -D STOP_ON_WARNING=OFF" + cmake_d="$cmake_d -D OCIO_BUILD_PYTHON=OFF" + cmake_d="$cmake_d -D OCIO_BUILD_GPU_TESTS=OFF" if file /bin/cp | grep -q '32-bit'; then cflags="-fPIC -m32 -march=i686" diff --git a/build_files/cmake/Modules/FindOpenColorIO.cmake b/build_files/cmake/Modules/FindOpenColorIO.cmake index 5c0ad89a0b7..21118533ebe 100644 --- a/build_files/cmake/Modules/FindOpenColorIO.cmake +++ b/build_files/cmake/Modules/FindOpenColorIO.cmake @@ -26,7 +26,8 @@ ENDIF() SET(_opencolorio_FIND_COMPONENTS OpenColorIO yaml-cpp - tinyxml + expat + pystring ) SET(_opencolorio_SEARCH_DIRS @@ -60,12 +61,23 @@ FOREACH(COMPONENT ${_opencolorio_FIND_COMPONENTS}) ENDIF() ENDFOREACH() +IF(EXISTS "${OPENCOLORIO_INCLUDE_DIR}/OpenColorIO/OpenColorABI.h") + # Search twice, because this symbol changed between OCIO 1.x and 2.x + FILE(STRINGS "${OPENCOLORIO_INCLUDE_DIR}/OpenColorIO/OpenColorABI.h" _opencolorio_version + REGEX "^#define OCIO_VERSION_STR[ \t].*$") + IF(NOT _opencolorio_version) + file(STRINGS "${OPENCOLORIO_INCLUDE_DIR}/OpenColorIO/OpenColorABI.h" _opencolorio_version + REGEX "^#define OCIO_VERSION[ \t].*$") + ENDIF() + STRING(REGEX MATCHALL "[0-9]+[.0-9]+" OPENCOLORIO_VERSION ${_opencolorio_version}) +ENDIF() # handle the QUIETLY and REQUIRED arguments and set OPENCOLORIO_FOUND to TRUE if # all listed variables are TRUE INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenColorIO DEFAULT_MSG - _opencolorio_LIBRARIES OPENCOLORIO_INCLUDE_DIR) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenColorIO + REQUIRED_VARS _opencolorio_LIBRARIES OPENCOLORIO_INCLUDE_DIR + VERSION_VAR OPENCOLORIO_VERSION) IF(OPENCOLORIO_FOUND) SET(OPENCOLORIO_LIBRARIES ${_opencolorio_LIBRARIES}) @@ -78,6 +90,7 @@ MARK_AS_ADVANCED( OPENCOLORIO_OPENCOLORIO_LIBRARY OPENCOLORIO_TINYXML_LIBRARY OPENCOLORIO_YAML-CPP_LIBRARY + OPENCOLORIO_VERSION ) UNSET(COMPONENT) diff --git a/build_files/cmake/platform/platform_apple.cmake b/build_files/cmake/platform/platform_apple.cmake index e51bdede34b..b95b21da946 100644 --- a/build_files/cmake/platform/platform_apple.cmake +++ b/build_files/cmake/platform/platform_apple.cmake @@ -297,7 +297,12 @@ if(WITH_OPENIMAGEIO) endif() if(WITH_OPENCOLORIO) - find_package(OpenColorIO) + find_package(OpenColorIO 2.0.0) + + if(NOT OPENCOLORIO_FOUND) + set(WITH_OPENCOLORIO OFF) + message(STATUS "OpenColorIO not found") + endif() endif() if(WITH_OPENVDB) diff --git a/build_files/cmake/platform/platform_unix.cmake b/build_files/cmake/platform/platform_unix.cmake index fed70c5b8b2..f212741f0b6 100644 --- a/build_files/cmake/platform/platform_unix.cmake +++ b/build_files/cmake/platform/platform_unix.cmake @@ -385,7 +385,7 @@ if(WITH_OPENIMAGEIO) endif() if(WITH_OPENCOLORIO) - find_package_wrapper(OpenColorIO) + find_package_wrapper(OpenColorIO 2.0.0) set(OPENCOLORIO_LIBRARIES ${OPENCOLORIO_LIBRARIES}) set(OPENCOLORIO_LIBPATH) # TODO, remove and reference the absolute path everywhere diff --git a/build_files/cmake/platform/platform_win32.cmake b/build_files/cmake/platform/platform_win32.cmake index 37a3eabc338..06cee51344a 100644 --- a/build_files/cmake/platform/platform_win32.cmake +++ b/build_files/cmake/platform/platform_win32.cmake @@ -500,7 +500,7 @@ if(WITH_OPENIMAGEIO) set(OPENIMAGEIO_LIBRARIES ${OIIO_OPTIMIZED} ${OIIO_DEBUG}) set(OPENIMAGEIO_DEFINITIONS "-DUSE_TBB=0") - set(OPENCOLORIO_DEFINITIONS "-DOCIO_STATIC_BUILD") + set(OPENCOLORIO_DEFINITIONS "-DDOpenColorIO_SKIP_IMPORTS") set(OPENIMAGEIO_IDIFF "${OPENIMAGEIO}/bin/idiff.exe") add_definitions(-DOIIO_STATIC_DEFINE) add_definitions(-DOIIO_NO_SSE=1) @@ -538,11 +538,13 @@ if(WITH_OPENCOLORIO) set(OPENCOLORIO_LIBPATH ${OPENCOLORIO}/lib) set(OPENCOLORIO_LIBRARIES optimized ${OPENCOLORIO_LIBPATH}/OpenColorIO.lib - optimized ${OPENCOLORIO_LIBPATH}/tinyxml.lib optimized ${OPENCOLORIO_LIBPATH}/libyaml-cpp.lib + optimized ${OPENCOLORIO_LIBPATH}/libexpatMD.lib + optimized ${OPENCOLORIO_LIBPATH}/pystring.lib debug ${OPENCOLORIO_LIBPATH}/OpencolorIO_d.lib - debug ${OPENCOLORIO_LIBPATH}/tinyxml_d.lib debug ${OPENCOLORIO_LIBPATH}/libyaml-cpp_d.lib + debug ${OPENCOLORIO_LIBPATH}/libexpatdMD.lib + debug ${OPENCOLORIO_LIBPATH}/pystring_d.lib ) set(OPENCOLORIO_DEFINITIONS) endif() diff --git a/intern/cycles/render/CMakeLists.txt b/intern/cycles/render/CMakeLists.txt index 389f913b145..c67919b375a 100644 --- a/intern/cycles/render/CMakeLists.txt +++ b/intern/cycles/render/CMakeLists.txt @@ -133,8 +133,11 @@ if(WITH_OPENCOLORIO) SYSTEM ${OPENCOLORIO_INCLUDE_DIRS} ) + list(APPEND LIB + ${OPENCOLORIO_LIBRARIES} + ) if(WIN32) - add_definitions(-DOpenColorIO_STATIC) + add_definitions(-DOpenColorIO_SKIP_IMPORTS) endif() endif() diff --git a/intern/cycles/render/colorspace.cpp b/intern/cycles/render/colorspace.cpp index 4c9e86ea278..4540793f78d 100644 --- a/intern/cycles/render/colorspace.cpp +++ b/intern/cycles/render/colorspace.cpp @@ -192,6 +192,7 @@ void ColorSpaceManager::is_builtin_colorspace(ustring colorspace, return; } + OCIO::ConstCPUProcessorRcPtr device_processor = processor->getDefaultCPUProcessor(); is_scene_linear = true; is_srgb = true; for (int i = 0; i < 256; i++) { @@ -201,10 +202,10 @@ void ColorSpaceManager::is_builtin_colorspace(ustring colorspace, 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); + device_processor->applyRGB(cR); + device_processor->applyRGB(cG); + device_processor->applyRGB(cB); + device_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 || @@ -267,6 +268,7 @@ inline void processor_apply_pixels(const OCIO::Processor *processor, T *pixels, /* TODO: implement faster version for when we know the conversion * is a simple matrix transform between linear spaces. In that case * un-premultiply is not needed. */ + OCIO::ConstCPUProcessorRcPtr device_processor = processor->getDefaultCPUProcessor(); /* Process large images in chunks to keep temporary memory requirement down. */ const size_t chunk_size = std::min((size_t)(16 * 1024 * 1024), num_pixels); @@ -289,7 +291,7 @@ inline void processor_apply_pixels(const OCIO::Processor *processor, T *pixels, } OCIO::PackedImageDesc desc((float *)float_pixels.data(), width, 1, 4); - processor->apply(desc); + device_processor->apply(desc); for (size_t i = 0; i < width; i++) { float4 value = float_pixels[i]; @@ -345,13 +347,14 @@ void ColorSpaceManager::to_scene_linear(ColorSpaceProcessor *processor_, const OCIO::Processor *processor = (const OCIO::Processor *)processor_; if (processor) { + OCIO::ConstCPUProcessorRcPtr device_processor = processor->getDefaultCPUProcessor(); if (channels == 3) { - processor->applyRGB(pixel); + device_processor->applyRGB(pixel); } else if (channels == 4) { if (pixel[3] == 1.0f || pixel[3] == 0.0f) { /* Fast path for RGBA. */ - processor->applyRGB(pixel); + device_processor->applyRGB(pixel); } else { /* Un-associate and associate alpha since color management should not @@ -363,7 +366,7 @@ void ColorSpaceManager::to_scene_linear(ColorSpaceProcessor *processor_, pixel[1] *= inv_alpha; pixel[2] *= inv_alpha; - processor->applyRGB(pixel); + device_processor->applyRGB(pixel); pixel[0] *= alpha; pixel[1] *= alpha; diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp index 332599be708..650587cb694 100644 --- a/intern/cycles/render/shader.cpp +++ b/intern/cycles/render/shader.cpp @@ -35,6 +35,7 @@ #include "util/util_foreach.h" #include "util/util_murmurhash.h" #include "util/util_task.h" +#include "util/util_transform.h" #ifdef WITH_OCIO # include <OpenColorIO/OpenColorIO.h> @@ -399,39 +400,7 @@ ShaderManager::ShaderManager() update_flags = UPDATE_ALL; beckmann_table_offset = TABLE_OFFSET_INVALID; - xyz_to_r = make_float3(3.2404542f, -1.5371385f, -0.4985314f); - xyz_to_g = make_float3(-0.9692660f, 1.8760108f, 0.0415560f); - xyz_to_b = make_float3(0.0556434f, -0.2040259f, 1.0572252f); - rgb_to_y = make_float3(0.2126729f, 0.7151522f, 0.0721750f); - -#ifdef WITH_OCIO - OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); - if (config) { - if (config->hasRole("XYZ") && config->hasRole("scene_linear")) { - OCIO::ConstProcessorRcPtr to_rgb_processor = config->getProcessor("XYZ", "scene_linear"); - OCIO::ConstProcessorRcPtr to_xyz_processor = config->getProcessor("scene_linear", "XYZ"); - if (to_rgb_processor && to_xyz_processor) { - float r[] = {1.0f, 0.0f, 0.0f}; - float g[] = {0.0f, 1.0f, 0.0f}; - float b[] = {0.0f, 0.0f, 1.0f}; - to_xyz_processor->applyRGB(r); - to_xyz_processor->applyRGB(g); - to_xyz_processor->applyRGB(b); - rgb_to_y = make_float3(r[1], g[1], b[1]); - - float x[] = {1.0f, 0.0f, 0.0f}; - float y[] = {0.0f, 1.0f, 0.0f}; - float z[] = {0.0f, 0.0f, 1.0f}; - to_rgb_processor->applyRGB(x); - to_rgb_processor->applyRGB(y); - to_rgb_processor->applyRGB(z); - xyz_to_r = make_float3(x[0], y[0], z[0]); - xyz_to_g = make_float3(x[1], y[1], z[1]); - xyz_to_b = make_float3(x[2], y[2], z[2]); - } - } - } -#endif + init_xyz_transforms(); } ShaderManager::~ShaderManager() @@ -829,4 +798,89 @@ bool ShaderManager::need_update() const return update_flags != UPDATE_NONE; } +#ifdef WITH_OCIO +static bool to_scene_linear_transform(OCIO::ConstConfigRcPtr &config, + const char *colorspace, + Transform &to_scene_linear) +{ + OCIO::ConstProcessorRcPtr processor; + try { + processor = config->getProcessor(OCIO::ROLE_SCENE_LINEAR, colorspace); + } + catch (OCIO::Exception &exception) { + return false; + } + + if (!processor) { + return false; + } + + OCIO::ConstCPUProcessorRcPtr device_processor = processor->getDefaultCPUProcessor(); + if (!device_processor) { + return false; + } + + to_scene_linear = transform_identity(); + device_processor->applyRGB(&to_scene_linear.x.x); + device_processor->applyRGB(&to_scene_linear.y.x); + device_processor->applyRGB(&to_scene_linear.z.x); + to_scene_linear = transform_transposed_inverse(to_scene_linear); + return true; +} +#endif + +void ShaderManager::init_xyz_transforms() +{ + /* Default to ITU-BT.709 in case no appropriate transform found. */ + xyz_to_r = make_float3(3.2404542f, -1.5371385f, -0.4985314f); + xyz_to_g = make_float3(-0.9692660f, 1.8760108f, 0.0415560f); + xyz_to_b = make_float3(0.0556434f, -0.2040259f, 1.0572252f); + rgb_to_y = make_float3(0.2126729f, 0.7151522f, 0.0721750f); + +#ifdef WITH_OCIO + /* Get from OpenColorO config if it has the required roles. */ + OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig(); + if (!(config && config->hasRole(OCIO::ROLE_SCENE_LINEAR))) { + return; + } + + Transform xyz_to_rgb; + + if (config->hasRole("aces_interchange")) { + /* Standard OpenColorIO role, defined as ACES2065-1. */ + const Transform xyz_to_aces = make_transform(1.0498110175f, + 0.0f, + -0.0000974845f, + 0.0f, + -0.4959030231f, + 1.3733130458f, + 0.0982400361f, + 0.0f, + 0.0f, + 0.0f, + 0.9912520182f, + 0.0f); + Transform aces_to_rgb; + if (!to_scene_linear_transform(config, "aces_interchange", aces_to_rgb)) { + return; + } + + xyz_to_rgb = aces_to_rgb * xyz_to_aces; + } + else if (config->hasRole("XYZ")) { + /* Custom role used before the standard existed. */ + if (!to_scene_linear_transform(config, "XYZ", xyz_to_rgb)) { + return; + } + } + + xyz_to_r = float4_to_float3(xyz_to_rgb.x); + xyz_to_g = float4_to_float3(xyz_to_rgb.y); + xyz_to_b = float4_to_float3(xyz_to_rgb.z); + + const Transform rgb_to_xyz = transform_inverse(xyz_to_rgb); + rgb_to_y = float4_to_float3(rgb_to_xyz.y); +#endif +} + CCL_NAMESPACE_END diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h index 4375ef9e978..f47d64f346c 100644 --- a/intern/cycles/render/shader.h +++ b/intern/cycles/render/shader.h @@ -221,6 +221,8 @@ class ShaderManager { bool need_update() const; + void init_xyz_transforms(); + protected: ShaderManager(); 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(); } /** \} */ diff --git a/release/datafiles/colormanagement/config.ocio b/release/datafiles/colormanagement/config.ocio index 5ad937e3efb..8da4b13df00 100644 --- a/release/datafiles/colormanagement/config.ocio +++ b/release/datafiles/colormanagement/config.ocio @@ -39,8 +39,8 @@ roles: # Non-color data data: Non-Color - # CIE XYZ color space - XYZ: XYZ + # For interop between configs, and to determine XYZ for rendering + aces_interchange: Linear ACES # Specifed by OCIO, not used in Blender color_timing: Filmic Log @@ -97,7 +97,10 @@ colorspaces: isdata: false allocation: lg2 allocationvars: [-8.5, 5] - to_reference: !<FileTransform> {src: rec709_to_aces.spimtx, interpolation: linear, direction: inverse} + from_reference: !<GroupTransform> + children: + - !<FileTransform> {src: srgb_to_xyz.spimtx, interpolation: linear} + - !<FileTransform> {src: xyz_to_aces.spimtx, interpolation: linear} - !<ColorSpace> name: nuke_rec709 diff --git a/release/datafiles/colormanagement/luts/aces_to_xyz.spimtx b/release/datafiles/colormanagement/luts/aces_to_xyz.spimtx deleted file mode 100644 index fbf52e63555..00000000000 --- a/release/datafiles/colormanagement/luts/aces_to_xyz.spimtx +++ /dev/null @@ -1,3 +0,0 @@ -0.9525523959 0.0000000000 0.0000936786 0 -0.3439664498 0.7281660966 -0.072132546 0 -0.0000000000 0.0000000000 1.0088251844 0 diff --git a/release/datafiles/colormanagement/luts/rec709_to_aces.spimtx b/release/datafiles/colormanagement/luts/rec709_to_aces.spimtx deleted file mode 100644 index 0f4f6bd68b4..00000000000 --- a/release/datafiles/colormanagement/luts/rec709_to_aces.spimtx +++ /dev/null @@ -1,3 +0,0 @@ -0.4395770431 0.3839148879 0.1765103489 0.0 -0.0895979404 0.8147120476 0.0956883803 0.0 -0.0174174830 0.1087378338 0.8738504052 0.0 diff --git a/release/datafiles/colormanagement/luts/xyz_to_aces.spimtx b/release/datafiles/colormanagement/luts/xyz_to_aces.spimtx new file mode 100644 index 00000000000..18bc78f5e63 --- /dev/null +++ b/release/datafiles/colormanagement/luts/xyz_to_aces.spimtx @@ -0,0 +1,3 @@ + 1.0498110175 0.0000000000 -0.0000974845 0 +-0.4959030231 1.3733130458 0.0982400361 0 + 0.0000000000 0.0000000000 0.9912520182 0 diff --git a/source/blender/imbuf/intern/IMB_colormanagement_intern.h b/source/blender/imbuf/intern/IMB_colormanagement_intern.h index 6b505a7171a..cc3f4879eea 100644 --- a/source/blender/imbuf/intern/IMB_colormanagement_intern.h +++ b/source/blender/imbuf/intern/IMB_colormanagement_intern.h @@ -32,6 +32,7 @@ extern "C" { struct ImBuf; struct OCIO_ConstProcessorRcPtr; +struct OCIO_ConstCPUProcessorRcPtr; extern float imbuf_luma_coefficients[3]; extern float imbuf_xyz_to_rgb[3][3]; @@ -46,8 +47,8 @@ typedef struct ColorSpace { char name[MAX_COLORSPACE_NAME]; char description[MAX_COLORSPACE_DESCRIPTION]; - struct OCIO_ConstProcessorRcPtr *to_scene_linear; - struct OCIO_ConstProcessorRcPtr *from_scene_linear; + struct OCIO_ConstCPUProcessorRcPtr *to_scene_linear; + struct OCIO_ConstCPUProcessorRcPtr *from_scene_linear; bool is_invertible; bool is_data; @@ -66,8 +67,8 @@ typedef struct ColorManagedDisplay { char name[MAX_COLORSPACE_NAME]; ListBase views; /* LinkData.data -> ColorManagedView */ - struct OCIO_ConstProcessorRcPtr *to_scene_linear; - struct OCIO_ConstProcessorRcPtr *from_scene_linear; + struct OCIO_ConstCPUProcessorRcPtr *to_scene_linear; + struct OCIO_ConstCPUProcessorRcPtr *from_scene_linear; } ColorManagedDisplay; typedef struct ColorManagedView { diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index 046e233fd05..8f8c12aa3b4 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -101,40 +101,26 @@ static float imbuf_linear_srgb_to_xyz[3][3] = {{0.0f}}; static pthread_mutex_t processor_lock = BLI_MUTEX_INITIALIZER; typedef struct ColormanageProcessor { - OCIO_ConstProcessorRcPtr *processor; + OCIO_ConstCPUProcessorRcPtr *cpu_processor; CurveMapping *curve_mapping; bool is_data_result; } ColormanageProcessor; -static struct global_glsl_state { - /* Actual processor used for GLSL baked LUTs. */ - /* UI colorspace here refers to the display linear color space, - * i.e: The linear color space w.r.t. display chromaticity and radiometry. - * We separate the colormanagement process into two steps to be able to - * merge UI using alpha blending in the correct color space. */ - OCIO_ConstProcessorRcPtr *processor_scene_to_ui; - OCIO_ConstProcessorRcPtr *processor_ui_to_display; - - /* Settings of processor for comparison. */ - char look[MAX_COLORSPACE_NAME]; - char view[MAX_COLORSPACE_NAME]; - char display[MAX_COLORSPACE_NAME]; - char input[MAX_COLORSPACE_NAME]; - float exposure, gamma; +static struct global_gpu_state { + /* GPU shader currently bound. */ + bool gpu_shader_bound; + /* Curve mapping. */ CurveMapping *curve_mapping, *orig_curve_mapping; bool use_curve_mapping; int curve_mapping_timestamp; OCIO_CurveMappingSettings curve_mapping_settings; - - /* Container for GLSL state needed for OCIO module. */ - struct OCIO_GLSLDrawState *ocio_glsl_state; -} global_glsl_state = {NULL}; +} global_gpu_state = {NULL}; static struct global_color_picking_state { /* Cached processor for color picking conversion. */ - OCIO_ConstProcessorRcPtr *processor_to; - OCIO_ConstProcessorRcPtr *processor_from; + OCIO_ConstCPUProcessorRcPtr *cpu_processor_to; + OCIO_ConstCPUProcessorRcPtr *cpu_processor_from; bool failed; } global_color_picking_state = {NULL}; @@ -609,11 +595,10 @@ static void colormanage_free_config(void) /* free precomputer processors */ if (colorspace->to_scene_linear) { - OCIO_processorRelease((OCIO_ConstProcessorRcPtr *)colorspace->to_scene_linear); + OCIO_cpuProcessorRelease((OCIO_ConstCPUProcessorRcPtr *)colorspace->to_scene_linear); } - if (colorspace->from_scene_linear) { - OCIO_processorRelease((OCIO_ConstProcessorRcPtr *)colorspace->from_scene_linear); + OCIO_cpuProcessorRelease((OCIO_ConstCPUProcessorRcPtr *)colorspace->from_scene_linear); } /* free color space itself */ @@ -631,11 +616,10 @@ static void colormanage_free_config(void) /* free precomputer processors */ if (display->to_scene_linear) { - OCIO_processorRelease((OCIO_ConstProcessorRcPtr *)display->to_scene_linear); + OCIO_cpuProcessorRelease((OCIO_ConstCPUProcessorRcPtr *)display->to_scene_linear); } - if (display->from_scene_linear) { - OCIO_processorRelease((OCIO_ConstProcessorRcPtr *)display->from_scene_linear); + OCIO_cpuProcessorRelease((OCIO_ConstCPUProcessorRcPtr *)display->from_scene_linear); } /* free list of views */ @@ -727,35 +711,25 @@ void colormanagement_init(void) void colormanagement_exit(void) { - if (global_glsl_state.processor_scene_to_ui) { - OCIO_processorRelease(global_glsl_state.processor_scene_to_ui); - } - - if (global_glsl_state.processor_ui_to_display) { - OCIO_processorRelease(global_glsl_state.processor_ui_to_display); - } - - if (global_glsl_state.curve_mapping) { - BKE_curvemapping_free(global_glsl_state.curve_mapping); - } + OCIO_gpuCacheFree(); - if (global_glsl_state.curve_mapping_settings.lut) { - MEM_freeN(global_glsl_state.curve_mapping_settings.lut); + if (global_gpu_state.curve_mapping) { + BKE_curvemapping_free(global_gpu_state.curve_mapping); } - if (global_glsl_state.ocio_glsl_state) { - OCIO_freeOGLState(global_glsl_state.ocio_glsl_state); + if (global_gpu_state.curve_mapping_settings.lut) { + MEM_freeN(global_gpu_state.curve_mapping_settings.lut); } - if (global_color_picking_state.processor_to) { - OCIO_processorRelease(global_color_picking_state.processor_to); + if (global_color_picking_state.cpu_processor_to) { + OCIO_cpuProcessorRelease(global_color_picking_state.cpu_processor_to); } - if (global_color_picking_state.processor_from) { - OCIO_processorRelease(global_color_picking_state.processor_from); + if (global_color_picking_state.cpu_processor_from) { + OCIO_cpuProcessorRelease(global_color_picking_state.cpu_processor_from); } - memset(&global_glsl_state, 0, sizeof(global_glsl_state)); + memset(&global_gpu_state, 0, sizeof(global_gpu_state)); memset(&global_color_picking_state, 0, sizeof(global_color_picking_state)); colormanage_free_config(); @@ -777,6 +751,12 @@ static bool colormanage_compatible_look(ColorManagedLook *look, const char *view return (look->view[0] == 0 || (view_name && STREQ(look->view, view_name))); } +static bool colormanage_use_look(const char *look, const char *view_name) +{ + ColorManagedLook *look_descr = colormanage_look_get_named(look); + return (look_descr->is_noop == false && colormanage_compatible_look(look_descr, view_name)); +} + void colormanage_cache_free(ImBuf *ibuf) { if (ibuf->display_buffer_flags) { @@ -852,95 +832,31 @@ static ColorSpace *display_transform_get_colorspace( return NULL; } -static OCIO_ConstProcessorRcPtr *create_display_buffer_processor(const char *look, - const char *view_transform, - const char *display, - float exposure, - float gamma, - const char *from_colorspace, - const bool linear_output) +static OCIO_ConstCPUProcessorRcPtr *create_display_buffer_processor(const char *look, + const char *view_transform, + const char *display, + float exposure, + float gamma, + const char *from_colorspace) { OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig(); - OCIO_DisplayTransformRcPtr *dt; - OCIO_ConstProcessorRcPtr *processor; - ColorManagedLook *look_descr = colormanage_look_get_named(look); - - dt = OCIO_createDisplayTransform(); - - OCIO_displayTransformSetInputColorSpaceName(dt, from_colorspace); - OCIO_displayTransformSetView(dt, view_transform); - OCIO_displayTransformSetDisplay(dt, display); - - if (look_descr->is_noop == false && colormanage_compatible_look(look_descr, view_transform)) { - OCIO_displayTransformSetLooksOverrideEnabled(dt, true); - OCIO_displayTransformSetLooksOverride(dt, look); - } - - /* fstop exposure control */ - if (exposure != 0.0f) { - OCIO_MatrixTransformRcPtr *mt; - float gain = powf(2.0f, exposure); - const float scale4f[] = {gain, gain, gain, 1.0f}; - float m44[16], offset4[4]; - - OCIO_matrixTransformScale(m44, offset4, scale4f); - mt = OCIO_createMatrixTransform(); - OCIO_matrixTransformSetValue(mt, m44, offset4); - OCIO_displayTransformSetLinearCC(dt, (OCIO_ConstTransformRcPtr *)mt); - - OCIO_matrixTransformRelease(mt); - } - - /* post-display gamma transform */ - if (gamma != 1.0f) { - OCIO_ExponentTransformRcPtr *et; - float exponent = 1.0f / MAX2(FLT_EPSILON, gamma); - const float exponent4f[] = {exponent, exponent, exponent, exponent}; + const bool use_look = colormanage_use_look(look, view_transform); + const float scale = (exposure == 0.0f) ? 1.0f : powf(2.0f, exposure); + const float exponent = (gamma == 1.0f) ? 1.0f : 1.0f / max_ff(FLT_EPSILON, gamma); - et = OCIO_createExponentTransform(); - OCIO_exponentTransformSetValue(et, exponent4f); - OCIO_displayTransformSetDisplayCC(dt, (OCIO_ConstTransformRcPtr *)et); + OCIO_ConstProcessorRcPtr *processor = OCIO_createDisplayProcessor( + config, from_colorspace, view_transform, display, (use_look) ? look : "", scale, exponent); - OCIO_exponentTransformRelease(et); - } - - OCIO_GroupTransformRcPtr *gt = OCIO_createGroupTransform(); - OCIO_groupTransformSetDirection(gt, true); - OCIO_groupTransformPushBack(gt, (OCIO_ConstTransformRcPtr *)dt); - - if (linear_output) { - /* TODO use correct function display. */ - OCIO_ExponentTransformRcPtr *et = OCIO_createExponentTransform(); - OCIO_exponentTransformSetValue(et, (float[4]){2.2f, 2.2f, 2.2f, 1.0f}); - OCIO_groupTransformPushBack(gt, (OCIO_ConstTransformRcPtr *)et); - OCIO_exponentTransformRelease(et); - } - - processor = OCIO_configGetProcessor(config, (OCIO_ConstTransformRcPtr *)gt); - - OCIO_groupTransformRelease(gt); - OCIO_displayTransformRelease(dt); OCIO_configRelease(config); - return processor; -} - -static OCIO_ConstProcessorRcPtr *create_display_encoded_buffer_processor( - const char *UNUSED(display)) -{ - OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig(); - OCIO_ConstProcessorRcPtr *processor; - - /* TODO use correct function display. */ - OCIO_ExponentTransformRcPtr *et = OCIO_createExponentTransform(); - OCIO_exponentTransformSetValue(et, (float[4]){1.0f / 2.2f, 1.0f / 2.2f, 1.0f / 2.2f, 1.0f}); - - processor = OCIO_configGetProcessor(config, (OCIO_ConstTransformRcPtr *)et); + if (processor == NULL) { + return NULL; + } - OCIO_exponentTransformRelease(et); - OCIO_configRelease(config); + OCIO_ConstCPUProcessorRcPtr *cpu_processor = OCIO_processorGetCPUProcessor(processor); + OCIO_processorRelease(processor); - return processor; + return cpu_processor; } static OCIO_ConstProcessorRcPtr *create_colorspace_transform_processor(const char *from_colorspace, @@ -956,43 +872,54 @@ static OCIO_ConstProcessorRcPtr *create_colorspace_transform_processor(const cha return processor; } -static OCIO_ConstProcessorRcPtr *colorspace_to_scene_linear_processor(ColorSpace *colorspace) +static OCIO_ConstCPUProcessorRcPtr *colorspace_to_scene_linear_cpu_processor( + ColorSpace *colorspace) { if (colorspace->to_scene_linear == NULL) { BLI_mutex_lock(&processor_lock); if (colorspace->to_scene_linear == NULL) { - OCIO_ConstProcessorRcPtr *to_scene_linear; - to_scene_linear = create_colorspace_transform_processor(colorspace->name, - global_role_scene_linear); - colorspace->to_scene_linear = (struct OCIO_ConstProcessorRcPtr *)to_scene_linear; + OCIO_ConstProcessorRcPtr *processor = create_colorspace_transform_processor( + colorspace->name, global_role_scene_linear); + + if (processor != NULL) { + colorspace->to_scene_linear = (struct OCIO_ConstCPUProcessorRcPtr *) + OCIO_processorGetCPUProcessor(processor); + OCIO_processorRelease(processor); + } } BLI_mutex_unlock(&processor_lock); } - return (OCIO_ConstProcessorRcPtr *)colorspace->to_scene_linear; + return (OCIO_ConstCPUProcessorRcPtr *)colorspace->to_scene_linear; } -static OCIO_ConstProcessorRcPtr *colorspace_from_scene_linear_processor(ColorSpace *colorspace) +static OCIO_ConstCPUProcessorRcPtr *colorspace_from_scene_linear_cpu_processor( + ColorSpace *colorspace) { if (colorspace->from_scene_linear == NULL) { BLI_mutex_lock(&processor_lock); if (colorspace->from_scene_linear == NULL) { - OCIO_ConstProcessorRcPtr *from_scene_linear; - from_scene_linear = create_colorspace_transform_processor(global_role_scene_linear, - colorspace->name); - colorspace->from_scene_linear = (struct OCIO_ConstProcessorRcPtr *)from_scene_linear; + OCIO_ConstProcessorRcPtr *processor = create_colorspace_transform_processor( + global_role_scene_linear, colorspace->name); + + if (processor != NULL) { + colorspace->from_scene_linear = (struct OCIO_ConstCPUProcessorRcPtr *) + OCIO_processorGetCPUProcessor(processor); + OCIO_processorRelease(processor); + } } BLI_mutex_unlock(&processor_lock); } - return (OCIO_ConstProcessorRcPtr *)colorspace->from_scene_linear; + return (OCIO_ConstCPUProcessorRcPtr *)colorspace->from_scene_linear; } -static OCIO_ConstProcessorRcPtr *display_from_scene_linear_processor(ColorManagedDisplay *display) +static OCIO_ConstCPUProcessorRcPtr *display_from_scene_linear_processor( + ColorManagedDisplay *display) { if (display->from_scene_linear == NULL) { BLI_mutex_lock(&processor_lock); @@ -1011,16 +938,20 @@ static OCIO_ConstProcessorRcPtr *display_from_scene_linear_processor(ColorManage OCIO_configRelease(config); } - display->from_scene_linear = (struct OCIO_ConstProcessorRcPtr *)processor; + if (processor != NULL) { + display->from_scene_linear = (struct OCIO_ConstCPUProcessorRcPtr *) + OCIO_processorGetCPUProcessor(processor); + OCIO_processorRelease(processor); + } } BLI_mutex_unlock(&processor_lock); } - return (OCIO_ConstProcessorRcPtr *)display->from_scene_linear; + return (OCIO_ConstCPUProcessorRcPtr *)display->from_scene_linear; } -static OCIO_ConstProcessorRcPtr *display_to_scene_linear_processor(ColorManagedDisplay *display) +static OCIO_ConstCPUProcessorRcPtr *display_to_scene_linear_processor(ColorManagedDisplay *display) { if (display->to_scene_linear == NULL) { BLI_mutex_lock(&processor_lock); @@ -1039,13 +970,17 @@ static OCIO_ConstProcessorRcPtr *display_to_scene_linear_processor(ColorManagedD OCIO_configRelease(config); } - display->to_scene_linear = (struct OCIO_ConstProcessorRcPtr *)processor; + if (processor != NULL) { + display->to_scene_linear = (struct OCIO_ConstCPUProcessorRcPtr *) + OCIO_processorGetCPUProcessor(processor); + OCIO_processorRelease(processor); + } } BLI_mutex_unlock(&processor_lock); } - return (OCIO_ConstProcessorRcPtr *)display->to_scene_linear; + return (OCIO_ConstCPUProcessorRcPtr *)display->to_scene_linear; } void IMB_colormanagement_init_default_view_settings( @@ -2168,7 +2103,7 @@ void IMB_colormanagement_transform_v4(float pixel[4], */ void IMB_colormanagement_colorspace_to_scene_linear_v3(float pixel[3], ColorSpace *colorspace) { - OCIO_ConstProcessorRcPtr *processor; + OCIO_ConstCPUProcessorRcPtr *processor; if (!colorspace) { /* should never happen */ @@ -2176,17 +2111,17 @@ void IMB_colormanagement_colorspace_to_scene_linear_v3(float pixel[3], ColorSpac return; } - processor = colorspace_to_scene_linear_processor(colorspace); + processor = colorspace_to_scene_linear_cpu_processor(colorspace); - if (processor) { - OCIO_processorApplyRGB(processor, pixel); + if (processor != NULL) { + OCIO_cpuProcessorApplyRGB(processor, pixel); } } /* same as above, but converts colors in opposite direction */ void IMB_colormanagement_scene_linear_to_colorspace_v3(float pixel[3], ColorSpace *colorspace) { - OCIO_ConstProcessorRcPtr *processor; + OCIO_ConstCPUProcessorRcPtr *processor; if (!colorspace) { /* should never happen */ @@ -2194,10 +2129,10 @@ void IMB_colormanagement_scene_linear_to_colorspace_v3(float pixel[3], ColorSpac return; } - processor = colorspace_from_scene_linear_processor(colorspace); + processor = colorspace_from_scene_linear_cpu_processor(colorspace); - if (processor) { - OCIO_processorApplyRGB(processor, pixel); + if (processor != NULL) { + OCIO_cpuProcessorApplyRGB(processor, pixel); } } @@ -2205,7 +2140,7 @@ void IMB_colormanagement_colorspace_to_scene_linear_v4(float pixel[4], bool predivide, ColorSpace *colorspace) { - OCIO_ConstProcessorRcPtr *processor; + OCIO_ConstCPUProcessorRcPtr *processor; if (!colorspace) { /* should never happen */ @@ -2213,14 +2148,14 @@ void IMB_colormanagement_colorspace_to_scene_linear_v4(float pixel[4], return; } - processor = colorspace_to_scene_linear_processor(colorspace); + processor = colorspace_to_scene_linear_cpu_processor(colorspace); - if (processor) { + if (processor != NULL) { if (predivide) { - OCIO_processorApplyRGBA_predivide(processor, pixel); + OCIO_cpuProcessorApplyRGBA_predivide(processor, pixel); } else { - OCIO_processorApplyRGBA(processor, pixel); + OCIO_cpuProcessorApplyRGBA(processor, pixel); } } } @@ -2232,7 +2167,7 @@ void IMB_colormanagement_colorspace_to_scene_linear(float *buffer, struct ColorSpace *colorspace, bool predivide) { - OCIO_ConstProcessorRcPtr *processor; + OCIO_ConstCPUProcessorRcPtr *processor; if (!colorspace) { /* should never happen */ @@ -2240,9 +2175,9 @@ void IMB_colormanagement_colorspace_to_scene_linear(float *buffer, return; } - processor = colorspace_to_scene_linear_processor(colorspace); + processor = colorspace_to_scene_linear_cpu_processor(colorspace); - if (processor) { + if (processor != NULL) { OCIO_PackedImageDesc *img; img = OCIO_createOCIO_PackedImageDesc(buffer, @@ -2254,10 +2189,10 @@ void IMB_colormanagement_colorspace_to_scene_linear(float *buffer, (size_t)channels * sizeof(float) * width); if (predivide) { - OCIO_processorApply_predivide(processor, img); + OCIO_cpuProcessorApply_predivide(processor, img); } else { - OCIO_processorApply(processor, img); + OCIO_cpuProcessorApply(processor, img); } OCIO_PackedImageDescRelease(img); @@ -2278,10 +2213,10 @@ void IMB_colormanagement_imbuf_to_byte_texture(unsigned char *out_buffer, * without precision or performance loss at minimal memory usage. */ BLI_assert(ibuf->rect && ibuf->rect_float == NULL); - OCIO_ConstProcessorRcPtr *processor = NULL; + OCIO_ConstCPUProcessorRcPtr *processor = NULL; if (compress_as_srgb && ibuf->rect_colorspace && !IMB_colormanagement_space_is_srgb(ibuf->rect_colorspace)) { - processor = colorspace_to_scene_linear_processor(ibuf->rect_colorspace); + processor = colorspace_to_scene_linear_cpu_processor(ibuf->rect_colorspace); } /* TODO(brecht): make this multi-threaded, or at least process in batches. */ @@ -2294,12 +2229,12 @@ void IMB_colormanagement_imbuf_to_byte_texture(unsigned char *out_buffer, const unsigned char *in = in_buffer + in_offset * 4; unsigned char *out = out_buffer + out_offset * 4; - if (processor) { + if (processor != NULL) { /* Convert to scene linear, to sRGB and premultiply. */ for (int x = 0; x < width; x++, in += 4, out += 4) { float pixel[4]; rgba_uchar_to_float(pixel, in); - OCIO_processorApplyRGB(processor, pixel); + OCIO_cpuProcessorApplyRGB(processor, pixel); linearrgb_to_srgb_v3_v3(pixel, pixel); if (use_premultiply) { mul_v3_fl(pixel, pixel[3]); @@ -2390,15 +2325,19 @@ void IMB_colormanagement_imbuf_to_float_texture(float *out_buffer, */ void IMB_colormanagement_scene_linear_to_color_picking_v3(float pixel[3]) { - if (!global_color_picking_state.processor_to && !global_color_picking_state.failed) { + if (!global_color_picking_state.cpu_processor_to && !global_color_picking_state.failed) { /* Create processor if none exists. */ BLI_mutex_lock(&processor_lock); - if (!global_color_picking_state.processor_to && !global_color_picking_state.failed) { - global_color_picking_state.processor_to = create_colorspace_transform_processor( + if (!global_color_picking_state.cpu_processor_to && !global_color_picking_state.failed) { + OCIO_ConstProcessorRcPtr *processor = create_colorspace_transform_processor( global_role_scene_linear, global_role_color_picking); - if (!global_color_picking_state.processor_to) { + if (processor != NULL) { + global_color_picking_state.cpu_processor_to = OCIO_processorGetCPUProcessor(processor); + OCIO_processorRelease(processor); + } + else { global_color_picking_state.failed = true; } } @@ -2406,22 +2345,26 @@ void IMB_colormanagement_scene_linear_to_color_picking_v3(float pixel[3]) BLI_mutex_unlock(&processor_lock); } - if (global_color_picking_state.processor_to) { - OCIO_processorApplyRGB(global_color_picking_state.processor_to, pixel); + if (global_color_picking_state.cpu_processor_to) { + OCIO_cpuProcessorApplyRGB(global_color_picking_state.cpu_processor_to, pixel); } } void IMB_colormanagement_color_picking_to_scene_linear_v3(float pixel[3]) { - if (!global_color_picking_state.processor_from && !global_color_picking_state.failed) { + if (!global_color_picking_state.cpu_processor_from && !global_color_picking_state.failed) { /* Create processor if none exists. */ BLI_mutex_lock(&processor_lock); - if (!global_color_picking_state.processor_from && !global_color_picking_state.failed) { - global_color_picking_state.processor_from = create_colorspace_transform_processor( + if (!global_color_picking_state.cpu_processor_from && !global_color_picking_state.failed) { + OCIO_ConstProcessorRcPtr *processor = create_colorspace_transform_processor( global_role_color_picking, global_role_scene_linear); - if (!global_color_picking_state.processor_from) { + if (processor != NULL) { + global_color_picking_state.cpu_processor_from = OCIO_processorGetCPUProcessor(processor); + OCIO_processorRelease(processor); + } + else { global_color_picking_state.failed = true; } } @@ -2429,8 +2372,8 @@ void IMB_colormanagement_color_picking_to_scene_linear_v3(float pixel[3]) BLI_mutex_unlock(&processor_lock); } - if (global_color_picking_state.processor_from) { - OCIO_processorApplyRGB(global_color_picking_state.processor_from, pixel); + if (global_color_picking_state.cpu_processor_from) { + OCIO_cpuProcessorApplyRGB(global_color_picking_state.cpu_processor_from, pixel); } } @@ -2456,24 +2399,20 @@ void IMB_colormanagement_srgb_to_scene_linear_v3(float pixel[3]) */ void IMB_colormanagement_scene_linear_to_display_v3(float pixel[3], ColorManagedDisplay *display) { - OCIO_ConstProcessorRcPtr *processor; - - processor = display_from_scene_linear_processor(display); + OCIO_ConstCPUProcessorRcPtr *processor = display_from_scene_linear_processor(display); - if (processor) { - OCIO_processorApplyRGB(processor, pixel); + if (processor != NULL) { + OCIO_cpuProcessorApplyRGB(processor, pixel); } } /* same as above, but converts color in opposite direction */ void IMB_colormanagement_display_to_scene_linear_v3(float pixel[3], ColorManagedDisplay *display) { - OCIO_ConstProcessorRcPtr *processor; + OCIO_ConstCPUProcessorRcPtr *processor = display_to_scene_linear_processor(display); - processor = display_to_scene_linear_processor(display); - - if (processor) { - OCIO_processorApplyRGB(processor, pixel); + if (processor != NULL) { + OCIO_cpuProcessorApplyRGB(processor, pixel); } } @@ -3833,13 +3772,13 @@ ColormanageProcessor *IMB_colormanagement_display_processor_new( cm_processor->is_data_result = display_space->is_data; } - cm_processor->processor = create_display_buffer_processor(applied_view_settings->look, - applied_view_settings->view_transform, - display_settings->display_device, - applied_view_settings->exposure, - applied_view_settings->gamma, - global_role_scene_linear, - false); + cm_processor->cpu_processor = create_display_buffer_processor( + applied_view_settings->look, + applied_view_settings->view_transform, + display_settings->display_device, + applied_view_settings->exposure, + applied_view_settings->gamma, + global_role_scene_linear); if (applied_view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) { cm_processor->curve_mapping = BKE_curvemapping_copy(applied_view_settings->curve_mapping); @@ -3860,7 +3799,12 @@ ColormanageProcessor *IMB_colormanagement_colorspace_processor_new(const char *f color_space = colormanage_colorspace_get_named(to_colorspace); cm_processor->is_data_result = color_space->is_data; - cm_processor->processor = create_colorspace_transform_processor(from_colorspace, to_colorspace); + OCIO_ConstProcessorRcPtr *processor = create_colorspace_transform_processor(from_colorspace, + to_colorspace); + if (processor != NULL) { + cm_processor->cpu_processor = OCIO_processorGetCPUProcessor(processor); + } + OCIO_processorRelease(processor); return cm_processor; } @@ -3871,8 +3815,8 @@ void IMB_colormanagement_processor_apply_v4(ColormanageProcessor *cm_processor, BKE_curvemapping_evaluate_premulRGBF(cm_processor->curve_mapping, pixel, pixel); } - if (cm_processor->processor) { - OCIO_processorApplyRGBA(cm_processor->processor, pixel); + if (cm_processor->cpu_processor) { + OCIO_cpuProcessorApplyRGBA(cm_processor->cpu_processor, pixel); } } @@ -3883,8 +3827,8 @@ void IMB_colormanagement_processor_apply_v4_predivide(ColormanageProcessor *cm_p BKE_curvemapping_evaluate_premulRGBF(cm_processor->curve_mapping, pixel, pixel); } - if (cm_processor->processor) { - OCIO_processorApplyRGBA_predivide(cm_processor->processor, pixel); + if (cm_processor->cpu_processor) { + OCIO_cpuProcessorApplyRGBA_predivide(cm_processor->cpu_processor, pixel); } } @@ -3894,8 +3838,8 @@ void IMB_colormanagement_processor_apply_v3(ColormanageProcessor *cm_processor, BKE_curvemapping_evaluate_premulRGBF(cm_processor->curve_mapping, pixel, pixel); } - if (cm_processor->processor) { - OCIO_processorApplyRGB(cm_processor->processor, pixel); + if (cm_processor->cpu_processor) { + OCIO_cpuProcessorApplyRGB(cm_processor->cpu_processor, pixel); } } @@ -3940,7 +3884,7 @@ void IMB_colormanagement_processor_apply(ColormanageProcessor *cm_processor, } } - if (cm_processor->processor && channels >= 3) { + if (cm_processor->cpu_processor && channels >= 3) { OCIO_PackedImageDesc *img; /* apply OCIO processor */ @@ -3953,10 +3897,10 @@ void IMB_colormanagement_processor_apply(ColormanageProcessor *cm_processor, (size_t)channels * sizeof(float) * width); if (predivide) { - OCIO_processorApply_predivide(cm_processor->processor, img); + OCIO_cpuProcessorApply_predivide(cm_processor->cpu_processor, img); } else { - OCIO_processorApply(cm_processor->processor, img); + OCIO_cpuProcessorApply(cm_processor->cpu_processor, img); } OCIO_PackedImageDescRelease(img); @@ -3986,8 +3930,8 @@ void IMB_colormanagement_processor_free(ColormanageProcessor *cm_processor) if (cm_processor->curve_mapping) { BKE_curvemapping_free(cm_processor->curve_mapping); } - if (cm_processor->processor) { - OCIO_processorRelease(cm_processor->processor); + if (cm_processor->cpu_processor) { + OCIO_cpuProcessorRelease(cm_processor->cpu_processor); } MEM_freeN(cm_processor); @@ -3995,19 +3939,6 @@ void IMB_colormanagement_processor_free(ColormanageProcessor *cm_processor) /* **** OpenGL drawing routines using GLSL for color space transform ***** */ -static bool check_glsl_display_processor_changed( - const ColorManagedViewSettings *view_settings, - const ColorManagedDisplaySettings *display_settings, - const char *from_colorspace) -{ - return !(global_glsl_state.exposure == view_settings->exposure && - global_glsl_state.gamma == view_settings->gamma && - STREQ(global_glsl_state.look, view_settings->look) && - STREQ(global_glsl_state.view, view_settings->view_transform) && - STREQ(global_glsl_state.display, display_settings->display_device) && - STREQ(global_glsl_state.input, from_colorspace)); -} - static void curve_mapping_to_ocio_settings(CurveMapping *curve_mapping, OCIO_CurveMappingSettings *curve_mapping_settings) { @@ -4041,94 +3972,60 @@ static void curve_mapping_to_ocio_settings(CurveMapping *curve_mapping, curve_mapping_settings->cache_id = (size_t)curve_mapping + curve_mapping->changed_timestamp; } -static void update_glsl_display_processor(const ColorManagedViewSettings *view_settings, - const ColorManagedDisplaySettings *display_settings, - const char *from_colorspace) +static OCIO_CurveMappingSettings *update_glsl_curve_mapping( + const ColorManagedViewSettings *view_settings) { - bool use_curve_mapping = (view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) != 0; - bool need_update = false; - - need_update = global_glsl_state.processor_scene_to_ui == NULL || - check_glsl_display_processor_changed( - view_settings, display_settings, from_colorspace) || - use_curve_mapping != global_glsl_state.use_curve_mapping; - - if (use_curve_mapping && need_update == false) { - need_update |= view_settings->curve_mapping->changed_timestamp != - global_glsl_state.curve_mapping_timestamp || - view_settings->curve_mapping != global_glsl_state.orig_curve_mapping; + /* Using curve mapping? */ + const bool use_curve_mapping = (view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) != 0; + if (!use_curve_mapping) { + return NULL; } - /* Update state if there's no processor yet or - * processor settings has been changed. - */ - if (need_update) { - OCIO_CurveMappingSettings *curve_mapping_settings = &global_glsl_state.curve_mapping_settings; - CurveMapping *new_curve_mapping = NULL; - - /* Store settings of processor for further comparison. */ - BLI_strncpy(global_glsl_state.look, view_settings->look, MAX_COLORSPACE_NAME); - BLI_strncpy(global_glsl_state.view, view_settings->view_transform, MAX_COLORSPACE_NAME); - BLI_strncpy(global_glsl_state.display, display_settings->display_device, MAX_COLORSPACE_NAME); - BLI_strncpy(global_glsl_state.input, from_colorspace, MAX_COLORSPACE_NAME); - global_glsl_state.exposure = view_settings->exposure; - global_glsl_state.gamma = view_settings->gamma; - - /* We're using curve mapping's address as a cache ID, - * so we need to make sure re-allocation gives new address here. - * We do this by allocating new curve mapping before freeing old one. */ - if (use_curve_mapping) { - new_curve_mapping = BKE_curvemapping_copy(view_settings->curve_mapping); - } - - if (global_glsl_state.curve_mapping) { - BKE_curvemapping_free(global_glsl_state.curve_mapping); - MEM_freeN(curve_mapping_settings->lut); - global_glsl_state.curve_mapping = NULL; - curve_mapping_settings->lut = NULL; - } - - /* Fill in OCIO's curve mapping settings. */ - if (use_curve_mapping) { - curve_mapping_to_ocio_settings(new_curve_mapping, &global_glsl_state.curve_mapping_settings); + /* Already up to date? */ + OCIO_CurveMappingSettings *curve_mapping_settings = &global_gpu_state.curve_mapping_settings; + if (view_settings->curve_mapping->changed_timestamp == + global_gpu_state.curve_mapping_timestamp && + view_settings->curve_mapping == global_gpu_state.orig_curve_mapping) { + return curve_mapping_settings; + } - global_glsl_state.curve_mapping = new_curve_mapping; - global_glsl_state.curve_mapping_timestamp = view_settings->curve_mapping->changed_timestamp; - global_glsl_state.orig_curve_mapping = view_settings->curve_mapping; - global_glsl_state.use_curve_mapping = true; - } - else { - global_glsl_state.orig_curve_mapping = NULL; - global_glsl_state.use_curve_mapping = false; - } + /* Need to update. */ + CurveMapping *new_curve_mapping = NULL; - /* Free old processor, if any. */ - if (global_glsl_state.processor_scene_to_ui) { - OCIO_processorRelease(global_glsl_state.processor_scene_to_ui); - } + /* We're using curve mapping's address as a cache ID, + * so we need to make sure re-allocation gives new address here. + * We do this by allocating new curve mapping before freeing old one. */ + if (use_curve_mapping) { + new_curve_mapping = BKE_curvemapping_copy(view_settings->curve_mapping); + } - if (global_glsl_state.processor_ui_to_display) { - OCIO_processorRelease(global_glsl_state.processor_ui_to_display); - } + if (global_gpu_state.curve_mapping) { + BKE_curvemapping_free(global_gpu_state.curve_mapping); + MEM_freeN(curve_mapping_settings->lut); + global_gpu_state.curve_mapping = NULL; + curve_mapping_settings->lut = NULL; + } - /* We're using display OCIO processor, no RGB curves yet. */ - global_glsl_state.processor_scene_to_ui = create_display_buffer_processor( - global_glsl_state.look, - global_glsl_state.view, - global_glsl_state.display, - global_glsl_state.exposure, - global_glsl_state.gamma, - global_glsl_state.input, - true); + /* Fill in OCIO's curve mapping settings. */ + if (use_curve_mapping) { + curve_mapping_to_ocio_settings(new_curve_mapping, &global_gpu_state.curve_mapping_settings); - global_glsl_state.processor_ui_to_display = create_display_encoded_buffer_processor( - global_glsl_state.display); + global_gpu_state.curve_mapping = new_curve_mapping; + global_gpu_state.curve_mapping_timestamp = view_settings->curve_mapping->changed_timestamp; + global_gpu_state.orig_curve_mapping = view_settings->curve_mapping; + global_gpu_state.use_curve_mapping = true; } + else { + global_gpu_state.orig_curve_mapping = NULL; + global_gpu_state.use_curve_mapping = false; + } + + return curve_mapping_settings; } bool IMB_colormanagement_support_glsl_draw(const ColorManagedViewSettings *UNUSED(view_settings)) { - return OCIO_supportGLSLDraw(); + return OCIO_supportGPUShader(); } /** @@ -4165,27 +4062,40 @@ bool IMB_colormanagement_setup_glsl_draw_from_space( applied_view_settings = &default_view_settings; } - /* Make sure OCIO processor is up-to-date. */ - update_glsl_display_processor(applied_view_settings, - display_settings, - from_colorspace ? from_colorspace->name : - global_role_scene_linear); + /* Ensure curve mapping is up to data. */ + OCIO_CurveMappingSettings *curve_mapping_settings = update_glsl_curve_mapping( + applied_view_settings); - if (global_glsl_state.processor_scene_to_ui == NULL) { - /* Happens when requesting non-existing color space or LUT in the - * configuration file does not exist. - */ - return false; - } + /* GPU shader parameters. */ + const char *input = from_colorspace ? from_colorspace->name : global_role_scene_linear; + const char *view = applied_view_settings->view_transform; + const char *display = display_settings->display_device; + const bool use_look = colormanage_use_look(applied_view_settings->look, + applied_view_settings->view_transform); + const char *look = (use_look) ? applied_view_settings->look : ""; + const float exposure = applied_view_settings->exposure; + const float gamma = applied_view_settings->gamma; + const float scale = (exposure == 0.0f) ? 1.0f : powf(2.0f, exposure); + const float exponent = (gamma == 1.0f) ? 1.0f : 1.0f / max_ff(FLT_EPSILON, gamma); + + OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig(); + + /* Bind shader. Internally GPU shaders are created and cached on demand. */ + global_gpu_state.gpu_shader_bound = OCIO_gpuDisplayShaderBind(config, + input, + view, + display, + look, + curve_mapping_settings, + scale, + exponent, + dither, + predivide, + do_overlay_merge); + + OCIO_configRelease(config); - return OCIO_setupGLSLDraw( - &global_glsl_state.ocio_glsl_state, - global_glsl_state.processor_scene_to_ui, - global_glsl_state.processor_ui_to_display, - global_glsl_state.use_curve_mapping ? &global_glsl_state.curve_mapping_settings : NULL, - dither, - predivide, - do_overlay_merge); + return global_gpu_state.gpu_shader_bound; } /* Configures GLSL shader for conversion from scene linear to display space */ @@ -4225,8 +4135,9 @@ bool IMB_colormanagement_setup_glsl_draw_ctx(const bContext *C, float dither, bo /* Finish GLSL-based display space conversion */ void IMB_colormanagement_finish_glsl_draw(void) { - if (global_glsl_state.ocio_glsl_state != NULL) { - OCIO_finishGLSLDraw(global_glsl_state.ocio_glsl_state); + if (global_gpu_state.gpu_shader_bound) { + OCIO_gpuDisplayShaderUnbind(); + global_gpu_state.gpu_shader_bound = false; } } |