Krita Source Code Documentation
Loading...
Searching...
No Matches
KisCanvasSurfaceColorSpaceManager Class Reference

#include <KisCanvasSurfaceColorSpaceManager.h>

+ Inheritance diagram for KisCanvasSurfaceColorSpaceManager:

Signals

void sigDisplayConfigChanged (const KisDisplayConfig &config)
 

Public Member Functions

QString colorManagementReport () const
 
KisDisplayConfig displayConfig () const
 
bool isReady () const
 
 KisCanvasSurfaceColorSpaceManager (KisSurfaceColorManagerInterface *interface, const KisConfig::CanvasSurfaceMode surfaceMode, const KisDisplayConfig::Options &options, QObject *parent=nullptr)
 
QString osPreferredColorSpaceReport () const
 
 Private (KisSurfaceColorManagerInterface *interface)
 
void setDisplayConfigOptions (const KisConfig::CanvasSurfaceMode surfaceMode, const KisDisplayConfig::Options &options)
 
void setDisplayConfigOptions (const KisDisplayConfig::Options &options)
 
 ~KisCanvasSurfaceColorSpaceManager ()
 
- Public Member Functions inherited from Private
 Private (KisCanvas2 *c)
 

Static Public Member Functions

static KisSurfaceColorimetry::RenderIntent calculateConfigIntent (const KisDisplayConfig::Options &options)
 

Public Attributes

KisDisplayConfig currentConfig
 
QScopedPointer< KisSurfaceColorManagerInterfaceinterface
 
std::optional< KisSurfaceColorimetry::RenderIntentproofingIntentOverride
 
KisConfig::CanvasSurfaceMode surfaceMode = KisConfig::CanvasSurfaceMode::Preferred
 
- Public Attributes inherited from Private
KisCanvas2canvas
 
int displayedFrame
 
int intendedFrame
 

Private Slots

void slotInterfacePreferredDescriptionChanged ()
 
void slotInterfaceReadyChanged (bool isReady)
 

Private Member Functions

void reinitializeSurfaceDescription (const KisDisplayConfig::Options &newOptions)
 

Private Attributes

QScopedPointer< Privatem_d
 

Detailed Description

Definition at line 20 of file KisCanvasSurfaceColorSpaceManager.cpp.

Constructor & Destructor Documentation

◆ KisCanvasSurfaceColorSpaceManager()

KisCanvasSurfaceColorSpaceManager::KisCanvasSurfaceColorSpaceManager ( KisSurfaceColorManagerInterface * interface,
const KisConfig::CanvasSurfaceMode surfaceMode,
const KisDisplayConfig::Options & options,
QObject * parent = nullptr )

Definition at line 32 of file KisCanvasSurfaceColorSpaceManager.cpp.

36 : QObject(parent)
37 , m_d(new Private(interface))
38{
39 m_d->currentConfig.profile = KoColorSpaceRegistry::instance()->p709SRGBProfile();
40 m_d->currentConfig.setOptions(options);
41 m_d->currentConfig.isHDR = false;
42 m_d->surfaceMode = surfaceMode;
43
46
47 if (m_d->interface->isReady()) {
49 }
50}
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
void sigReadyChanged(bool value)
void sigPreferredSurfaceDescriptionChanged(const KisSurfaceColorimetry::SurfaceDescription &desc)
QScopedPointer< KisSurfaceColorManagerInterface > interface
static KoColorSpaceRegistry * instance()
const KoColorProfile * p709SRGBProfile() const

References connect(), KoColorSpaceRegistry::instance(), m_d, KoColorSpaceRegistry::p709SRGBProfile(), KisSurfaceColorManagerInterface::sigPreferredSurfaceDescriptionChanged(), KisSurfaceColorManagerInterface::sigReadyChanged(), slotInterfacePreferredDescriptionChanged(), slotInterfaceReadyChanged(), and surfaceMode.

◆ ~KisCanvasSurfaceColorSpaceManager()

KisCanvasSurfaceColorSpaceManager::~KisCanvasSurfaceColorSpaceManager ( )

Definition at line 52 of file KisCanvasSurfaceColorSpaceManager.cpp.

53{
54}

Member Function Documentation

◆ calculateConfigIntent()

static KisSurfaceColorimetry::RenderIntent KisCanvasSurfaceColorSpaceManager::calculateConfigIntent ( const KisDisplayConfig::Options & options)
static

◆ colorManagementReport()

QString KisCanvasSurfaceColorSpaceManager::colorManagementReport ( ) const

