diff --git a/include/OpenColorIO/OpenColorIO.h b/include/OpenColorIO/OpenColorIO.h index c5e499ff78..5ef81b8112 100644 --- a/include/OpenColorIO/OpenColorIO.h +++ b/include/OpenColorIO/OpenColorIO.h @@ -852,6 +852,10 @@ class OCIOEXPORT Config * \ref Config::validate will throw if the config does not contain * the matching display color space. */ + + /// Check if a view within a given display is referencing one of the config's shared views. + bool viewIsShared(const char * dispName, const char * viewName) const; + /// Will throw if view or colorSpaceName are null or empty. void addSharedView(const char * view, const char * viewTransformName, const char * colorSpaceName, const char * looks, @@ -859,6 +863,9 @@ class OCIOEXPORT Config /// Remove a shared view. Will throw if the view does not exist. void removeSharedView(const char * view); + /// Clear all shared views. This will throw if any displays are still using the shared views. + void clearSharedViews(); + const char * getDefaultDisplay() const; int getNumDisplays() const; /// Will return "" if the index is invalid. @@ -883,6 +890,23 @@ class OCIOEXPORT Config int getNumViews(const char * display, const char * colorspaceName) const; const char * getView(const char * display, const char * colorspaceName, int index) const; + /** + * \brief Compare views in a pair of configs. + * + * Will return false if either of the views does not exist. This will return true even + * if the view is display-defined in one config and a reference to a shared view in the + * other config (both within the same display), as long as the contents match. The + * description text (if any) is ignored, since it is not a functional difference. + * + * Note that the comparison is only on the strings contained in the view definition, + * the function does not attempt to compare that the color spaces or view transforms + * being referenced are identical (only that they have the same name). + */ + static bool ViewsAreEqual(const ConstConfigRcPtr & first, + const ConstConfigRcPtr & second, + const char * dispName, + const char * viewName); + /** * Returns the view_transform attribute of the (display, view) pair. View can * be a shared view of the display. If display is null or empty, config shared views are used. @@ -900,6 +924,17 @@ class OCIOEXPORT Config /// Returns the description attribute of a (display, view) pair. const char * getDisplayViewDescription(const char * display, const char * view) const noexcept; + /** + * \brief Determine if a display and view exist. + * + * This returns false if either the display or view doesn't exist. It works regardless + * of whether the display or view are active, and it works regardless of whether the + * view is display-defined or if the display has this as a shared view. It will only + * check config-level shared views if dispName is null. It will not check config level + * shared views if dispName is not null. + */ + bool displayHasView(const char * dispName, const char * viewName) const; + /** * For the (display, view) pair, specify which color space and look to use. * If a look is not desired, then just pass a null or empty string. @@ -963,6 +998,18 @@ class OCIOEXPORT Config * */ + /** + * \brief Determine if a virtual view exists. + * + * This returns false if the virtual view doesn't exist. It works regardless of + * whether the virtual view is active, and it works regardless of whether the virtual + * view is display-defined or if the display has this as a shared virtual view. + */ + bool hasVirtualView(const char * viewName) const; + + /// Check if a given virtual view is referencing one of the config's shared views. + bool virtualViewIsShared(const char * viewName) const; + void addVirtualDisplayView(const char * view, const char * viewTransformName, const char * colorSpaceName, @@ -977,6 +1024,23 @@ class OCIOEXPORT Config /// Get the view name at a specific index. const char * getVirtualDisplayView(ViewType type, int index) const noexcept; + /** + * \brief Compare virtual views in a pair of configs. + * + * Will return false if either of the virtual views does not exist. This will return true + * even if the virtual view is display-defined in one config and a reference to a shared + * virtual view in the other config, as long as the contents match. + * + * The description text (if any) is ignored, since it is not a functional difference. + * + * Note that the comparison is only on the strings contained in the view definition, + * the function does not attempt to compare that the color spaces or view transforms + * being referenced are identical (only that they have the same name). + */ + static bool VirtualViewsAreEqual(const ConstConfigRcPtr & first, + const ConstConfigRcPtr & second, + const char * viewName); + const char * getVirtualDisplayViewTransformName(const char * view) const noexcept; const char * getVirtualDisplayViewColorSpaceName(const char * view) const noexcept; const char * getVirtualDisplayViewLooks(const char * view) const noexcept; diff --git a/src/OpenColorIO/Config.cpp b/src/OpenColorIO/Config.cpp index a4cf7c5fe4..c44b2fdc34 100644 --- a/src/OpenColorIO/Config.cpp +++ b/src/OpenColorIO/Config.cpp @@ -3305,6 +3305,22 @@ void Config::setViewingRules(ConstViewingRulesRcPtr viewingRules) getImpl()->resetCacheIDs(); } +bool Config::viewIsShared(const char * dispName, const char * viewName) const +{ + if (!viewName || !*viewName) return false; + + for (int v = 0; v < getNumViews(VIEW_SHARED, dispName); v++) + { + const char * sharedViewName = getView(VIEW_SHARED, dispName, v); + if (sharedViewName && *sharedViewName && Platform::Strcasecmp(sharedViewName, viewName) == 0) + { + return true; + } + } + + return false; +} + void Config::addSharedView(const char * view, const char * viewTransform, const char * colorSpace, const char * looks, const char * rule, const char * description) @@ -3358,6 +3374,19 @@ void Config::removeSharedView(const char * view) } } +void Config::clearSharedViews() +{ + int numViews = getNumViews(VIEW_SHARED, nullptr); + for (int v = numViews - 1; v >= 0; v--) + { + const char * sharedViewName = getView(VIEW_SHARED, nullptr, v); + if (sharedViewName && *sharedViewName) + { + removeSharedView(sharedViewName); + } + } +} + const char * Config::getDefaultDisplay() const { return getDisplay(0); @@ -3487,6 +3516,43 @@ const char * Config::getView(const char * display, const char * colorspace, int return ""; } + +bool Config::ViewsAreEqual(const ConstConfigRcPtr & first, + const ConstConfigRcPtr & second, + const char * dispName, // may be empty or nullptr for shared views + const char * viewName) +{ + // It's ok to call this even for displays/views that don't exist, it will simply return false. + + // Note that this will return true even if the view is display-defined in one config and a reference + // to a shared view in the other config (both within the same display), as long as the contents match. + + // These calls return null if either the display or view doesn't exist (regardless if it's active). + const char * cs1 = first->getDisplayViewColorSpaceName(dispName, viewName); + const char * cs2 = second->getDisplayViewColorSpaceName(dispName, viewName); + + // If the color space is not null, the display and view exist. + if (cs1 && *cs1 && cs2 && *cs2) + { + // Both configs have a display and view by this name, now check the contents. + if (Platform::Strcasecmp(cs1, cs2) == 0) + { + // Note the remaining strings may be empty in a valid view. + // Intentionally not checking the description since it is not a functional difference. + if ( (Platform::Strcasecmp(first->getDisplayViewLooks(dispName, viewName), + second->getDisplayViewLooks(dispName, viewName)) == 0) && + (Platform::Strcasecmp(first->getDisplayViewTransformName(dispName, viewName), + second->getDisplayViewTransformName(dispName, viewName)) == 0) && + (Platform::Strcasecmp(first->getDisplayViewRule(dispName, viewName), + second->getDisplayViewRule(dispName, viewName)) == 0) ) + { + return true; + } + } + } + return false; +} + const char * Config::getDisplayViewTransformName(const char * display, const char * view) const { const View * viewPtr = getImpl()->getView(display, view); @@ -3525,6 +3591,21 @@ const char * Config::getDisplayViewDescription(const char * display, const char return viewPtr ? viewPtr->m_description.c_str() : ""; } +bool Config::displayHasView(const char * dispName, const char * viewName) const +{ + // This returns null if either the display or view doesn't exist. + // It works regardless of whether the display or view are active, + // and it works regardless of whether the view is display-defined + // or if the display has this as a shared view. + // + // It will only check config level shared views if dispName is null. + // It will not check config level shared views if dispName is not null. + const char * cs = getDisplayViewColorSpaceName(dispName, viewName); + + // All views must have a color space, so if it's not empty, the view exists. + return (cs && *cs); +} + void Config::addDisplaySharedView(const char * display, const char * sharedView) { if (!display || !*display) @@ -3695,6 +3776,30 @@ void Config::clearDisplays() getImpl()->resetCacheIDs(); } +bool Config::hasVirtualView(const char * viewName) const +{ + const char * cs = getVirtualDisplayViewColorSpaceName(viewName); + + // All views must have a color space, so if it's not empty, the view exists. + return (cs && *cs); +} + +bool Config::virtualViewIsShared(const char * viewName) const +{ + if (!viewName || !*viewName) return false; + + for (int v = 0; v < getVirtualDisplayNumViews(VIEW_SHARED); v++) + { + const char * sharedViewName = getVirtualDisplayView(VIEW_SHARED, v); + if (sharedViewName && *sharedViewName && Platform::Strcasecmp(sharedViewName, viewName) == 0) + { + return true; + } + } + + return false; +} + void Config::addVirtualDisplayView(const char * view, const char * viewTransform, const char * colorSpace, @@ -3795,10 +3900,44 @@ const char * Config::getVirtualDisplayView(ViewType type, int index) const noexc return ""; } +bool Config::VirtualViewsAreEqual(const ConstConfigRcPtr & first, + const ConstConfigRcPtr & second, + const char * viewName) +{ + const char * cs1 = first->getVirtualDisplayViewColorSpaceName(viewName); + const char * cs2 = second->getVirtualDisplayViewColorSpaceName(viewName); + + // If the color space is not null, the display and view exist. + if (cs1 && *cs1 && cs2 && *cs2) + { + if (Platform::Strcasecmp(cs1, cs2) == 0) + { + // Note the remaining strings may be empty in a valid view. + // Intentionally not checking the description since it is not a functional difference. + if ( (Platform::Strcasecmp(first->getVirtualDisplayViewLooks(viewName), + second->getVirtualDisplayViewLooks(viewName)) == 0) && + (Platform::Strcasecmp(first->getVirtualDisplayViewTransformName(viewName), + second->getVirtualDisplayViewTransformName(viewName)) == 0) && + (Platform::Strcasecmp(first->getVirtualDisplayViewRule(viewName), + second->getVirtualDisplayViewRule(viewName)) == 0) ) + { + return true; + } + } + } + return false; +} + const char * Config::getVirtualDisplayViewTransformName(const char * view) const noexcept { if (!view) return ""; + // Get the view transform name for the case where a virtual view is shared. + if (virtualViewIsShared(view)) + { + return getDisplayViewTransformName(nullptr, view); + } + ViewVec::const_iterator iter = FindView(getImpl()->m_virtualDisplay.m_views, view); if (iter != getImpl()->m_virtualDisplay.m_views.end()) { @@ -3812,6 +3951,12 @@ const char * Config::getVirtualDisplayViewColorSpaceName(const char * view) cons { if (!view) return ""; + // Get the colorspace name for the case where a virtual view is shared. + if (virtualViewIsShared(view)) + { + return getDisplayViewColorSpaceName(nullptr, view); + } + ViewVec::const_iterator iter = FindView(getImpl()->m_virtualDisplay.m_views, view); if (iter != getImpl()->m_virtualDisplay.m_views.end()) { @@ -3825,6 +3970,12 @@ const char * Config::getVirtualDisplayViewLooks(const char * view) const noexcep { if (!view) return ""; + // Get the view looks for the case where a virtual view is shared + if (virtualViewIsShared(view)) + { + return getDisplayViewLooks(nullptr, view); + } + ViewVec::const_iterator iter = FindView(getImpl()->m_virtualDisplay.m_views, view); if (iter != getImpl()->m_virtualDisplay.m_views.end()) { @@ -3838,6 +3989,12 @@ const char * Config::getVirtualDisplayViewRule(const char * view) const noexcept { if (!view) return ""; + // Get the view rule for the case where a virtual view is shared + if (virtualViewIsShared(view)) + { + return getDisplayViewRule(nullptr, view); + } + ViewVec::const_iterator iter = FindView(getImpl()->m_virtualDisplay.m_views, view); if (iter != getImpl()->m_virtualDisplay.m_views.end()) { @@ -3851,6 +4008,12 @@ const char * Config::getVirtualDisplayViewDescription(const char * view) const n { if (!view) return ""; + // Get the view description for the case where a virtual view is shared + if (virtualViewIsShared(view)) + { + return getDisplayViewDescription(nullptr, view); + } + ViewVec::const_iterator iter = FindView(getImpl()->m_virtualDisplay.m_views, view); if (iter != getImpl()->m_virtualDisplay.m_views.end()) { diff --git a/src/bindings/python/PyConfig.cpp b/src/bindings/python/PyConfig.cpp index 9534ddc358..1d24cd9dc7 100644 --- a/src/bindings/python/PyConfig.cpp +++ b/src/bindings/python/PyConfig.cpp @@ -404,6 +404,8 @@ void bindPyConfig(py::module & m) DOC(Config, addSharedView)) .def("removeSharedView", &Config::removeSharedView, "view"_a, DOC(Config, removeSharedView)) + .def("clearSharedViews", &Config::clearSharedViews, + DOC(Config, clearSharedViews)) .def("getSharedViews", [](ConfigRcPtr & self) { return SharedViewIterator(self); @@ -456,6 +458,9 @@ void bindPyConfig(py::module & m) .def("getDisplayViewDescription", &Config::getDisplayViewDescription, "display"_a, "view"_a, DOC(Config, getDisplayViewDescription)) + .def("displayHasView", &Config::displayHasView, + "display"_a, "view"_a, + DOC(Config, displayHasView)) .def("addDisplayView", (void (Config::*)(const char *, const char *, const char *, const char *)) &Config::addDisplayView, @@ -475,20 +480,35 @@ void bindPyConfig(py::module & m) "ruleName"_a = "", "description"_a = "", DOC(Config, addDisplayView)) + .def("viewIsShared", &Config::viewIsShared, "display"_a, "view"_a, + DOC(Config, viewIsShared)) .def("addDisplaySharedView", &Config::addDisplaySharedView, "display"_a, "view"_a, DOC(Config, addDisplaySharedView)) .def("removeDisplayView", &Config::removeDisplayView, "display"_a, "view"_a, DOC(Config, removeDisplayView)) .def("clearDisplays", &Config::clearDisplays, DOC(Config, clearDisplays)) + .def_static("ViewsAreEqual", [](const ConstConfigRcPtr & first, + const ConstConfigRcPtr & second, + const char * dispName, + const char * viewName) + { + return Config::ViewsAreEqual(first, second, dispName, viewName); + }, + "first"_a, "second"_a, "dispName"_a, "viewName"_a, + DOC(Config, ViewsAreEqual)) // Virtual Display + .def("hasVirtualView", &Config::hasVirtualView, "view"_a, + DOC(Config, hasVirtualView)) .def("addVirtualDisplayView", &Config::addVirtualDisplayView, "view"_a, "viewTransformName"_a, "colorSpaceName"_a, "looks"_a = "", "ruleName"_a = "", "description"_a = "", DOC(Config, addVirtualDisplayView)) + .def("virtualViewIsShared", &Config::virtualViewIsShared, "view"_a, + DOC(Config, virtualViewIsShared)) .def("addVirtualDisplaySharedView", &Config::addVirtualDisplaySharedView, "sharedView"_a, DOC(Config, addVirtualDisplaySharedView)) .def("getVirtualDisplayViews", [](ConfigRcPtr & self, ViewType type) @@ -532,6 +552,14 @@ void bindPyConfig(py::module & m) return false; }, "display"_a) + .def_static("VirtualViewsAreEqual", [](const ConstConfigRcPtr & first, + const ConstConfigRcPtr & second, + const char * viewName) + { + return Config::VirtualViewsAreEqual(first, second, viewName); + }, + "first"_a, "second"_a, "viewName"_a, + DOC(Config, VirtualViewsAreEqual)) // Active Displays and Views .def("setActiveDisplays", &Config::setActiveDisplays, "displays"_a, diff --git a/tests/cpu/Config_tests.cpp b/tests/cpu/Config_tests.cpp index 518b97275b..45145f9de0 100644 --- a/tests/cpu/Config_tests.cpp +++ b/tests/cpu/Config_tests.cpp @@ -6902,17 +6902,28 @@ OCIO_ADD_TEST(Config, display_view) // Add a simple view. const std::string display{ "display" }; + + OCIO_CHECK_ASSERT(!config->displayHasView(display.c_str(), "view1")); + OCIO_CHECK_NO_THROW(config->addDisplayView(display.c_str(), "view1", "scs", "")); + OCIO_CHECK_ASSERT(config->displayHasView(display.c_str(), "view1")); + OCIO_CHECK_NO_THROW(config->validate()); + OCIO_CHECK_ASSERT(!config->displayHasView(display.c_str(), "view2")); + OCIO_CHECK_NO_THROW(config->addDisplayView(display.c_str(), "view2", "view_transform", "scs", "", "", "")); OCIO_CHECK_THROW_WHAT(config->validate(), OCIO::Exception, "color space, 'scs', that is not a display-referred"); + OCIO_CHECK_ASSERT(config->displayHasView(display.c_str(), "view2")); + OCIO_CHECK_NO_THROW(config->addDisplayView(display.c_str(), "view2", "view_transform", "dcs", "", "", "")); + OCIO_CHECK_ASSERT(config->displayHasView(display.c_str(), "view2")); + OCIO_CHECK_NO_THROW(config->validate()); // Validate how the config is serialized. @@ -7339,6 +7350,7 @@ OCIO_ADD_TEST(Config, add_remove_display) // Add a (display, view) pair. OCIO_CHECK_NO_THROW(config->addDisplayView("disp1", "view1", "raw", nullptr)); + OCIO_CHECK_ASSERT(config->displayHasView("disp1", "view1")); OCIO_REQUIRE_EQUAL(config->getNumDisplays(), 2); OCIO_CHECK_EQUAL(std::string(config->getDisplay(0)), std::string("sRGB")); OCIO_CHECK_EQUAL(std::string(config->getDisplay(1)), std::string("disp1")); @@ -7347,6 +7359,7 @@ OCIO_ADD_TEST(Config, add_remove_display) // Remove a (display, view) pair. OCIO_CHECK_NO_THROW(config->removeDisplayView("disp1", "view1")); + OCIO_CHECK_ASSERT(!config->displayHasView("disp1", "view1")); OCIO_REQUIRE_EQUAL(config->getNumDisplays(), 1); OCIO_CHECK_EQUAL(std::string(config->getDisplay(0)), std::string("sRGB")); } @@ -8489,15 +8502,30 @@ active_views: [] OCIO_CHECK_EQUAL(2, config->getNumViews(OCIO::VIEW_DISPLAY_DEFINED, "sRGB")); OCIO_CHECK_EQUAL(1, config->getNumViews(OCIO::VIEW_SHARED, "sRGB")); + OCIO_CHECK_EQUAL(std::string("sview1"), config->getView(OCIO::VIEW_SHARED, "sRGB", 0)); + OCIO_CHECK_ASSERT(config->displayHasView("sRGB", "sview1")); + OCIO_CHECK_ASSERT(config->viewIsShared("sRGB", "sview1")); + OCIO_CHECK_ASSERT(!config->viewIsShared("sRGB", "")); + OCIO_CHECK_ASSERT(!config->viewIsShared("sRGB", nullptr)); + + OCIO_CHECK_EQUAL(std::string("raw"), config->getDisplayViewColorSpaceName("sRGB", "sview1")); + OCIO_CHECK_EQUAL(std::string("raw"), config->getVirtualDisplayViewColorSpaceName("sview2")); + // Step 3 - Validate the virtual display information. { OCIO::ConfigRcPtr cfg = config->createEditableCopy(); + OCIO_CHECK_ASSERT(OCIO::Config::ViewsAreEqual(config, cfg, "sRGB", "sview1")); + OCIO_CHECK_ASSERT(OCIO::Config::ViewsAreEqual(config, cfg, "sRGB", "Raw")); + OCIO_CHECK_ASSERT(OCIO::Config::ViewsAreEqual(config, cfg, "sRGB", "view")); + OCIO_REQUIRE_EQUAL(2, cfg->getVirtualDisplayNumViews(OCIO::VIEW_DISPLAY_DEFINED)); const char * viewName = cfg->getVirtualDisplayView(OCIO::VIEW_DISPLAY_DEFINED, 0); + OCIO_CHECK_ASSERT(cfg->hasVirtualView(viewName)); + OCIO_CHECK_EQUAL(std::string("Raw"), viewName); OCIO_CHECK_EQUAL(std::string(""), cfg->getVirtualDisplayViewTransformName(viewName)); OCIO_CHECK_EQUAL(std::string("raw"), cfg->getVirtualDisplayViewColorSpaceName(viewName)); @@ -8505,9 +8533,11 @@ active_views: [] OCIO_CHECK_EQUAL(std::string(""), cfg->getVirtualDisplayViewRule(viewName)); OCIO_CHECK_EQUAL(std::string(""), cfg->getVirtualDisplayViewDescription(viewName)); + OCIO_CHECK_ASSERT(OCIO::Config::VirtualViewsAreEqual(config, cfg, viewName)); + viewName = cfg->getVirtualDisplayView(OCIO::VIEW_DISPLAY_DEFINED, 1); - OCIO_CHECK_EQUAL(std::string("Film"), cfg->getVirtualDisplayView(OCIO::VIEW_DISPLAY_DEFINED, 1)); + OCIO_CHECK_EQUAL(std::string("Film"), viewName); OCIO_CHECK_EQUAL(std::string("display_vt"), cfg->getVirtualDisplayViewTransformName(viewName)); OCIO_CHECK_EQUAL(std::string(""), cfg->getVirtualDisplayViewColorSpaceName(viewName)); OCIO_CHECK_EQUAL(std::string(""), cfg->getVirtualDisplayViewLooks(viewName)); @@ -8516,11 +8546,22 @@ active_views: [] OCIO_REQUIRE_EQUAL(1, cfg->getVirtualDisplayNumViews(OCIO::VIEW_SHARED)); OCIO_CHECK_EQUAL(std::string("sview2"), cfg->getVirtualDisplayView(OCIO::VIEW_SHARED, 0)); + OCIO_CHECK_EQUAL(std::string("raw"), cfg->getVirtualDisplayViewColorSpaceName("sview2")); + + OCIO_CHECK_ASSERT(cfg->hasVirtualView("sview2")); + OCIO_CHECK_ASSERT(cfg->virtualViewIsShared("sview2")); + OCIO_CHECK_ASSERT(OCIO::Config::VirtualViewsAreEqual(config, cfg, "sview2")); + + OCIO_CHECK_ASSERT(!cfg->virtualViewIsShared("")); + OCIO_CHECK_ASSERT(!cfg->virtualViewIsShared(nullptr)); // Remove a view from the Virtual Display. cfg->removeVirtualDisplayView("Raw"); + OCIO_CHECK_ASSERT(!OCIO::Config::VirtualViewsAreEqual(config, cfg, "Raw")); + OCIO_CHECK_ASSERT(!cfg->hasVirtualView("Raw")); + OCIO_REQUIRE_EQUAL(1, cfg->getVirtualDisplayNumViews(OCIO::VIEW_DISPLAY_DEFINED)); OCIO_CHECK_EQUAL(std::string("Film"), cfg->getVirtualDisplayView(OCIO::VIEW_DISPLAY_DEFINED, 0)); @@ -8532,6 +8573,9 @@ active_views: [] cfg->removeVirtualDisplayView("sview2"); OCIO_REQUIRE_EQUAL(1, cfg->getVirtualDisplayNumViews(OCIO::VIEW_DISPLAY_DEFINED)); OCIO_REQUIRE_EQUAL(0, cfg->getVirtualDisplayNumViews(OCIO::VIEW_SHARED)); + OCIO_CHECK_ASSERT(!cfg->hasVirtualView("sview2")); + OCIO_CHECK_ASSERT(!cfg->virtualViewIsShared("sview2")); + OCIO_CHECK_ASSERT(!OCIO::Config::VirtualViewsAreEqual(config, cfg, "sview2")); { // Extra serialize & deserialize validation. @@ -8552,12 +8596,14 @@ active_views: [] cfg->addVirtualDisplaySharedView("sview2"); OCIO_REQUIRE_EQUAL(1, cfg->getVirtualDisplayNumViews(OCIO::VIEW_DISPLAY_DEFINED)); OCIO_REQUIRE_EQUAL(1, cfg->getVirtualDisplayNumViews(OCIO::VIEW_SHARED)); + OCIO_CHECK_ASSERT(cfg->virtualViewIsShared("sview2")); // Remove the Virtual Display. cfg->clearVirtualDisplay(); OCIO_REQUIRE_EQUAL(0, cfg->getVirtualDisplayNumViews(OCIO::VIEW_DISPLAY_DEFINED)); OCIO_REQUIRE_EQUAL(0, cfg->getVirtualDisplayNumViews(OCIO::VIEW_SHARED)); + OCIO_CHECK_ASSERT(!cfg->virtualViewIsShared("sview2")); { // Extra serialize & deserialize validation. diff --git a/tests/cpu/Display_tests.cpp b/tests/cpu/Display_tests.cpp index c9562aa0a2..03ef992ba8 100644 --- a/tests/cpu/Display_tests.cpp +++ b/tests/cpu/Display_tests.cpp @@ -232,4 +232,532 @@ OCIO_ADD_TEST(SharedViews, basic) OCIO_CHECK_EQUAL(std::string(OCIO::OCIO_VIEW_USE_DISPLAY_NAME), configBack->getDisplayViewColorSpaceName(nullptr, "shared3")); + + // Remove all shared views + OCIO_REQUIRE_EQUAL(4, config->getNumViews(OCIO::VIEW_SHARED, nullptr)); + OCIO_CHECK_NO_THROW(config->clearSharedViews()); + OCIO_REQUIRE_EQUAL(0, config->getNumViews(OCIO::VIEW_SHARED, nullptr)); +} + +OCIO_ADD_TEST(Config, compare_displays) { + static constexpr char CONFIG1[]{ R"(ocio_profile_version: 2 + +roles: + default: raw + +file_rules: + - ! {name: Default, colorspace: default} + +shared_views: + - ! {name: sview1, colorspace: raw} + +displays: + Raw: + - ! {name: Raw, colorspace: raw} + sRGB: + - ! {name: Raw, colorspace: raw} + - ! {name: view, view_transform: display_vt, display_colorspace: display_cs} + - ! [sview1] + +active_displays: [sRGB] +active_views: [view, sview1] + +view_transforms: + - ! + name: default_vt + to_scene_reference: ! {sat: 1.5} + + - ! + name: display_vt + to_display_reference: ! {sat: 1.5} + +display_colorspaces: + - ! + name: display_cs + to_display_reference: ! {sat: 1.5} + +colorspaces: + - ! + name: raw +)" }; + + static constexpr char CONFIG2[]{ R"(ocio_profile_version: 2 + +roles: + default: raw + +file_rules: + - ! {name: Default, colorspace: default} + +shared_views: + - ! {name: view, view_transform: display_vt, display_colorspace: display_cs} + - ! {name: sview1, colorspace: raw} + +displays: + Raw: + - ! {name: Raw, colorspace: raw} + sRGB: + - ! {name: Raw, colorspace: raw} + - ! [view, sview1] + +active_displays: [Raw] +active_views: [Raw] + +view_transforms: + - ! + name: default_vt + to_scene_reference: ! {sat: 1.5} + + - ! + name: display_vt + to_display_reference: ! {sat: 1.5} + +display_colorspaces: + - ! + name: display_cs + to_display_reference: ! {sat: 1.5} + +colorspaces: + - ! + name: raw +)" }; + + std::istringstream is; + is.str(CONFIG1); + OCIO::ConstConfigRcPtr config1, config2; + OCIO_CHECK_NO_THROW(config1 = OCIO::Config::CreateFromStream(is)); + is.clear(); + is.str(CONFIG2); + OCIO_CHECK_NO_THROW(config2 = OCIO::Config::CreateFromStream(is)); + OCIO_CHECK_NO_THROW(config1->validate()); + OCIO_CHECK_NO_THROW(config2->validate()); + + { + // Test that Config::ViewsAreEqual works for a matching (display, view) pair across separate configs. + // Works regardless of if the view is display-defined in one config and shared in the other. + // Works regardless of if the (display, view) pair is active in one config and inactive in another. + + // Active (display, view) pair where the view is display-defined. + OCIO_REQUIRE_EQUAL(1, config1->getNumDisplays()); + OCIO_REQUIRE_EQUAL(std::string("sRGB"), config1->getDefaultDisplay()); + + OCIO_CHECK_EQUAL(2, config1->getNumViews(OCIO::VIEW_DISPLAY_DEFINED, "sRGB")); + OCIO_CHECK_EQUAL(std::string("Raw"), config1->getView(OCIO::VIEW_DISPLAY_DEFINED, "sRGB", 0)); + OCIO_CHECK_EQUAL(std::string("view"), config1->getView(OCIO::VIEW_DISPLAY_DEFINED, "sRGB", 1)); + + OCIO_CHECK_ASSERT(!config1->viewIsShared("sRGB", "view")); + + OCIO_CHECK_EQUAL(2, config1->getNumViews("sRGB")); + OCIO_CHECK_EQUAL(std::string("view"), config1->getView("sRGB", 0)); + + // Inactive (display, view) pair where the view is a reference to a shared view. + OCIO_REQUIRE_EQUAL(1, config2->getNumDisplays()); + OCIO_CHECK_EQUAL(std::string("Raw"), config2->getDefaultDisplay()); + OCIO_CHECK_EQUAL(1, config2->getNumViews("Raw")); + OCIO_CHECK_EQUAL(std::string("Raw"), config2->getDefaultView("Raw")); + + OCIO_REQUIRE_EQUAL(config2->getNumDisplaysAll(), 2); + OCIO_CHECK_EQUAL(config2->getDisplayAll(1), std::string("sRGB")); + + OCIO_CHECK_EQUAL(2, config2->getNumViews(OCIO::VIEW_SHARED, "sRGB")); + OCIO_CHECK_EQUAL(std::string("view"), config2->getView(OCIO::VIEW_SHARED, "sRGB", 0)); + OCIO_CHECK_EQUAL(std::string("sview1"), config2->getView(OCIO::VIEW_SHARED, "sRGB", 1)); + + OCIO_CHECK_ASSERT(config2->viewIsShared("sRGB", "view")); + + OCIO_CHECK_ASSERT(OCIO::Config::ViewsAreEqual(config1, config2, "sRGB", "view")); + + } + + { + // Test that Config::ViewsAreEqual works for a matching (display, view) pair across separate configs, + // even if the pair is active in one config and inactive in another. Both views are display-defined. + + // Inactive (display, view) pair where the view is display-defined. + OCIO_REQUIRE_EQUAL(1, config1->getNumDisplays()); + OCIO_CHECK_EQUAL(std::string("sRGB"), config1->getDefaultDisplay()); + OCIO_CHECK_EQUAL(config1->getDisplayAll(0), std::string("Raw")); + OCIO_CHECK_EQUAL(1, config1->getNumViews(OCIO::VIEW_DISPLAY_DEFINED, "Raw")); + OCIO_CHECK_EQUAL(std::string("Raw"), config1->getView(OCIO::VIEW_DISPLAY_DEFINED, "Raw", 0)); + OCIO_CHECK_ASSERT(!config1->viewIsShared("Raw", "Raw")); + + // Active (display, view) pair where the view is display-defined. + OCIO_REQUIRE_EQUAL(1, config2->getNumDisplays()); + OCIO_CHECK_EQUAL(std::string("Raw"), config2->getDefaultDisplay()); + OCIO_CHECK_EQUAL(1, config2->getNumViews(OCIO::VIEW_DISPLAY_DEFINED, "Raw")); + OCIO_CHECK_EQUAL(std::string("Raw"), config2->getView(OCIO::VIEW_DISPLAY_DEFINED, "Raw", 0)); + OCIO_CHECK_ASSERT(!config2->viewIsShared("Raw", "Raw")); + + OCIO_CHECK_ASSERT(OCIO::Config::ViewsAreEqual(config1, config2, "Raw", "Raw")); + } + + { + // Test that Config::ViewsAreEqual works for a matching (display, view) pair across separate configs, even + // if the pair is active in one config and inactive in another. Both views are reference to a shared view. + + // Active (display, view) pair where the view is a reference to a shared view. + OCIO_CHECK_EQUAL(1, config1->getNumViews(OCIO::VIEW_SHARED, "sRGB")); + OCIO_CHECK_EQUAL(std::string("sview1"), config1->getView(OCIO::VIEW_SHARED, "sRGB", 0)); + OCIO_CHECK_ASSERT(config1->viewIsShared("sRGB", "sview1")); + + // Inactive (display, view) pair where the view is a reference to a shared view. + OCIO_CHECK_EQUAL(2, config2->getNumViews(OCIO::VIEW_SHARED, "sRGB")); + OCIO_CHECK_EQUAL(std::string("view"), config2->getView(OCIO::VIEW_SHARED, "sRGB", 0)); + OCIO_CHECK_EQUAL(std::string("sview1"), config2->getView(OCIO::VIEW_SHARED, "sRGB", 1)); + OCIO_CHECK_ASSERT(config2->viewIsShared("sRGB", "sview1")); + + OCIO_CHECK_ASSERT(OCIO::Config::ViewsAreEqual(config1, config2, "sRGB", "sview1")); + } + + { + // Check that displayHasView method works if (display, view) pair exists regardless of whether the display or view + // are active and regardless of whether the view is display-defined or if the view is a reference to a shared view. + + OCIO::ConfigRcPtr cfg1 = config1->createEditableCopy(); + OCIO_CHECK_ASSERT(cfg1->displayHasView("sRGB", "Raw" )); // Active display has inactive view (display-defined). + OCIO_CHECK_ASSERT(cfg1->displayHasView("sRGB", "view" )); // Active display has active view (display-defined). + OCIO_CHECK_ASSERT(cfg1->displayHasView("sRGB", "sview1")); // Active display has active view (shared). + OCIO_CHECK_ASSERT(cfg1->displayHasView("Raw" , "Raw" )); // Inactive display has inactive view (display-defined). + + OCIO_CHECK_NO_THROW(cfg1->setActiveDisplays("Raw")); + OCIO_CHECK_EQUAL(1, cfg1->getNumDisplays()); + OCIO_CHECK_EQUAL(std::string("Raw"), cfg1->getDefaultDisplay()); + + OCIO_CHECK_ASSERT(cfg1->displayHasView("sRGB", "sview1")); // Inactive display has active view (shared). + + OCIO_CHECK_NO_THROW(cfg1->setActiveViews("Raw")); + OCIO_REQUIRE_EQUAL(cfg1->getNumViews("sRGB"), 1); + OCIO_CHECK_EQUAL(cfg1->getView("sRGB", 0), std::string("Raw")); + + OCIO_CHECK_ASSERT(cfg1->displayHasView("sRGB" , "Raw" )); // Inactive display has active view (display-defined). + OCIO_CHECK_ASSERT(cfg1->displayHasView("sRGB", "sview1")); // Inactive display has inactive view (shared). + + OCIO_CHECK_NO_THROW(cfg1->setActiveDisplays("sRGB")); + OCIO_CHECK_EQUAL(1, cfg1->getNumDisplays()); + OCIO_CHECK_EQUAL(std::string("sRGB"), cfg1->getDefaultDisplay()); + + OCIO_CHECK_ASSERT(cfg1->displayHasView("sRGB", "sview1")); // Active display has inactive view (shared). + } + + { + // Test when a display exists, but a view doesn't exist. + + OCIO::ConfigRcPtr cfg1 = config1->createEditableCopy(); + + OCIO_CHECK_EQUAL(std::string("sRGB"), cfg1->getDefaultDisplay()); + OCIO_CHECK_EQUAL(2, cfg1->getNumViews(OCIO::VIEW_DISPLAY_DEFINED, "sRGB")); + OCIO_CHECK_EQUAL(std::string("Raw"), cfg1->getView(OCIO::VIEW_DISPLAY_DEFINED, "sRGB", 0)); + OCIO_CHECK_EQUAL(std::string("view"), cfg1->getView(OCIO::VIEW_DISPLAY_DEFINED, "sRGB", 1)); + + OCIO_CHECK_ASSERT(cfg1->displayHasView("sRGB", "Raw")); + OCIO_CHECK_ASSERT(OCIO::Config::ViewsAreEqual(config1, cfg1, "sRGB", "Raw")); + + // Remove the view from the display. + OCIO_CHECK_NO_THROW(cfg1->removeDisplayView("sRGB", "Raw")); + OCIO_CHECK_EQUAL(1, cfg1->getNumViews(OCIO::VIEW_DISPLAY_DEFINED, "sRGB")); + OCIO_CHECK_EQUAL(std::string("view"), cfg1->getView(OCIO::VIEW_DISPLAY_DEFINED, "sRGB", 0)); + + OCIO_CHECK_ASSERT(!cfg1->displayHasView("sRGB", "Raw")); + OCIO_CHECK_ASSERT(!OCIO::Config::ViewsAreEqual(config1, cfg1, "sRGB", "Raw")); + } + + { + // Test when a view exists, but a display doesn't exist. + + OCIO::ConfigRcPtr cfg2 = config2->createEditableCopy(); + + OCIO_CHECK_EQUAL(std::string("Raw"), cfg2->getDefaultDisplay()); + OCIO_REQUIRE_EQUAL(1, cfg2->getNumViews("Raw")); + OCIO_REQUIRE_EQUAL(std::string("Raw"), cfg2->getView("Raw", 0)); + OCIO_CHECK_EQUAL(std::string("Raw"), cfg2->getActiveViews()); + + OCIO_CHECK_ASSERT(cfg2->displayHasView("Raw", "Raw")); + OCIO_CHECK_ASSERT(OCIO::Config::ViewsAreEqual(config2, cfg2, "Raw", "Raw")); + + // Remove the view from the display and the display itself since it only has no more views. + OCIO_REQUIRE_EQUAL(2, cfg2->getNumDisplaysAll()); + OCIO_CHECK_NO_THROW(cfg2->removeDisplayView("Raw", "Raw")); + OCIO_REQUIRE_EQUAL(1, cfg2->getNumDisplaysAll()); + + // The view is still active. + OCIO_REQUIRE_EQUAL(std::string("Raw"), cfg2->getActiveViews()); + + OCIO_CHECK_ASSERT(!cfg2->displayHasView("Raw", "Raw")); + OCIO_CHECK_ASSERT(!OCIO::Config::ViewsAreEqual(config2, cfg2, "Raw", "Raw")); + } + + { + // Test access of config-level shared views for displayHasView method. + + OCIO::ConfigRcPtr cfg1 = config1->createEditableCopy(); + + OCIO_CHECK_EQUAL(1, cfg1->getNumViews(OCIO::VIEW_SHARED, "sRGB")); + OCIO_CHECK_EQUAL(std::string("sview1"), cfg1->getView(OCIO::VIEW_SHARED, "sRGB", 0)); + OCIO_CHECK_ASSERT(cfg1->viewIsShared("sRGB", "sview1")); + + OCIO_CHECK_ASSERT(cfg1->displayHasView("sRGB", "sview1")); + + // Remove the shared view from the display. + OCIO_CHECK_NO_THROW(cfg1->removeDisplayView("sRGB", "sview1")); + OCIO_REQUIRE_EQUAL(std::string("sRGB"), config1->getDefaultDisplay()); + OCIO_CHECK_EQUAL(0, cfg1->getNumViews(OCIO::VIEW_SHARED, "sRGB")); + + // Shared view still exists in the config. + OCIO_CHECK_EQUAL(1, cfg1->getNumViews(OCIO::VIEW_SHARED, nullptr)); + OCIO_CHECK_EQUAL(std::string("sview1"), cfg1->getView(OCIO::VIEW_SHARED, nullptr, 0)); + OCIO_CHECK_ASSERT(cfg1->viewIsShared(nullptr, "sview1")); + + OCIO_CHECK_ASSERT(!cfg1->displayHasView("sRGB", "sview1")); + + // When display name is null, displayHasView will only check config level shared views. + OCIO_CHECK_ASSERT(cfg1->displayHasView(nullptr, "sview1")); + } +} + +OCIO_ADD_TEST(Config, compare_virtual_displays) { + static constexpr char CONFIG1[]{ R"(ocio_profile_version: 2 + +roles: + default: raw + +file_rules: + - ! {name: Default, colorspace: default} + +viewing_rules: + - ! {name: Linear, colorspaces: default} + +shared_views: + - ! {name: Film, view_transform: display_vt, display_colorspace: , looks: look1, rule: Linear, description: Test view} + - ! {name: view, view_transform: display_vt, display_colorspace: display_cs} + +displays: + Raw: + - ! {name: Raw, colorspace: raw} + sRGB: + - ! {name: Raw, colorspace: raw} + +virtual_display: + - ! {name: Raw, colorspace: raw} + - ! [Film, view] + +looks: + - ! + name: look1 + process_space: default + +view_transforms: + - ! + name: default_vt + to_scene_reference: ! {sat: 1.5} + + - ! + name: display_vt + to_display_reference: ! {sat: 1.5} + +display_colorspaces: + - ! + name: display_cs + to_display_reference: ! {sat: 1.5} + +colorspaces: + - ! + name: raw +)" }; + + static constexpr char CONFIG2[]{ R"(ocio_profile_version: 2 + +roles: + default: raw + +file_rules: + - ! {name: Default, colorspace: default} + +viewing_rules: + - ! {name: Linear, colorspaces: default} + +shared_views: + - ! {name: view, view_transform: display_vt, display_colorspace: display_cs} + +displays: + Raw: + - ! {name: Raw, colorspace: raw} + sRGB: + - ! {name: Raw, colorspace: raw} + - ! [view] + +virtual_display: + - ! {name: Raw, colorspace: raw} + - ! {name: Film, view_transform: display_vt, display_colorspace: , looks: look1, rule: Linear, description: Test view} + - ! [view] + +looks: + - ! + name: look1 + process_space: default + +view_transforms: + - ! + name: default_vt + to_scene_reference: ! {sat: 1.5} + + - ! + name: display_vt + to_display_reference: ! {sat: 1.5} + +display_colorspaces: + - ! + name: display_cs + to_display_reference: ! {sat: 1.5} + +colorspaces: + - ! + name: raw +)" }; + + std::istringstream is; + is.str(CONFIG1); + OCIO::ConstConfigRcPtr config1, config2; + OCIO_CHECK_NO_THROW(config1 = OCIO::Config::CreateFromStream(is)); + is.clear(); + is.str(CONFIG2); + OCIO_CHECK_NO_THROW(config2 = OCIO::Config::CreateFromStream(is)); + OCIO_CHECK_NO_THROW(config1->validate()); + OCIO_CHECK_NO_THROW(config2->validate()); + + { + // Test that Config::VirtualViewsAreEqual works for a matching virtual view pair across separate configs. + // Works regardless of if the virtual view is display-defined in one config and shared in the other. + + // Virtual view is a reference to a shared view. + OCIO_REQUIRE_EQUAL(2, config1->getVirtualDisplayNumViews(OCIO::VIEW_SHARED)); + + const char * viewName1 = config1->getVirtualDisplayView(OCIO::VIEW_SHARED, 0); + + OCIO_CHECK_EQUAL(std::string("Film"), viewName1); + OCIO_CHECK_EQUAL(std::string("display_vt"), config1->getVirtualDisplayViewTransformName(viewName1)); + OCIO_CHECK_EQUAL(std::string(""), config1->getVirtualDisplayViewColorSpaceName(viewName1)); + OCIO_CHECK_EQUAL(std::string("look1"), config1->getVirtualDisplayViewLooks(viewName1)); + OCIO_CHECK_EQUAL(std::string("Linear"), config1->getVirtualDisplayViewRule(viewName1)); + OCIO_CHECK_EQUAL(std::string("Test view"), config1->getVirtualDisplayViewDescription(viewName1)); + + // Virtual view is a reference to a display-defined view. + OCIO_REQUIRE_EQUAL(2, config2->getVirtualDisplayNumViews(OCIO::VIEW_DISPLAY_DEFINED)); + + const char * viewName2 = config2->getVirtualDisplayView(OCIO::VIEW_DISPLAY_DEFINED, 1); + + OCIO_CHECK_EQUAL(std::string("Film"), viewName2); + OCIO_CHECK_EQUAL(std::string("display_vt"), config2->getVirtualDisplayViewTransformName(viewName2)); + OCIO_CHECK_EQUAL(std::string(""), config2->getVirtualDisplayViewColorSpaceName(viewName2)); + OCIO_CHECK_EQUAL(std::string("look1"), config2->getVirtualDisplayViewLooks(viewName2)); + OCIO_CHECK_EQUAL(std::string("Linear"), config2->getVirtualDisplayViewRule(viewName2)); + OCIO_CHECK_EQUAL(std::string("Test view"), config2->getVirtualDisplayViewDescription(viewName2)); + + OCIO_CHECK_EQUAL(std::string(viewName1), std::string(viewName2)); + OCIO_CHECK_ASSERT(OCIO::Config::VirtualViewsAreEqual(config1, config2, viewName1)); + } + { + // Virtual views are both display-defined. + OCIO_REQUIRE_EQUAL(1, config1->getVirtualDisplayNumViews(OCIO::VIEW_DISPLAY_DEFINED)); + + const char * viewName1 = config1->getVirtualDisplayView(OCIO::VIEW_DISPLAY_DEFINED, 0); + + OCIO_CHECK_EQUAL(std::string("Raw"), viewName1); + OCIO_CHECK_EQUAL(std::string(""), config1->getVirtualDisplayViewTransformName(viewName1)); + OCIO_CHECK_EQUAL(std::string("raw"), config1->getVirtualDisplayViewColorSpaceName(viewName1)); + OCIO_CHECK_EQUAL(std::string(""), config1->getVirtualDisplayViewLooks(viewName1)); + OCIO_CHECK_EQUAL(std::string(""), config1->getVirtualDisplayViewRule(viewName1)); + OCIO_CHECK_EQUAL(std::string(""), config1->getVirtualDisplayViewDescription(viewName1)); + + const char * viewName2 = config2->getVirtualDisplayView(OCIO::VIEW_DISPLAY_DEFINED, 0); + + OCIO_CHECK_EQUAL(std::string("Raw"), viewName2); + OCIO_CHECK_EQUAL(std::string(""), config2->getVirtualDisplayViewTransformName(viewName2)); + OCIO_CHECK_EQUAL(std::string("raw"), config2->getVirtualDisplayViewColorSpaceName(viewName2)); + OCIO_CHECK_EQUAL(std::string(""), config2->getVirtualDisplayViewLooks(viewName2)); + OCIO_CHECK_EQUAL(std::string(""), config2->getVirtualDisplayViewRule(viewName2)); + OCIO_CHECK_EQUAL(std::string(""), config2->getVirtualDisplayViewDescription(viewName2)); + + OCIO_CHECK_EQUAL(std::string(viewName1), std::string(viewName2)); + OCIO_CHECK_ASSERT(OCIO::Config::VirtualViewsAreEqual(config1, config2, viewName1)); + } + { + // Virtual views are both shared. + const char * viewName1 = config1->getVirtualDisplayView(OCIO::VIEW_SHARED, 1); + + OCIO_CHECK_EQUAL(std::string("view"), viewName1); + OCIO_CHECK_EQUAL(std::string("display_vt"), config1->getVirtualDisplayViewTransformName(viewName1)); + OCIO_CHECK_EQUAL(std::string("display_cs"), config1->getVirtualDisplayViewColorSpaceName(viewName1)); + OCIO_CHECK_EQUAL(std::string(""), config1->getVirtualDisplayViewLooks(viewName1)); + OCIO_CHECK_EQUAL(std::string(""), config1->getVirtualDisplayViewRule(viewName1)); + OCIO_CHECK_EQUAL(std::string(""), config1->getVirtualDisplayViewDescription(viewName1)); + + OCIO_REQUIRE_EQUAL(1, config2->getVirtualDisplayNumViews(OCIO::VIEW_SHARED)); + + const char * viewName2 = config2->getVirtualDisplayView(OCIO::VIEW_SHARED, 0); + + OCIO_CHECK_EQUAL(std::string("view"), viewName2); + OCIO_CHECK_EQUAL(std::string("display_vt"), config2->getVirtualDisplayViewTransformName(viewName2)); + OCIO_CHECK_EQUAL(std::string("display_cs"), config2->getVirtualDisplayViewColorSpaceName(viewName2)); + OCIO_CHECK_EQUAL(std::string(""), config2->getVirtualDisplayViewLooks(viewName2)); + OCIO_CHECK_EQUAL(std::string(""), config2->getVirtualDisplayViewRule(viewName2)); + OCIO_CHECK_EQUAL(std::string(""), config2->getVirtualDisplayViewDescription(viewName2)); + + OCIO_CHECK_EQUAL(std::string(viewName1), std::string(viewName2)); + OCIO_CHECK_ASSERT(OCIO::Config::VirtualViewsAreEqual(config1, config2, viewName1)); + + OCIO_CHECK_EQUAL(std::string(viewName1), std::string(viewName2)); + OCIO_CHECK_ASSERT(OCIO::Config::VirtualViewsAreEqual(config1, config2, viewName1)); + } + { + // Test when a shared virtual view exists in one config but not the other. + OCIO::ConfigRcPtr cfg = config1->createEditableCopy(); + + OCIO_CHECK_ASSERT(config1->hasVirtualView("Film")); + OCIO_CHECK_ASSERT(config1->virtualViewIsShared("Film")); + + OCIO_REQUIRE_EQUAL(2, cfg->getVirtualDisplayNumViews(OCIO::VIEW_SHARED)); + OCIO_CHECK_ASSERT(cfg->hasVirtualView("Film")); + OCIO_CHECK_ASSERT(cfg->virtualViewIsShared("Film")); + + OCIO_CHECK_ASSERT(OCIO::Config::VirtualViewsAreEqual(config1, cfg, "Film")); + + // Check against another config where the virtual view is display-defined. + OCIO_CHECK_ASSERT(OCIO::Config::VirtualViewsAreEqual(config2, cfg, "Film")); + + // Remove a shared view from the virtual display. + cfg->removeVirtualDisplayView("Film"); + + OCIO_REQUIRE_EQUAL(1, cfg->getVirtualDisplayNumViews(OCIO::VIEW_SHARED)); + OCIO_CHECK_ASSERT(!cfg->hasVirtualView("Film")); + OCIO_CHECK_ASSERT(!cfg->virtualViewIsShared("Film")); + + OCIO_CHECK_ASSERT(!OCIO::Config::VirtualViewsAreEqual(config1, cfg, "Film")); + OCIO_CHECK_ASSERT(!OCIO::Config::VirtualViewsAreEqual(config2, cfg, "Film")); + } + { + // Test when a display-defined virtual view exists in one config but not the other. + OCIO::ConfigRcPtr cfg = config2->createEditableCopy(); + + // Remove a display-defined view from the virtual display. + OCIO_CHECK_ASSERT(config2->hasVirtualView("Film")); + OCIO_CHECK_ASSERT(!config2->virtualViewIsShared("Film")); // Confirm display-defined + + OCIO_REQUIRE_EQUAL(2, cfg->getVirtualDisplayNumViews(OCIO::VIEW_DISPLAY_DEFINED)); + OCIO_CHECK_ASSERT(cfg->hasVirtualView("Film")); + OCIO_CHECK_ASSERT(!cfg->virtualViewIsShared("Film")); // Confirm display-defined + + OCIO_CHECK_ASSERT(OCIO::Config::VirtualViewsAreEqual(config2, cfg, "Film")); + + // Check against another config where the virtual view is a reference to a shared view. + OCIO_CHECK_ASSERT(OCIO::Config::VirtualViewsAreEqual(config1, cfg, "Film")); + + // Remove a display-defined view from the virtual display. + cfg->removeVirtualDisplayView("Film"); + + OCIO_REQUIRE_EQUAL(1, cfg->getVirtualDisplayNumViews(OCIO::VIEW_DISPLAY_DEFINED)); + OCIO_CHECK_ASSERT(!cfg->hasVirtualView("Film")); + + OCIO_CHECK_ASSERT(!OCIO::Config::VirtualViewsAreEqual(config2, cfg, "Film")); + OCIO_CHECK_ASSERT(!OCIO::Config::VirtualViewsAreEqual(config1, cfg, "Film")); + } } diff --git a/tests/python/ConfigTest.py b/tests/python/ConfigTest.py index 5130ebbf88..f63ad15af6 100644 --- a/tests/python/ConfigTest.py +++ b/tests/python/ConfigTest.py @@ -288,7 +288,7 @@ def test_copy(self): self.assertEqual(other.getFileRules().getNumEntries(), cfg.getFileRules().getNumEntries() - 1) def test_shared_views(self): - # Test these Config functions: addSharedView, getSharedViews, removeSharedView. + # Test these Config functions: addSharedView, getSharedViews, removeSharedView, clearSharedViews. cfg = OCIO.Config.CreateRaw() views = cfg.getSharedViews() @@ -413,11 +413,7 @@ def test_shared_views(self): cfg.removeSharedView('view3') views = cfg.getSharedViews() self.assertEqual(5, len(views)) - cfg.removeSharedView('view4') - cfg.removeSharedView('view5') - cfg.removeSharedView('view6') - cfg.removeSharedView('view1') - cfg.removeSharedView('view2') + cfg.clearSharedViews() views = cfg.getSharedViews() self.assertEqual(0, len(views)) @@ -842,12 +838,35 @@ def test_virtual_display(self): "sRGB"))) self.assertEqual(1, len(cfg.getViews(OCIO.VIEW_SHARED, "sRGB"))) + self.assertTrue(cfg.displayHasView("sRGB", "sview1")) + self.assertFalse(cfg.displayHasView("sRGB", "sview2")) + self.assertFalse(cfg.displayHasView("sRGB", " ")) + + self.assertTrue(cfg.viewIsShared("sRGB", "sview1")) + self.assertFalse(cfg.viewIsShared("sRGB", "Raw")) + self.assertFalse(cfg.viewIsShared("sRGB", " ")) + + other = copy.deepcopy(cfg) + + self.assertTrue(OCIO.Config.ViewsAreEqual(cfg, other, "sRGB", "sview1")) + self.assertTrue(OCIO.Config.ViewsAreEqual(cfg, other, "sRGB", "Raw")) + self.assertTrue(OCIO.Config.ViewsAreEqual(cfg, other, "sRGB", "view")) + + cfg.removeDisplayView("sRGB", "sview1") + cfg.removeDisplayView("sRGB", "Raw") + cfg.removeDisplayView("sRGB", "view") + + self.assertFalse(OCIO.Config.ViewsAreEqual(cfg, other, "sRGB", "sview1")) + self.assertFalse(OCIO.Config.ViewsAreEqual(cfg, other, "sRGB", "Raw")) + self.assertFalse(OCIO.Config.ViewsAreEqual(cfg, other, "sRGB", "view")) + # Validate the virtual display information self.assertEqual( 2, len(cfg.getVirtualDisplayViews(OCIO.VIEW_DISPLAY_DEFINED))) view_name = cfg.getVirtualDisplayViews(OCIO.VIEW_DISPLAY_DEFINED)[0] + self.assertTrue(cfg.hasVirtualView(view_name)) self.assertEqual("Raw", view_name) self.assertEqual("", cfg.getVirtualDisplayViewTransformName(view_name)) self.assertEqual("raw", @@ -856,7 +875,10 @@ def test_virtual_display(self): self.assertEqual("", cfg.getVirtualDisplayViewRule(view_name)) self.assertEqual("", cfg.getVirtualDisplayViewDescription(view_name)) + self.assertTrue(OCIO.Config.VirtualViewsAreEqual(cfg, other, view_name)) + view_name = cfg.getVirtualDisplayViews(OCIO.VIEW_DISPLAY_DEFINED)[1] + self.assertTrue(cfg.hasVirtualView(view_name)) self.assertEqual("Film", view_name) self.assertEqual("display_vt", cfg.getVirtualDisplayViewTransformName(view_name)) @@ -866,13 +888,39 @@ def test_virtual_display(self): self.assertEqual("", cfg.getVirtualDisplayViewRule(view_name)) self.assertEqual("", cfg.getVirtualDisplayViewDescription(view_name)) + self.assertTrue(OCIO.Config.VirtualViewsAreEqual(cfg, other, view_name)) + self.assertEqual(1, len(cfg.getVirtualDisplayViews(OCIO.VIEW_SHARED))) self.assertEqual("sview2", cfg.getVirtualDisplayViews(OCIO.VIEW_SHARED)[0]) + + self.assertTrue(cfg.hasVirtualView("sview2")) + self.assertTrue(cfg.virtualViewIsShared("sview2")) + self.assertTrue(OCIO.Config.VirtualViewsAreEqual(cfg, other, "sview2")) + + other.addVirtualDisplayView("sview3", "", "raw") + + self.assertFalse(cfg.hasVirtualView("sview3")) + self.assertTrue(other.hasVirtualView("sview3")) + self.assertFalse(OCIO.Config.VirtualViewsAreEqual(cfg, other, "sview3")) + + # Test a virtual view that doesn't exist in either + self.assertFalse(cfg.hasVirtualView(" ")) + self.assertFalse(other.hasVirtualView(" ")) + self.assertFalse(OCIO.Config.VirtualViewsAreEqual(cfg, other, " ")) + + self.assertFalse(cfg.hasVirtualView("nonexistent")) + self.assertFalse(other.hasVirtualView("nonexistent")) + self.assertFalse(OCIO.Config.VirtualViewsAreEqual(cfg, other, "nonexistent")) # Remove a view from the virtual display cfg.removeVirtualDisplayView("Raw") + self.assertFalse(cfg.hasVirtualView("Raw")) + self.assertTrue(other.hasVirtualView("Raw")) + + self.assertFalse(OCIO.Config.VirtualViewsAreEqual(cfg, other, "Raw")) + self.assertEqual( 1, len(cfg.getVirtualDisplayViews(OCIO.VIEW_DISPLAY_DEFINED))) @@ -891,6 +939,14 @@ def test_virtual_display(self): len(cfg.getVirtualDisplayViews(OCIO.VIEW_DISPLAY_DEFINED))) self.assertEqual(0, len(cfg.getVirtualDisplayViews(OCIO.VIEW_SHARED))) + self.assertFalse(cfg.hasVirtualView("sview2")) + self.assertFalse(cfg.virtualViewIsShared("sview2")) + + self.assertTrue(other.hasVirtualView("sview2")) + self.assertTrue(other.virtualViewIsShared("sview2")) + + self.assertFalse(OCIO.Config.VirtualViewsAreEqual(cfg, other, "sview2")) + cfg.addVirtualDisplaySharedView("sview2") self.assertEqual( 1,