10#include <config-hdr.h>
11#include <QApplication>
12#include <QOpenGLContext>
13#include <QOpenGLFunctions>
24#include <qpa/qplatformnativeinterface.h>
27#include <QGlobalStatic>
49 return isFormatHDR(QSurfaceFormat::defaultFormat());
55 QOpenGLContext *sharedContext = QOpenGLContext::globalShareContext();
56 QSurfaceFormat format = sharedContext ? sharedContext->format() : QSurfaceFormat::defaultFormat();
64 const auto surfaceColorSpace =
85struct AppAttributeSetter
87 AppAttributeSetter(Qt::ApplicationAttribute attribute,
bool useOpenGLES)
88 : m_attribute(attribute),
89 m_oldValue(QCoreApplication::testAttribute(attribute))
91 QCoreApplication::setAttribute(attribute, useOpenGLES);
94 ~AppAttributeSetter() {
95 QCoreApplication::setAttribute(m_attribute, m_oldValue);
99 Qt::ApplicationAttribute m_attribute;
100 bool m_oldValue =
false;
103struct SurfaceFormatSetter
105 SurfaceFormatSetter(
const QSurfaceFormat &format)
106 : m_oldFormat(QSurfaceFormat::defaultFormat())
108 QSurfaceFormat::setDefaultFormat(format);
111 ~SurfaceFormatSetter() {
112 QSurfaceFormat::setDefaultFormat(m_oldFormat);
116 QSurfaceFormat m_oldFormat;
120struct EnvironmentSetter
122 EnvironmentSetter(
const QLatin1String &env,
const QString &
value)
125 if (!qEnvironmentVariableIsEmpty(m_env.latin1())) {
126 m_oldValue = qgetenv(env.latin1());
128 if (!
value.isEmpty()) {
129 qputenv(env.latin1(),
value.toLatin1());
131 qunsetenv(env.latin1());
135 ~EnvironmentSetter() {
137 qputenv(m_env.latin1(), (*m_oldValue).toLatin1());
139 qunsetenv(m_env.latin1());
144 const QLatin1String m_env;
145 boost::optional<QString> m_oldValue;
150boost::optional<KisOpenGLModeProber::Result>
152 bool adjustGlobalState)
154 const QSurfaceFormat &format = rendererConfig.
format;
159 QScopedPointer<AppAttributeSetter> sharedContextSetter;
160 QScopedPointer<AppAttributeSetter> glSetter;
161 QScopedPointer<AppAttributeSetter> glesSetter;
162 QScopedPointer<SurfaceFormatSetter> formatSetter;
163 QScopedPointer<EnvironmentSetter> rendererSetter;
164 QScopedPointer<EnvironmentSetter> portalSetter;
165 QScopedPointer<QGuiApplication> application;
168 QByteArray probeAppName(
"krita");
169 char *argv = probeAppName.data();
172 if (adjustGlobalState) {
173 sharedContextSetter.reset(
new AppAttributeSetter(Qt::AA_ShareOpenGLContexts,
false));
175 if (format.renderableType() != QSurfaceFormat::DefaultRenderableType) {
176 glSetter.reset(
new AppAttributeSetter(Qt::AA_UseDesktopOpenGL, format.renderableType() != QSurfaceFormat::OpenGLES));
177 glesSetter.reset(
new AppAttributeSetter(Qt::AA_UseOpenGLES, format.renderableType() == QSurfaceFormat::OpenGLES));
180 if (!qEnvironmentVariableIsSet(
"QT_ANGLE_PLATFORM")) {
183 portalSetter.reset(
new EnvironmentSetter(QLatin1String(
"QT_NO_XDG_DESKTOP_PORTAL"), QLatin1String(
"1")));
184 formatSetter.reset(
new SurfaceFormatSetter(format));
188 const bool runningInKDE = qEnvironmentVariableIsSet(
"KDE_FULL_SESSION");
189 const bool isInAppimage = qEnvironmentVariableIsSet(
"APPIMAGE");
191 if (runningInKDE && !isInAppimage) {
192 QGuiApplication::setDesktopSettingsAware(
false);
195 application.reset(
new QGuiApplication(argc, &argv));
197 if (runningInKDE && !isInAppimage) {
198 QGuiApplication::setDesktopSettingsAware(
true);
204 surface.setFormat(format);
205 surface.setSurfaceType(QSurface::OpenGLSurface);
207 QOpenGLContext context;
208 context.setFormat(format);
211 if (!context.create()) {
212 dbgOpenGL <<
"OpenGL context cannot be created";
215 if (!context.isValid()) {
216 dbgOpenGL <<
"OpenGL context is not valid while checking Qt's OpenGL status";
219 if (!context.makeCurrent(&surface)) {
220 dbgOpenGL <<
"OpenGL context cannot be made current";
228 dbgOpenGL <<
"Failed to create an OpenGL context with requested color space. Requested:" << format.colorSpace() <<
"Actual:" << context.format().colorSpace();
232 if (format.redBufferSize() > 0 && format.greenBufferSize() > 0 && format.blueBufferSize() > 0
233 && (context.format().redBufferSize() != format.redBufferSize()
234 || context.format().greenBufferSize() != format.greenBufferSize()
235 || context.format().blueBufferSize() != format.blueBufferSize())) {
237 dbgOpenGL <<
"Failed to create an OpenGL context with requested bit depth. Requested:" << format.redBufferSize()
238 <<
"Actual:" << context.format().redBufferSize();
259 QSurfaceFormat *format)
267 format->setRedBufferSize(10);
268 format->setGreenBufferSize(10);
269 format->setBlueBufferSize(10);
270 format->setAlphaBufferSize(2);
274 format->setRedBufferSize(16);
275 format->setGreenBufferSize(16);
276 format->setBlueBufferSize(16);
277 format->setAlphaBufferSize(16);
281 format->setRedBufferSize(8);
282 format->setGreenBufferSize(8);
283 format->setBlueBufferSize(8);
284 format->setAlphaBufferSize(8);
294 qWarning() <<
"WARNING: Bt.2020 PQ surface type is not supported by this build of Krita";
297 qWarning() <<
"WARNING: scRGB surface type is not supported by this build of Krita";
303 if (rootSurfaceFormat.second == 10) {
304 format->setRedBufferSize(10);
305 format->setGreenBufferSize(10);
306 format->setBlueBufferSize(10);
307 format->setAlphaBufferSize(2);
311 format->setRedBufferSize(8);
312 format->setGreenBufferSize(8);
313 format->setBlueBufferSize(8);
314 format->setAlphaBufferSize(8);
328 format.redBufferSize() == 10 &&
329 format.greenBufferSize() == 10 &&
330 format.blueBufferSize() == 10 &&
331 format.alphaBufferSize() == 2;
335 format.redBufferSize() == 16 &&
336 format.greenBufferSize() == 16 &&
337 format.blueBufferSize() == 16 &&
338 format.alphaBufferSize() == 16;
340 return isBt2020PQ || isBt709G10;
369 if (!context.isValid()) {
373 QOpenGLFunctions *funcs = context.functions();
377 m_vendorString = QString(
reinterpret_cast<const char *
>(funcs->glGetString(GL_VENDOR)));
378 m_shadingLanguageString = QString(
reinterpret_cast<const char *
>(funcs->glGetString(GL_SHADING_LANGUAGE_VERSION)));
384 m_supportsFBO = context.functions()->hasOpenGLFeature(QOpenGLFunctions::Framebuffers);
388 context.hasExtension(
"GL_OES_mapbuffer") ||
389 context.hasExtension(
"GL_EXT_map_buffer_range") ||
390 context.hasExtension(
"GL_ARB_map_buffer_range");
394 context.hasExtension(
"GL_ARB_invalidate_subdata"));
395 m_supportsLod = context.format().majorVersion() >= 3 || (
m_isOpenGLES && context.hasExtension(
"GL_EXT_shader_texture_lod"));
398 if (QApplication::platformName() ==
"xcb") {
399 QPlatformNativeInterface *native = qApp->platformNativeInterface();
400 if (native->nativeResourceFunctionForContext(
"eglcontext")) {
402 }
else if (native->nativeResourceFunctionForContext(
"glxcontext")) {
405 qWarning() <<
"WARNING: Failed to detect QXcbGlIntegration type!";
float value(const T *src, size_t ch)
Q_GLOBAL_STATIC(KisStoragePluginRegistry, s_instance)
@ PRIMARIES_ITU_R_BT_2020_2_AND_2100_0
std::optional< KisOpenGL::XcbGLProviderProtocol > m_xcbGlProviderProtocol
QString rendererString() const
bool m_supportsBufferInvalidation
bool m_supportsBufferMapping
Result(QOpenGLContext &context)
QSet< QByteArray > m_extensions
QString m_driverVersionString
QString driverVersionString() const
QString m_shadingLanguageString
bool m_supportsDeprecatedFunctions
static KisOpenGLModeProber * instance()
boost::optional< Result > probeFormat(const KisOpenGL::RendererConfig &rendererConfig, bool adjustGlobalState=true)
const KoColorProfile * rootSurfaceColorProfile() const
QSurfaceFormat surfaceformatInUse() const
static bool isFormatHDR(const QSurfaceFormat &format)
static void initSurfaceFormatFromConfig(std::pair< KisSurfaceColorSpaceWrapper, int > rootSurfaceFormat, QSurfaceFormat *format)
static QString angleRendererToString(KisOpenGL::AngleRenderer renderer)
static bool fuzzyCompareColorSpaces(const KisSurfaceColorSpaceWrapper &lhs, const KisSurfaceColorSpaceWrapper &rhs)
static constexpr KisSurfaceColorSpaceWrapper makeSCRGBColorSpace()
static KisSurfaceColorSpaceWrapper fromQtColorSpace(const QColorSpace &colorSpace)
static constexpr KisSurfaceColorSpaceWrapper makeBt2020PQColorSpace()
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
AngleRenderer angleRenderer
OpenGLRenderer rendererId() const
The KoColorProfileQuery struct.
std::optional< double > hdrReferenceWhite
CICP-compatible enum value representing the transfer function.
static KoColorSpaceRegistry * instance()
const KoColorProfile * profileFor(const KoColorProfileQuery &query, const bool generate=true) const
profileFor tries to find the profile that matches these characteristics, if no such profile is found,...
const KoColorProfile * p709G10Profile() const
const KoColorProfile * p709SRGBProfile() const