10#include <config-hdr.h>
11#include <QApplication>
12#include <QOpenGLContext>
13#include <QOpenGLFunctions>
23#include <qpa/qplatformnativeinterface.h>
26#include <QGlobalStatic>
48 return isFormatHDR(QSurfaceFormat::defaultFormat());
54 QOpenGLContext *sharedContext = QOpenGLContext::globalShareContext();
55 QSurfaceFormat format = sharedContext ? sharedContext->format() : QSurfaceFormat::defaultFormat();
63 const auto surfaceColorSpace =
84struct AppAttributeSetter
86 AppAttributeSetter(Qt::ApplicationAttribute attribute,
bool useOpenGLES)
87 : m_attribute(attribute),
88 m_oldValue(QCoreApplication::testAttribute(attribute))
90 QCoreApplication::setAttribute(attribute, useOpenGLES);
93 ~AppAttributeSetter() {
94 QCoreApplication::setAttribute(m_attribute, m_oldValue);
98 Qt::ApplicationAttribute m_attribute;
99 bool m_oldValue =
false;
102struct SurfaceFormatSetter
104 SurfaceFormatSetter(
const QSurfaceFormat &format)
105 : m_oldFormat(QSurfaceFormat::defaultFormat())
107 QSurfaceFormat::setDefaultFormat(format);
110 ~SurfaceFormatSetter() {
111 QSurfaceFormat::setDefaultFormat(m_oldFormat);
115 QSurfaceFormat m_oldFormat;
119struct EnvironmentSetter
121 EnvironmentSetter(
const QLatin1String &env,
const QString &
value)
124 if (!qEnvironmentVariableIsEmpty(m_env.latin1())) {
125 m_oldValue = qgetenv(env.latin1());
127 if (!
value.isEmpty()) {
128 qputenv(env.latin1(),
value.toLatin1());
130 qunsetenv(env.latin1());
134 ~EnvironmentSetter() {
136 qputenv(m_env.latin1(), (*m_oldValue).toLatin1());
138 qunsetenv(m_env.latin1());
143 const QLatin1String m_env;
144 boost::optional<QString> m_oldValue;
149boost::optional<KisOpenGLModeProber::Result>
151 bool adjustGlobalState)
153 const QSurfaceFormat &format = rendererConfig.
format;
158 QScopedPointer<AppAttributeSetter> sharedContextSetter;
159 QScopedPointer<AppAttributeSetter> glSetter;
160 QScopedPointer<AppAttributeSetter> glesSetter;
161 QScopedPointer<SurfaceFormatSetter> formatSetter;
162 QScopedPointer<EnvironmentSetter> rendererSetter;
163 QScopedPointer<EnvironmentSetter> portalSetter;
164 QScopedPointer<QGuiApplication> application;
167 QByteArray probeAppName(
"krita");
168 char *argv = probeAppName.data();
171 if (adjustGlobalState) {
172 sharedContextSetter.reset(
new AppAttributeSetter(Qt::AA_ShareOpenGLContexts,
false));
174 if (format.renderableType() != QSurfaceFormat::DefaultRenderableType) {
175 glSetter.reset(
new AppAttributeSetter(Qt::AA_UseDesktopOpenGL, format.renderableType() != QSurfaceFormat::OpenGLES));
176 glesSetter.reset(
new AppAttributeSetter(Qt::AA_UseOpenGLES, format.renderableType() == QSurfaceFormat::OpenGLES));
179 if (!qEnvironmentVariableIsSet(
"QT_ANGLE_PLATFORM")) {
182 portalSetter.reset(
new EnvironmentSetter(QLatin1String(
"QT_NO_XDG_DESKTOP_PORTAL"), QLatin1String(
"1")));
183 formatSetter.reset(
new SurfaceFormatSetter(format));
187 const bool runningInKDE = qEnvironmentVariableIsSet(
"KDE_FULL_SESSION");
188 const bool isInAppimage = qEnvironmentVariableIsSet(
"APPIMAGE");
190 if (runningInKDE && !isInAppimage) {
191 QGuiApplication::setDesktopSettingsAware(
false);
194 application.reset(
new QGuiApplication(argc, &argv));
196 if (runningInKDE && !isInAppimage) {
197 QGuiApplication::setDesktopSettingsAware(
true);
203 surface.setFormat(format);
204 surface.setSurfaceType(QSurface::OpenGLSurface);
206 QOpenGLContext context;
207 context.setFormat(format);
210 if (!context.create()) {
211 dbgOpenGL <<
"OpenGL context cannot be created";
214 if (!context.isValid()) {
215 dbgOpenGL <<
"OpenGL context is not valid while checking Qt's OpenGL status";
218 if (!context.makeCurrent(&surface)) {
219 dbgOpenGL <<
"OpenGL context cannot be made current";
227 dbgOpenGL <<
"Failed to create an OpenGL context with requested color space. Requested:" << format.colorSpace() <<
"Actual:" << context.format().colorSpace();
231 if (format.redBufferSize() > 0 && format.greenBufferSize() > 0 && format.blueBufferSize() > 0
232 && (context.format().redBufferSize() != format.redBufferSize()
233 || context.format().greenBufferSize() != format.greenBufferSize()
234 || context.format().blueBufferSize() != format.blueBufferSize())) {
236 dbgOpenGL <<
"Failed to create an OpenGL context with requested bit depth. Requested:" << format.redBufferSize()
237 <<
"Actual:" << context.format().redBufferSize();
258 QSurfaceFormat *format)
266 format->setRedBufferSize(10);
267 format->setGreenBufferSize(10);
268 format->setBlueBufferSize(10);
269 format->setAlphaBufferSize(2);
273 format->setRedBufferSize(16);
274 format->setGreenBufferSize(16);
275 format->setBlueBufferSize(16);
276 format->setAlphaBufferSize(16);
280 format->setRedBufferSize(8);
281 format->setGreenBufferSize(8);
282 format->setBlueBufferSize(8);
283 format->setAlphaBufferSize(8);
293 qWarning() <<
"WARNING: Bt.2020 PQ surface type is not supported by this build of Krita";
296 qWarning() <<
"WARNING: scRGB surface type is not supported by this build of Krita";
302 if (rootSurfaceFormat.second == 10) {
303 format->setRedBufferSize(10);
304 format->setGreenBufferSize(10);
305 format->setBlueBufferSize(10);
306 format->setAlphaBufferSize(2);
310 format->setRedBufferSize(8);
311 format->setGreenBufferSize(8);
312 format->setBlueBufferSize(8);
313 format->setAlphaBufferSize(8);
327 format.redBufferSize() == 10 &&
328 format.greenBufferSize() == 10 &&
329 format.blueBufferSize() == 10 &&
330 format.alphaBufferSize() == 2;
334 format.redBufferSize() == 16 &&
335 format.greenBufferSize() == 16 &&
336 format.blueBufferSize() == 16 &&
337 format.alphaBufferSize() == 16;
339 return isBt2020PQ || isBt709G10;
368 if (!context.isValid()) {
372 QOpenGLFunctions *funcs = context.functions();
376 m_vendorString = QString(
reinterpret_cast<const char *
>(funcs->glGetString(GL_VENDOR)));
377 m_shadingLanguageString = QString(
reinterpret_cast<const char *
>(funcs->glGetString(GL_SHADING_LANGUAGE_VERSION)));
383 m_supportsFBO = context.functions()->hasOpenGLFeature(QOpenGLFunctions::Framebuffers);
387 context.hasExtension(
"GL_OES_mapbuffer") ||
388 context.hasExtension(
"GL_EXT_map_buffer_range") ||
389 context.hasExtension(
"GL_ARB_map_buffer_range");
393 context.hasExtension(
"GL_ARB_invalidate_subdata"));
394 m_supportsLod = context.format().majorVersion() >= 3 || (
m_isOpenGLES && context.hasExtension(
"GL_EXT_shader_texture_lod"));
397 if (QApplication::platformName() ==
"xcb") {
398 QPlatformNativeInterface *native = qApp->platformNativeInterface();
399 if (native->nativeResourceFunctionForContext(
"eglcontext")) {
401 }
else if (native->nativeResourceFunctionForContext(
"glxcontext")) {
404 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