Definition at line 56 of file KisCanvasSurfaceColorSpaceManager.cpp.

57{
58 QString report;
59 QDebug str(&report);
60
61 if (!m_d->interface->isReady()) {
62 str << "WARNING: surface color management interface is not ready!" << Qt::endl;
63 str << Qt::endl;
64 }
65
70
71 str << "Configured mode:" << m_d->surfaceMode << Qt::endl;
72
73 RenderIntent preferredIntent = Private::calculateConfigIntent(m_d->currentConfig.options());
74 str << "Configured intent:" << preferredIntent << "supported:" << m_d->interface->supportsRenderIntent(preferredIntent) << Qt::endl;
75
76 str << "Actual intent:";
77 if (m_d->interface->renderingIntent()) {
78 str << *m_d->interface->renderingIntent() << Qt::endl;
79 } else {
80 str << "<none>" << Qt::endl;
81 }
82 str << Qt::endl;
83
84 str << "Active surface description:";
85 if (m_d->interface->surfaceDescription()) {
86 str << Qt::endl;
87 str.noquote() << m_d->interface->surfaceDescription()->makeTextReport() << Qt::endl;
88 } else {
89 str << "<none>" << Qt::endl;
90 }
91 str << Qt::endl;
92
93 str << "Selected Profile:";
94 if (m_d->currentConfig.profile) {
95 auto profile = m_d->currentConfig.profile;
96
97 str << profile->name() << Qt::endl;
98 str << " primaries:" << KoColorProfile::getColorPrimariesName(profile->getColorPrimaries()) << Qt::endl;
99 str << " transfer: " << KoColorProfile::getTransferCharacteristicName(profile->getTransferCharacteristics()) << Qt::endl;
100 str << Qt::endl;
101
102 {
103 auto colVec = profile->getColorantsxyY();
104 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(colVec.size() == 9, report);
105 KisColorimetryUtils::xyY colR{colVec[0], colVec[1], colVec[2]};
106 KisColorimetryUtils::xyY colG{colVec[3], colVec[4], colVec[5]};
107 KisColorimetryUtils::xyY colB{colVec[6], colVec[7], colVec[8]};
108
109 str << " red: " << colR << Qt::endl;
110 str << " green:" << colG << Qt::endl;
111 str << " blue: " << colB << Qt::endl;
112 }
113
114 {
115 auto whiteVec = profile->getWhitePointxyY();
116 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(whiteVec.size() == 3, report);
117 KisColorimetryUtils::xyY white{whiteVec[0], whiteVec[1], whiteVec[2]};
118
119 str << " white: " << white << Qt::endl;
120 str << Qt::endl;
121 }
122
123 } else {
124 str << "<none>" << Qt::endl;
125 }
126
127 str << "Compositor preferred surface description:";
128 if (m_d->interface->preferredSurfaceDescription()) {
129 str << Qt::endl;
130 str.noquote() << m_d->interface->preferredSurfaceDescription()->makeTextReport() << Qt::endl;
131 } else {
132 str << "<none>" << Qt::endl;
133 }
134 str << Qt::endl;
135
136 return report;
137}
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
Definition kis_assert.h:129
static QString getTransferCharacteristicName(TransferCharacteristics curve)
getTransferCharacteristicName
static QString getColorPrimariesName(ColorPrimaries primaries)
getColorPrimariesName

References KoColorProfile::getColorPrimariesName(), KoColorProfile::getTransferCharacteristicName(), KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE, and m_d.

◆ displayConfig()

KisDisplayConfig KisCanvasSurfaceColorSpaceManager::displayConfig ( ) const

Definition at line 395 of file KisCanvasSurfaceColorSpaceManager.cpp.

396{
397 return m_d->currentConfig;
398}

References m_d.

◆ isReady()

bool KisCanvasSurfaceColorSpaceManager::isReady ( ) const

Definition at line 390 of file KisCanvasSurfaceColorSpaceManager.cpp.

391{
392 return m_d->interface->isReady();
393}

References m_d.

◆ osPreferredColorSpaceReport()

QString KisCanvasSurfaceColorSpaceManager::osPreferredColorSpaceReport ( ) const

Definition at line 139 of file KisCanvasSurfaceColorSpaceManager.cpp.

140{
141 QString report;
142 QDebug str(&report);
143
144 if (!m_d->interface->isReady()) {
145 str << "WARNING: surface color management interface is not ready!" << Qt::endl;
146 str << Qt::endl;
147 }
148
149 if (m_d->interface->preferredSurfaceDescription()) {
150 str << Qt::endl;
151 str.noquote() << m_d->interface->preferredSurfaceDescription()->makeTextReport() << Qt::endl;
152 } else {
153 str << "<none>" << Qt::endl;
154 }
155
156 return report;
157}

