Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions src/lib/app/RvCommon/DesktopVideoDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
#include <lcms2.h>
#endif

#ifdef PLATFORM_DARWIN
#include <ApplicationServices/ApplicationServices.h>
#include <ColorSync/ColorSync.h>
#endif

#include <RvCommon/DesktopVideoDevice.h>
#include <TwkGLF/GLPipeline.h>
#include <TwkGLF/GLRenderPrimitives.h>
Expand Down Expand Up @@ -916,6 +921,51 @@ namespace Rv
}
#endif

#ifdef PLATFORM_DARWIN
TwkApp::VideoDevice::ColorProfile DesktopVideoDevice::colorProfile() const
{
//
// Get the display's color sync profile
//

CGDirectDisplayID displayIDs[20];
uint32_t displayCount = 0;
CGGetOnlineDisplayList(20, displayIDs, &displayCount);

if (m_screen < 0 || m_screen >= static_cast<int>(displayCount))
{
m_colorProfile = ColorProfile();
return m_colorProfile;
}

CGDirectDisplayID cgScreen = displayIDs[m_screen];

if (ColorSyncProfileRef iccRef = ColorSyncProfileCreateWithDisplayID(cgScreen))
{
m_colorProfile.type = ICCProfile;

CFStringRef desc = ColorSyncProfileCopyDescriptionString(iccRef);
CFIndex n = CFStringGetLength(desc);
std::vector<char> buffer(n * 4 + 1);
CFStringGetCString(desc, &buffer.front(), buffer.size(), kCFStringEncodingUTF8);
m_colorProfile.description = &buffer.front();

CFURLRef url = ColorSyncProfileGetURL(iccRef, NULL);
CFStringRef urlstr = CFURLGetString(url);
buffer.resize(CFStringGetLength(urlstr) * 4 + 1);
CFStringGetCString(urlstr, &buffer.front(), buffer.size(), kCFStringEncodingUTF8);

m_colorProfile.url = &buffer.front();
}
else
{
m_colorProfile = ColorProfile();
}

return m_colorProfile;
}
#endif

std::vector<VideoDevice*> DesktopVideoDevice::createDesktopVideoDevices(TwkApp::VideoModule* module, const QTGLVideoDevice* shareDevice)
{
std::vector<VideoDevice*> devices;
Expand Down
2 changes: 1 addition & 1 deletion src/lib/app/RvCommon/RvCommon/DesktopVideoDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ namespace Rv
private:
void addDataFormatAtDepth(size_t depth, DesktopStereoMode m);

#ifdef PLATFORM_WINDOWS
#if defined(PLATFORM_WINDOWS) || defined(PLATFORM_DARWIN)
virtual ColorProfile colorProfile() const;
#endif

Expand Down
11 changes: 10 additions & 1 deletion src/lib/ip/OCIONodes/OCIOIPNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,8 @@ namespace IPCore

updateContext();
updateFunction();

m_initialized = true;
}

void OCIOIPNode::updateContext()
Expand Down Expand Up @@ -519,7 +521,10 @@ namespace IPCore
boost::hash<string> string_hash;
string inName = stringProp("ocio.inColorSpace", m_state->linear);

if (inName.empty())
// synlinearize/syndisplay build their pipeline from file/URL
// transforms, so an empty input color space is valid for those modes.
const bool needsInColorSpace = ociofunction != "synlinearize" && ociofunction != "syndisplay";
if (inName.empty() && needsInColorSpace)
return;

try
Expand Down Expand Up @@ -603,6 +608,8 @@ namespace IPCore
string inTransformURL = stringProp("inTransform.url", "");
if (inTransformURL.empty() && (!m_inTransformData || m_inTransformData->size() == 0))
{
if (!m_initialized)
return;
TWK_THROW_EXC_STREAM("Either inTransform.url or inTransform.data property "
"needs to be set for synlinearize function");
}
Expand Down Expand Up @@ -648,6 +655,8 @@ namespace IPCore
const string outTransformURL = stringProp("outTransform.url", "");
if (outTransformURL.empty())
{
if (!m_initialized)
return;
TWK_THROW_EXC_STREAM("outTransform.url property needs to "
"be set for syndisplay function");
}
Expand Down
1 change: 1 addition & 0 deletions src/lib/ip/OCIONodes/OCIONodes/OCIOIPNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ namespace IPCore
std::vector<OCIO3DLUTPtr> m_3DLUTs;
OCIOState* m_state{nullptr};
bool m_useRawConfig{false};
bool m_initialized{false};

// synlinearize/syndisplay functions
StringProperty* m_inTransformURL{nullptr};
Expand Down
11 changes: 11 additions & 0 deletions src/plugins/rv-packages/color_profile_setup/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#
# Copyright (C) 2026 Autodesk, Inc. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#

SET(_target
"color_profile_setup"
)

RV_STAGE(TYPE "RVPKG" TARGET ${_target})
46 changes: 46 additions & 0 deletions src/plugins/rv-packages/color_profile_setup/PACKAGE
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package: Color Profile Setup
author: Autodesk, Inc.
organization: Autodesk, Inc.
version: 1.0
requires: ''
rv: 4.0
openrv: 1.0.0
optional: true
system: true
hidden: false

modes:
- file: color_profile_setup.py
menu: ''
shortcut: ''
event: ''
load: immediate

description: |
<p>
Automatically inserts the SYNLinearize (source linearization) and
SYNDisplay (display color management) OCIO nodes based on embedded ICC
color profiles and the display's system profile, replacing the manual,
key-bound script that previously had to be run by hand.
</p>

<p>
Source media carrying an embedded ICC profile has its
RVLinearizePipelineGroup switched to a SYNLinearize node whose
inTransform.data is set to the profile blob. Each RVDisplayGroup whose
device has a system ICC profile has its display pipeline switched to a
SYNDisplay node pointed at that profile.
</p>

<p>
For rvio parity, the display transform is baked into the RVOutputGroup(s)
at session-write time (RVDisplayGroup is not persisted, and rvio renders
through the output group), so an exported session renders identically in
rvio.
</p>

<p>
The feature is opt-in and self-contained: enable it via the
"Automatic Color Profile Setup" checkbox under the package's menu. The
setting is stored in the package's own preferences and is off by default.
</p>
Loading
Loading