References m_d.

◆ Private()

KisCanvasSurfaceColorSpaceManager::Private ( KisSurfaceColorManagerInterface * interface)
inline

Definition at line 22 of file KisCanvasSurfaceColorSpaceManager.cpp.

◆ reinitializeSurfaceDescription()

void KisCanvasSurfaceColorSpaceManager::reinitializeSurfaceDescription ( const KisDisplayConfig::Options & newOptions)
private

Definition at line 216 of file KisCanvasSurfaceColorSpaceManager.cpp.

217{
222
223 RenderIntent preferredIntent =
224 Private::calculateConfigIntent(newOptions);
225
226 if (!m_d->interface->supportsRenderIntent(preferredIntent)) {
227 qWarning() << "WARNING: failed to set user preferred rendering"
228 << "intent for the surface, intent \""
229 << preferredIntent << "\" is unsupported, falling back to \"perceptual\"";
230
231 preferredIntent = RenderIntent::render_intent_perceptual;
232
233 // perceptual intent is guaranteed to be supported by the compositor
234 KIS_SAFE_ASSERT_RECOVER_RETURN(m_d->interface->supportsRenderIntent(preferredIntent));
235 }
236
237 std::optional<SurfaceDescription> requestedDescription;
238 const KoColorProfile *profile = nullptr;
239
240 if (m_d->surfaceMode == KisConfig::CanvasSurfaceMode::Unmanaged) {
242 } else {
243 requestedDescription = SurfaceDescription();
244
245 using namespace KisSurfaceColorimetry;
246
247 const auto compositorPreferred = m_d->interface->preferredSurfaceDescription();
248 KIS_SAFE_ASSERT_RECOVER_RETURN(compositorPreferred);
249
250 if (m_d->surfaceMode == KisConfig::CanvasSurfaceMode::Preferred) {
251 // we don't copy mastering properties, since they mean a different thing
252 // for the preferred space and outputs
253 requestedDescription->colorSpace = compositorPreferred->colorSpace;
254
255 if (std::holds_alternative<NamedTransferFunction>(requestedDescription->colorSpace.transferFunction) &&
256 std::get<NamedTransferFunction>(requestedDescription->colorSpace.transferFunction) == NamedTransferFunction::transfer_function_st2084_pq) {
257
258 // we have our own definition of the Rec2020PQ space with
259 // the reference point fixed to 80 cd/m2
260 requestedDescription->colorSpace.luminance = Luminance();
261 requestedDescription->colorSpace.luminance->minLuminance = 0;
262 requestedDescription->colorSpace.luminance->referenceLuminance = 80;
263 requestedDescription->colorSpace.luminance->maxLuminance = 10000;
264 }
265
266 } else if (m_d->surfaceMode == KisConfig::CanvasSurfaceMode::Rec709g22) {
267 requestedDescription->colorSpace.primaries = NamedPrimaries::primaries_srgb;
268 requestedDescription->colorSpace.transferFunction = NamedTransferFunction::transfer_function_gamma22;
269 if (compositorPreferred->colorSpace.luminance) {
270 // rec709-g22 is considered as SDR in lcms, so we should our space to SDR range
271 requestedDescription->colorSpace.luminance =
272 compositorPreferred->colorSpace.luminance->clipToSdr();
273 }
274 } else if (m_d->surfaceMode == KisConfig::CanvasSurfaceMode::Rec709g10) {
275 requestedDescription->colorSpace.primaries = NamedPrimaries::primaries_srgb;
276 requestedDescription->colorSpace.transferFunction = NamedTransferFunction::transfer_function_ext_linear;
277 if (compositorPreferred->colorSpace.luminance) {
278 // rec709-g22 is considered as SDR in lcms, so we should our space to SDR range
279 requestedDescription->colorSpace.luminance =
280 compositorPreferred->colorSpace.luminance->clipToSdr();
281 }
282 }
283
284 if (std::holds_alternative<NamedPrimaries>(requestedDescription->colorSpace.primaries) &&
285 std::get<NamedPrimaries>(requestedDescription->colorSpace.primaries) == NamedPrimaries::primaries_unknown) {
286
287 requestedDescription->colorSpace.primaries = NamedPrimaries::primaries_srgb;
288 }
289
290 if (std::holds_alternative<NamedTransferFunction>(requestedDescription->colorSpace.transferFunction) &&
291 std::get<NamedTransferFunction>(requestedDescription->colorSpace.transferFunction) == NamedTransferFunction::transfer_function_unknown) {
292
293 requestedDescription->colorSpace.transferFunction = NamedTransferFunction::transfer_function_gamma22;
294 }
295
296 if (!m_d->interface->supportsSurfaceDescription(*requestedDescription)) {
297
298 // try pure sRGB
299 requestedDescription->colorSpace.primaries = NamedPrimaries::primaries_srgb;
300 requestedDescription->colorSpace.transferFunction = NamedTransferFunction::transfer_function_srgb;
301
302 if (!m_d->interface->supportsSurfaceDescription(*requestedDescription)) {
303 requestedDescription->colorSpace.transferFunction = NamedTransferFunction::transfer_function_gamma22;
304
305 if (!m_d->interface->supportsSurfaceDescription(*requestedDescription)) {
306 qWarning() << "WARNING: failed to find a suitable surface format for the compositor";
307 return; // TODO: extra signals?
308 }
309 }
310 }
311
312 {
313 auto request = colorSpaceToRequest(requestedDescription->colorSpace);
314 if (request.isValid()) {
315 profile = KoColorSpaceRegistry::instance()->profileFor(request.colorants,
316 request.colorPrimariesType,
317 request.transferFunction);
318 }
319 }
320
321 if (!profile) {
322 // keep primaries, but change the transfer function to gamma22
323 requestedDescription->colorSpace.transferFunction = NamedTransferFunction::transfer_function_gamma22;
324 if (m_d->interface->supportsSurfaceDescription(*requestedDescription)) {
325 auto request = colorSpaceToRequest(requestedDescription->colorSpace);
326 if (request.isValid()) {
327 profile = KoColorSpaceRegistry::instance()->profileFor(request.colorants,
328 request.colorPrimariesType,
329 request.transferFunction);
330 }
331 }
332 }
333
334 if (!profile) {
335 // keep primaries, but change the transfer function to srgb
336 requestedDescription->colorSpace.transferFunction = NamedTransferFunction::transfer_function_srgb;
337 if (m_d->interface->supportsSurfaceDescription(*requestedDescription)) {
338 auto request = colorSpaceToRequest(requestedDescription->colorSpace);
339 if (request.isValid()) {
340 profile = KoColorSpaceRegistry::instance()->profileFor(request.colorants,
341 request.colorPrimariesType,
342 request.transferFunction);
343 }
344 }
345 }
346
347 if (!profile) {
348 qWarning() << "WARNING: failed to to create a profile for the compositor's preferred color space";
349 qWarning() << " " << ppVar(compositorPreferred);
350 qWarning() << " " << ppVar(*requestedDescription);
351 // TODO: debug all supported values for the compositor
352 return; // TODO: extra signals?
353 }
354 }
355
357 KIS_SAFE_ASSERT_RECOVER_RETURN(!requestedDescription || m_d->interface->supportsSurfaceDescription(*requestedDescription));
358
359 if (m_d->interface->surfaceDescription() != requestedDescription ||
360 m_d->interface->renderingIntent() != preferredIntent) {
361
362 if (requestedDescription) {
363 auto future = m_d->interface->setSurfaceDescription(*requestedDescription, preferredIntent);
364 future.then([](QFuture<bool> result) {
365 if (!result.isValid() || !result.result()) {
366 qWarning()
367 << "WARNING: failed to set color space for the surface, setSurfaceDescription() returned false";
368 }
369 });
370 } else {
371 m_d->interface->unsetSurfaceDescription();
372 }
373 }
374
375 const bool requestedDescriptionIsHDR = requestedDescription && requestedDescription->colorSpace.isHDR();
376
377 KisDisplayConfig newDisplayConfig;
378 newDisplayConfig.profile = profile;
379 newDisplayConfig.setOptions(newOptions); // TODO: think about failure to set the intent and infinite update loop
380 newDisplayConfig.isHDR = requestedDescriptionIsHDR;
381
382 KIS_SAFE_ASSERT_RECOVER_RETURN(m_d->currentConfig.profile);
383
384 if (m_d->currentConfig != newDisplayConfig) {
385 m_d->currentConfig = newDisplayConfig;
386 Q_EMIT sigDisplayConfigChanged(m_d->currentConfig);
387 }
388}
KisDisplayConfig This class keeps track of the color management configuration for image to display....
void setOptions(const Options &options)
const KoColorProfile * profile
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128
#define ppVar(var)
Definition kis_debug.h:155
PigmentProfileRequest colorSpaceToRequest(ColorSpace cs)
void sigDisplayConfigChanged(const KisDisplayConfig &config)
const KoColorProfile * profileFor(const QVector< double > &colorants, ColorPrimaries colorPrimaries, TransferCharacteristics transferFunction) const
profileFor tries to find the profile that matches these characteristics, if no such profile is found,...

References KoColorSpaceRegistry::instance(), KisDisplayConfig::isHDR, KIS_SAFE_ASSERT_RECOVER_RETURN, m_d, KoColorSpaceRegistry::p709SRGBProfile(), ppVar, KisConfig::Preferred, KisDisplayConfig::profile, KoColorSpaceRegistry::profileFor(), KisConfig::Rec709g10, KisConfig::Rec709g22, KisDisplayConfig::setOptions(), sigDisplayConfigChanged(), and KisConfig::Unmanaged.

◆ setDisplayConfigOptions() [1/2]

void KisCanvasSurfaceColorSpaceManager::setDisplayConfigOptions ( const KisConfig::CanvasSurfaceMode surfaceMode,
const KisDisplayConfig::Options & options )

Definition at line 187 of file KisCanvasSurfaceColorSpaceManager.cpp.

188{
189 if (!m_d->interface->isReady()) return;
190 if (surfaceMode == m_d->surfaceMode && options == m_d->currentConfig.options()) return;
191
192 m_d->surfaceMode = surfaceMode;
194}
void reinitializeSurfaceDescription(const KisDisplayConfig::Options &newOptions)

References m_d, reinitializeSurfaceDescription(), and surfaceMode.

◆ setDisplayConfigOptions() [2/2]

void KisCanvasSurfaceColorSpaceManager::setDisplayConfigOptions ( const KisDisplayConfig::Options & options)

Definition at line 196 of file KisCanvasSurfaceColorSpaceManager.cpp.

197{
198 setDisplayConfigOptions(m_d->surfaceMode, options);
199}
void setDisplayConfigOptions(const KisConfig::CanvasSurfaceMode surfaceMode, const KisDisplayConfig::Options &options)

References m_d, and setDisplayConfigOptions().

◆ sigDisplayConfigChanged

void KisCanvasSurfaceColorSpaceManager::sigDisplayConfigChanged ( const KisDisplayConfig & config)
signal

◆ slotInterfacePreferredDescriptionChanged

void KisCanvasSurfaceColorSpaceManager::slotInterfacePreferredDescriptionChanged ( )
privateslot

Definition at line 208 of file KisCanvasSurfaceColorSpaceManager.cpp.

209{
210 reinitializeSurfaceDescription(m_d->currentConfig.options());
211}

References m_d, and reinitializeSurfaceDescription().

◆ slotInterfaceReadyChanged

void KisCanvasSurfaceColorSpaceManager::slotInterfaceReadyChanged ( bool isReady)
privateslot

Definition at line 201 of file KisCanvasSurfaceColorSpaceManager.cpp.

202{
203 if (isReady) {
204 reinitializeSurfaceDescription(m_d->currentConfig.options());
205 }
206}

References isReady(), m_d, and reinitializeSurfaceDescription().

Member Data Documentation

◆ currentConfig

KisDisplayConfig KisCanvasSurfaceColorSpaceManager::currentConfig

Definition at line 25 of file KisCanvasSurfaceColorSpaceManager.cpp.

◆ interface

QScopedPointer<KisSurfaceColorManagerInterface> KisCanvasSurfaceColorSpaceManager::interface

Definition at line 24 of file KisCanvasSurfaceColorSpaceManager.cpp.

◆ m_d

QScopedPointer<Private> KisCanvasSurfaceColorSpaceManager::m_d
private

Definition at line 49 of file KisCanvasSurfaceColorSpaceManager.h.

◆ proofingIntentOverride

std::optional<KisSurfaceColorimetry::RenderIntent> KisCanvasSurfaceColorSpaceManager::proofingIntentOverride

Definition at line 26 of file KisCanvasSurfaceColorSpaceManager.cpp.

◆ surfaceMode

KisConfig::CanvasSurfaceMode KisCanvasSurfaceColorSpaceManager::surfaceMode = KisConfig::CanvasSurfaceMode::Preferred

Definition at line 27 of file KisCanvasSurfaceColorSpaceManager.cpp.


The documentation for this class was generated from the following files: