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

#include <kis_opengl.h>

Classes

struct  RendererConfig
 

Public Types

enum  AngleRenderer { AngleRendererDefault = 0x0000 , AngleRendererD3d11 = 0x0002 , AngleRendererD3d9 = 0x0004 , AngleRendererD3d11Warp = 0x0008 }
 
enum  FilterMode { NearestFilterMode , BilinearFilterMode , TrilinearFilterMode , HighQualityFiltering }
 
enum  OpenGLRenderer {
  RendererNone = 0x00 , RendererAuto = 0x01 , RendererDesktopGL = 0x02 , RendererOpenGLES = 0x04 ,
  RendererSoftware = 0x08
}
 
enum  XcbGLProviderProtocol { XCB_GLX = 0 , XCB_EGL }
 

Static Public Member Functions

static OpenGLRenderer convertConfigToOpenGLRenderer (QString renderer)
 
static QString convertOpenGLRendererToConfig (OpenGLRenderer renderer)
 
static QString currentDriver ()
 
static bool forceDisableTextureBuffers ()
 
static OpenGLRenderer getCurrentOpenGLRenderer ()
 
static const QString & getDebugText ()
 
static QStringList getOpenGLWarnings ()
 
static OpenGLRenderer getQtPreferredOpenGLRenderer ()
 
static OpenGLRenderers getSupportedOpenGLRenderers ()
 
static OpenGLRenderer getUserPreferredOpenGLRendererConfig ()
 
static void glInvalidateBufferData (uint buffer)
 
static bool hasOpenGL ()
 Check for OpenGL.
 
static bool hasOpenGL3 ()
 
static bool hasOpenGLES ()
 
static void initialize ()
 Request OpenGL version 3.2.
 
static void initializeContext (QOpenGLContext *ctx)
 Initialize shared OpenGL context.
 
static bool needsFenceWorkaround ()
 
static RendererConfig selectSurfaceConfig (KisOpenGL::OpenGLRenderer preferredRenderer, KisConfig::RootSurfaceFormat preferredRootSurfaceFormat, KisConfig::CanvasSurfaceBitDepthMode preferredCanvasSurfaceBitMode, bool enableDebug)
 
static void setDebugSynchronous (bool value)
 
static void setDefaultSurfaceConfig (const RendererConfig &config)
 
static void setUserPreferredOpenGLRendererConfig (OpenGLRenderer renderer)
 
static bool shouldUseTextureBuffers (bool userPreference)
 
static bool supportsBufferMapping ()
 
static bool supportsFenceSync ()
 supportsFilter
 
static bool supportsLoD ()
 
static bool supportsVAO ()
 
static void testingInitializeDefaultSurfaceFormat ()
 
static bool useFBOForToolOutlineRendering ()
 supportsRenderToFBO
 
static bool useTextureBufferInvalidation ()
 
static std::optional< XcbGLProviderProtocol > xcbGlProviderProtocol ()
 

Private Member Functions

 KisOpenGL ()
 

Static Private Member Functions

static void fakeInitWindowsOpenGL (KisOpenGL::OpenGLRenderers supportedRenderers, KisOpenGL::OpenGLRenderer preferredByQt)
 

Detailed Description

This class manages a shared OpenGL context and provides utility functions for checking capabilities and error reporting.

Definition at line 30 of file kis_opengl.h.

Member Enumeration Documentation

◆ AngleRenderer

Enumerator
AngleRendererDefault 
AngleRendererD3d11 
AngleRendererD3d9 
AngleRendererD3d11Warp 

Definition at line 49 of file kis_opengl.h.

49 {
50 AngleRendererDefault = 0x0000,
51 AngleRendererD3d11 = 0x0002,
52 AngleRendererD3d9 = 0x0004,
53 AngleRendererD3d11Warp = 0x0008, // "Windows Advanced Rasterization Platform"
54 };
@ AngleRendererD3d11Warp
Definition kis_opengl.h:53
@ AngleRendererD3d11
Definition kis_opengl.h:51
@ AngleRendererD3d9
Definition kis_opengl.h:52
@ AngleRendererDefault
Definition kis_opengl.h:50

◆ FilterMode

Enumerator
NearestFilterMode 
BilinearFilterMode 
TrilinearFilterMode 
HighQualityFiltering 

Definition at line 33 of file kis_opengl.h.

33 {
34 NearestFilterMode, // nearest
35 BilinearFilterMode, // linear, no mipmap
36 TrilinearFilterMode, // LINEAR_MIPMAP_LINEAR
37 HighQualityFiltering // Mipmaps + custom shader
38 };
@ NearestFilterMode
Definition kis_opengl.h:34
@ HighQualityFiltering
Definition kis_opengl.h:37
@ BilinearFilterMode
Definition kis_opengl.h:35
@ TrilinearFilterMode
Definition kis_opengl.h:36

◆ OpenGLRenderer

Enumerator
RendererNone 
RendererAuto 
RendererDesktopGL 
RendererOpenGLES 
RendererSoftware 

Definition at line 40 of file kis_opengl.h.

40 {
41 RendererNone = 0x00,
42 RendererAuto = 0x01,
43 RendererDesktopGL = 0x02,
44 RendererOpenGLES = 0x04,
45 RendererSoftware = 0x08
46 };
@ RendererSoftware
Definition kis_opengl.h:45
@ RendererDesktopGL
Definition kis_opengl.h:43
@ RendererOpenGLES
Definition kis_opengl.h:44

◆ XcbGLProviderProtocol

Enumerator
XCB_GLX 
XCB_EGL 

Definition at line 63 of file kis_opengl.h.

63 {
64 XCB_GLX = 0,
66 };

Constructor & Destructor Documentation

◆ KisOpenGL()

KisOpenGL::KisOpenGL ( )
private

Member Function Documentation

◆ convertConfigToOpenGLRenderer()

KisOpenGL::OpenGLRenderer KisOpenGL::convertConfigToOpenGLRenderer ( QString renderer)
static

Definition at line 492 of file kis_opengl.cpp.

493{
494 if (renderer == "desktop") {
495 return RendererDesktopGL;
496 } else if (renderer == "angle") {
497 return RendererOpenGLES;
498 } else if (renderer == "software") {
499 return RendererSoftware;
500 } else if (renderer == "none") {
501 return RendererNone;
502 } else {
503 return RendererAuto;
504 }
505}

References RendererAuto, RendererDesktopGL, RendererNone, RendererOpenGLES, and RendererSoftware.

◆ convertOpenGLRendererToConfig()

QString KisOpenGL::convertOpenGLRendererToConfig ( KisOpenGL::OpenGLRenderer renderer)
static

Definition at line 476 of file kis_opengl.cpp.

477{
478 switch (renderer) {
479 case RendererNone:
480 return QStringLiteral("none");
481 case RendererSoftware:
482 return QStringLiteral("software");
484 return QStringLiteral("desktop");
485 case RendererOpenGLES:
486 return QStringLiteral("angle");
487 default:
488 return QStringLiteral("auto");
489 }
490}

References RendererDesktopGL, RendererNone, RendererOpenGLES, and RendererSoftware.

◆ currentDriver()

QString KisOpenGL::currentDriver ( )
static

Definition at line 347 of file kis_opengl.cpp.

348{
349 initialize();
350 if (openGLCheckResult) {
351 return openGLCheckResult->driverVersionString();
352 }
353 return QString();
354}
static void initialize()
Request OpenGL version 3.2.

References initialize().

◆ fakeInitWindowsOpenGL()

static void KisOpenGL::fakeInitWindowsOpenGL ( KisOpenGL::OpenGLRenderers supportedRenderers,
KisOpenGL::OpenGLRenderer preferredByQt )
staticprivate

◆ forceDisableTextureBuffers()

bool KisOpenGL::forceDisableTextureBuffers ( )
static

Definition at line 394 of file kis_opengl.cpp.

395{
396 initialize();
397 return g_forceDisableTextureBuffers;
398}

References initialize().

◆ getCurrentOpenGLRenderer()

KisOpenGL::OpenGLRenderer KisOpenGL::getCurrentOpenGLRenderer ( )
static

Definition at line 446 of file kis_opengl.cpp.

447{
448 if (!openGLCheckResult) return RendererAuto;
449 return getRendererFromProbeResult(*openGLCheckResult);
450}

References RendererAuto.

◆ getDebugText()

const QString & KisOpenGL::getDebugText ( )
static

Definition at line 333 of file kis_opengl.cpp.

334{
335 initialize();
336 return g_debugText;
337}

References initialize().

◆ getOpenGLWarnings()

QStringList KisOpenGL::getOpenGLWarnings ( )
static

Definition at line 339 of file kis_opengl.cpp.

339 {
340 QStringList strings;
341 Q_FOREACH (const KLocalizedString &item, g_openglWarningStrings) {
342 strings << item.toString();
343 }
344 return strings;
345}

◆ getQtPreferredOpenGLRenderer()

KisOpenGL::OpenGLRenderer KisOpenGL::getQtPreferredOpenGLRenderer ( )
static

Definition at line 452 of file kis_opengl.cpp.

453{
454 return g_rendererPreferredByQt;
455}

◆ getSupportedOpenGLRenderers()

KisOpenGL::OpenGLRenderers KisOpenGL::getSupportedOpenGLRenderers ( )
static

Definition at line 457 of file kis_opengl.cpp.

458{
459 return g_supportedRenderers;
460}

◆ getUserPreferredOpenGLRendererConfig()

KisOpenGL::OpenGLRenderer KisOpenGL::getUserPreferredOpenGLRendererConfig ( )
static

Definition at line 462 of file kis_opengl.cpp.

463{
464 const QString configPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);
465 QSettings kritarc(configPath + QStringLiteral("/kritadisplayrc"), QSettings::IniFormat);
466 return convertConfigToOpenGLRenderer(kritarc.value("OpenGLRenderer", "auto").toString());
467}
static OpenGLRenderer convertConfigToOpenGLRenderer(QString renderer)

References convertConfigToOpenGLRenderer().

◆ glInvalidateBufferData()

void KisOpenGL::glInvalidateBufferData ( uint buffer)
static

Definition at line 441 of file kis_opengl.cpp.

442{
443 g_glInvalidateBufferData(buffer);
444}

◆ hasOpenGL()

bool KisOpenGL::hasOpenGL ( )
static

Check for OpenGL.

Definition at line 1212 of file kis_opengl.cpp.

1213{
1214 return openGLCheckResult->isSupportedVersion();
1215}

◆ hasOpenGL3()

bool KisOpenGL::hasOpenGL3 ( )
static

Definition at line 364 of file kis_opengl.cpp.

365{
366 initialize();
367 return openGLCheckResult && openGLCheckResult->hasOpenGL3();
368}

References initialize().

◆ hasOpenGLES()

bool KisOpenGL::hasOpenGLES ( )
static

Definition at line 376 of file kis_opengl.cpp.

377{
378 initialize();
379 return openGLCheckResult && openGLCheckResult->isOpenGLES();
380}

References initialize().

◆ initialize()

void KisOpenGL::initialize ( )
static

Request OpenGL version 3.2.

The large pixmap cache workaround was originally added to fix the bug 361709 and later extended to all GPU/OS configurations. This setting is still left here in case anyone finds the cached method performing better that the direct drawing of assistants onto the canvas.

See bugs: https://bugs.kde.org/show_bug.cgi?id=361709 https://bugs.kde.org/show_bug.cgi?id=401940

Definition at line 139 of file kis_opengl.cpp.

140{
141 if (openGLCheckResult) return;
142
143 KIS_SAFE_ASSERT_RECOVER_NOOP(g_sanityDefaultFormatIsSet);
144
146 config.format = QSurfaceFormat::defaultFormat();
147
148 openGLCheckResult =
150
151#ifdef Q_OS_WIN
152
153 if (!qEnvironmentVariableIsSet("KRITA_UNLOCK_TEXTURE_BUFFERS") &&
154 openGLCheckResult->rendererString().toUpper().contains("ANGLE")) {
155
156 // Angle should always be openGLES...
158
170 g_forceDisableTextureBuffers = true;
171 appendOpenGLWarningString(
172 ki18n("Texture buffers are explicitly disabled on ANGLE renderer due "
173 "to performance issues."));
174 }
175#endif
176
177
178 g_debugText.clear();
179 QDebug debugOut(&g_debugText);
180 debugOut << "OpenGL Info\n";
181
182 if (openGLCheckResult) {
183 debugOut << "\n Qt Platform Name: " << QGuiApplication::platformName();
184 if (openGLCheckResult->xcbGlProviderProtocol()) {
185 debugOut << "\n Qt XCB GL integration plugin: "
186 << (*openGLCheckResult->xcbGlProviderProtocol() == KisOpenGL::XCB_EGL ? "xcb_egl" : "xcb_glx");
187 }
188 debugOut << "\n Vendor: " << openGLCheckResult->vendorString();
189 debugOut << "\n Renderer: " << openGLCheckResult->rendererString();
190 debugOut << "\n Driver version: " << openGLCheckResult->driverVersionString();
191 debugOut << "\n Shading language: " << openGLCheckResult->shadingLanguageString();
192 debugOut << "\n Requested format: " << QSurfaceFormat::defaultFormat();
193 debugOut << "\n Current format: " << openGLCheckResult->format();
194 {
195 QDebugStateSaver saver(debugOut);
196 debugOut.nospace() << "\n GL version: " << openGLCheckResult->glMajorVersion() << "."
197 << openGLCheckResult->glMinorVersion();
198 }
199 debugOut << "\n Supports deprecated functions" << openGLCheckResult->supportsDeprecatedFunctions();
200 debugOut << "\n Is OpenGL ES:" << openGLCheckResult->isOpenGLES();
201 debugOut << "\n supportsBufferMapping:" << openGLCheckResult->supportsBufferMapping();
202 debugOut << "\n supportsBufferInvalidation:" << openGLCheckResult->supportsBufferInvalidation();
203 debugOut << "\n forceDisableTextureBuffers:" << g_forceDisableTextureBuffers;
204 debugOut << "\n Extensions:";
205 {
206 QDebugStateSaver saver(debugOut);
207 Q_FOREACH (const QByteArray &i, openGLCheckResult->extensions()) {
208 debugOut.noquote() << "\n " << QString::fromLatin1(i);
209 }
210 }
211 }
212
213 debugOut << "\n\nQPA OpenGL Detection Info";
214 debugOut << "\n supportsDesktopGL:" << bool(g_supportedRenderers & RendererDesktopGL);
215#ifdef Q_OS_WIN
216 debugOut << "\n supportsAngleD3D11:" << bool(g_supportedRenderers & RendererOpenGLES);
217 debugOut << "\n isQtPreferAngle:" << bool(g_rendererPreferredByQt == RendererOpenGLES);
218#else
219 debugOut << "\n supportsOpenGLES:" << bool(g_supportedRenderers & RendererOpenGLES);
220 debugOut << "\n isQtPreferOpenGLES:" << bool(g_rendererPreferredByQt == RendererOpenGLES);
221#endif
222 debugOut << "\n Detected renderers:";
223 {
224 QDebugStateSaver saver(debugOut);
225 Q_FOREACH (const DetectedRenderer &x, g_detectedRenderers) {
226 debugOut.noquote().nospace() << "\n " << (std::get<2>(x) ? "(Supported)" : "(Unsupported)") << " "
227 << std::get<0>(x) << " (" << std::get<1>(x) << ") ";
228 }
229 }
230
231// debugOut << "\n== log ==\n";
232// debugOut.noquote();
233// debugOut << g_surfaceFormatDetectionLog;
234// debugOut.resetFormat();
235// debugOut << "\n== end log ==";
236
237 dbgOpenGL.noquote().nospace() << g_debugText;
238 KisUsageLogger::writeSysInfo(g_debugText);
239
240 if (!openGLCheckResult) {
241 return;
242 }
243
244
245 // Check if we have a bugged driver that needs fence workaround
246 bool isOnX11 = false;
247#ifdef HAVE_X11
248 isOnX11 = true;
249#endif
250
251 KisConfig cfg(true);
252
253 g_useBufferInvalidation = cfg.readEntry("useBufferInvalidation", false);
254 KisUsageLogger::writeSysInfo(QString("\nuseBufferInvalidation (config option): %1\n").arg(g_useBufferInvalidation ? "true" : "false"));
255
256 if ((isOnX11 && openGLCheckResult->rendererString().startsWith("AMD")) || cfg.forceOpenGLFenceWorkaround()) {
257 g_needsFenceWorkaround = true;
258 }
259
272 if (cfg.assistantsDrawMode() == KisConfig::ASSISTANTS_DRAW_MODE_LARGE_PIXMAP_CACHE) {
273 const qreal devicePixelRatio = QGuiApplication::primaryScreen()->devicePixelRatio();
274 const QSize screenSize = QGuiApplication::primaryScreen()->size() * devicePixelRatio;
275 const int minCacheSize = 20 * 1024;
276
277 // reserve space for at least 4 textures
278 const int cacheSize = 2048 + 5 * 4 * screenSize.width() * screenSize.height() / 1024; // KiB
279
280 QPixmapCache::setCacheLimit(qMax(minCacheSize, cacheSize));
281 }
282}
@ ASSISTANTS_DRAW_MODE_LARGE_PIXMAP_CACHE
Definition kis_config.h:874
static KisOpenGLModeProber * instance()
boost::optional< Result > probeFormat(const KisOpenGL::RendererConfig &rendererConfig, bool adjustGlobalState=true)
static bool hasOpenGLES()
static void writeSysInfo(const QString &message)
Writes to the system information file and Krita log.
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:130
#define dbgOpenGL
Definition kis_debug.h:63
QSurfaceFormat format
Definition kis_opengl.h:57

References KisConfig::ASSISTANTS_DRAW_MODE_LARGE_PIXMAP_CACHE, KisConfig::assistantsDrawMode(), dbgOpenGL, KisConfig::forceOpenGLFenceWorkaround(), KisOpenGL::RendererConfig::format, hasOpenGLES(), KisOpenGLModeProber::instance(), KIS_SAFE_ASSERT_RECOVER_NOOP, KisOpenGLModeProber::probeFormat(), KisConfig::readEntry(), RendererDesktopGL, RendererOpenGLES, KisUsageLogger::writeSysInfo(), and XCB_EGL.

◆ initializeContext()

void KisOpenGL::initializeContext ( QOpenGLContext * ctx)
static

Initialize shared OpenGL context.

Definition at line 284 of file kis_opengl.cpp.

285{
286 KisConfig cfg(true);
287 initialize();
288
289 const bool isDebugEnabled = ctx->format().testOption(QSurfaceFormat::DebugContext);
290
291 dbgUI << "OpenGL: Opening new context";
292 if (isDebugEnabled) {
293 // Passing ctx for ownership management only, not specifying context.
294 // QOpenGLDebugLogger only function on the current active context.
295 // FIXME: Do we need to make sure ctx is the active context?
296 QOpenGLDebugLogger* openglLogger = new QOpenGLDebugLogger(ctx);
297 if (openglLogger->initialize()) {
298 qDebug() << "QOpenGLDebugLogger is initialized. Check whether you get a message below.";
299 QObject::connect(openglLogger, &QOpenGLDebugLogger::messageLogged, &openglOnMessageLogged);
300 openglLogger->startLogging(g_isDebugSynchronous ? QOpenGLDebugLogger::SynchronousLogging : QOpenGLDebugLogger::AsynchronousLogging);
301 openglLogger->logMessage(QOpenGLDebugMessage::createApplicationMessage(QStringLiteral("QOpenGLDebugLogger is logging.")));
302 } else {
303 qDebug() << "QOpenGLDebugLogger cannot be initialized.";
304 delete openglLogger;
305 }
306 }
307
308 // Double check we were given the version we requested
309 QSurfaceFormat format = ctx->format();
310 QOpenGLFunctions *f = ctx->functions();
311 f->initializeOpenGLFunctions();
312
313 if (openGLCheckResult->supportsBufferInvalidation()) {
314 QOpenGLContext *ctx = QOpenGLContext::currentContext();
315 g_glInvalidateBufferData = (PFNGLINVALIDATEBUFFERDATAPROC)ctx->getProcAddress("glInvalidateBufferData");
316 }
317
318 QFile log(QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/krita-opengl.txt");
319 if (log.open(QFile::WriteOnly)) {
320 QString vendor((const char*)f->glGetString(GL_VENDOR));
321 log.write(vendor.toLatin1());
322 log.write(", ");
323 log.write(openGLCheckResult->rendererString().toLatin1());
324 log.write(", ");
325 QString version((const char*)f->glGetString(GL_VERSION));
326 log.write(version.toLatin1());
327 log.close();
328 } else {
329 qWarning() << "Could not open" << log.fileName() << "for writing:" << log.errorString();
330 }
331}
#define dbgUI
Definition kis_debug.h:56

References dbgUI, and initialize().

◆ needsFenceWorkaround()

bool KisOpenGL::needsFenceWorkaround ( )
static

Returns true if we have a driver that has bugged support to sync objects (a fence) and false otherwise.

Definition at line 425 of file kis_opengl.cpp.

426{
427 initialize();
428 return g_needsFenceWorkaround;
429}

References initialize().

◆ selectSurfaceConfig()

KisOpenGL::RendererConfig KisOpenGL::selectSurfaceConfig ( KisOpenGL::OpenGLRenderer preferredRenderer,
KisConfig::RootSurfaceFormat preferredRootSurfaceFormat,
KisConfig::CanvasSurfaceBitDepthMode preferredCanvasSurfaceBitMode,
bool enableDebug )
static

On Windows we always prefer Angle, not what Qt suggests us

Definition at line 910 of file kis_opengl.cpp.

914{
915 QVector<KLocalizedString> warningMessages;
916
917 using Info = boost::optional<KisOpenGLModeProber::Result>;
918
919 QHash<OpenGLRenderer, Info> renderersToTest;
920#ifndef Q_OS_ANDROID
921 renderersToTest.insert(RendererDesktopGL, Info());
922#endif
923 renderersToTest.insert(RendererOpenGLES, Info());
924
925#ifdef Q_OS_WIN
926 renderersToTest.insert(RendererSoftware, Info());
927#endif
928
929 auto makeDefaultSurfaceFormatPair = [] () -> std::pair<KisSurfaceColorSpaceWrapper, int> {
931 };
932
933#if defined HAVE_HDR
934 std::vector<std::pair<KisSurfaceColorSpaceWrapper, int>> formatSymbolPairs(
935 {
936 // TODO: check if we can use real sRGB space here
940 });
941#elif KRITA_USE_SURFACE_COLOR_MANAGEMENT_API
942 std::vector<std::pair<KisSurfaceColorSpaceWrapper, int>> formatSymbolPairs(
943 {
946 });
947#else
948 std::vector<std::pair<KisSurfaceColorSpaceWrapper, int>> formatSymbolPairs(
949 {
951 });
952#endif
953
954 bool shouldInhibitCompatibilityProfile = false;
955 KisOpenGL::RendererConfig defaultConfig = generateSurfaceConfig(KisOpenGL::RendererAuto,
956 makeDefaultSurfaceFormatPair(),
957 false,
958 shouldInhibitCompatibilityProfile);
959 Info info = KisOpenGLModeProber::instance()->probeFormat(defaultConfig);
960
961#ifndef Q_OS_MACOS
962 // When RendererAuto is active, Qt may perform insane things internally,
963 // e.g. switch from OpenGL to OpenGLES automatically. And the presence of
964 // the compatibility profile flag will cause the context creation process
965 // to fail.
966 //
967 // So, here we request an explicit API again to avoid Qt making decisions
968 // for us.
969
970 if (!info) {
971 dbgOpenGL << "Failed to probe default Qt's openGL format.. Trying DesktopGL with compatibility enabled...";
972 shouldInhibitCompatibilityProfile = false;
973 defaultConfig = generateSurfaceConfig(KisOpenGL::RendererDesktopGL,
974 makeDefaultSurfaceFormatPair(),
975 false,
976 shouldInhibitCompatibilityProfile);
977 info = KisOpenGLModeProber::instance()->probeFormat(defaultConfig);
978 }
979
980 if (!info) {
981 dbgOpenGL << "Failed again.. Trying DesktopGL with compatibility disabled...";
982 shouldInhibitCompatibilityProfile = true;
983 defaultConfig = generateSurfaceConfig(KisOpenGL::RendererDesktopGL,
984 makeDefaultSurfaceFormatPair(),
985 false,
986 shouldInhibitCompatibilityProfile);
987 info = KisOpenGLModeProber::instance()->probeFormat(defaultConfig);
988 }
989
990 if (!info) {
991 dbgOpenGL << "Failed again.. Trying OpenGLES...";
992 shouldInhibitCompatibilityProfile = false;
993 defaultConfig = generateSurfaceConfig(KisOpenGL::RendererOpenGLES,
994 makeDefaultSurfaceFormatPair(),
995 false,
996 true);
997 info = KisOpenGLModeProber::instance()->probeFormat(defaultConfig);
998 }
999
1000#endif /* Q_OS_MACOS */
1001
1002#ifdef Q_OS_WIN
1003 if (!info) {
1004 // try software rasterizer (WARP)
1005 defaultConfig = generateSurfaceConfig(KisOpenGL::RendererSoftware,
1006 makeDefaultSurfaceFormatPair(),
1007 false,
1008 shouldInhibitCompatibilityProfile);
1009 info = KisOpenGLModeProber::instance()->probeFormat(defaultConfig);
1010
1011 if (!info) {
1012 renderersToTest.remove(RendererSoftware);
1013 }
1014 }
1015#endif
1016
1017 if (!info) {
1018 dbgOpenGL << "Failed to probe default openGL format! No openGL support will be available in Krita";
1020 }
1021
1022 const OpenGLRenderer defaultRenderer = getRendererFromProbeResult(*info);
1023
1027#ifdef Q_OS_WIN
1028 const OpenGLRenderer preferredAutoRenderer = RendererOpenGLES;
1029#else
1030 const OpenGLRenderer preferredAutoRenderer = defaultRenderer;
1031#endif
1032
1033 OpenGLRenderers supportedRenderers = RendererNone;
1034
1035 FormatPositionLess compareOp;
1036 compareOp.setPreferredRendererByQt(preferredAutoRenderer);
1037
1038#ifdef HAVE_HDR
1039 compareOp.setPreferredColorSpace(
1041 preferredRootSurfaceFormat == KisConfig::BT709_G10 ? KisSurfaceColorSpaceWrapper::scRGBColorSpace :
1042 KisSurfaceColorSpaceWrapper::bt2020PQColorSpace);
1043#else
1044 Q_UNUSED(preferredRootSurfaceFormat);
1045 compareOp.setPreferredColorSpace(KisSurfaceColorSpaceWrapper::sRGBColorSpace);
1046#endif
1047
1048#ifdef Q_OS_WIN
1049 compareOp.setPreferredRendererByHDR(KisOpenGL::RendererOpenGLES);
1050#endif
1051 compareOp.setPreferredRendererByUser(preferredRenderer);
1052 compareOp.setOpenGLESBlacklisted(false); // We cannot blacklist ES drivers atm
1053
1054#if KRITA_USE_SURFACE_COLOR_MANAGEMENT_API
1055 // 10-bit is the default, 8-bit is set explicitly by the user
1056 compareOp.setUserPreferredBitDepth(preferredCanvasSurfaceBitMode == KisConfig::CanvasSurfaceBitDepthMode::Depth8Bit ? 8 : 10);
1057#else
1058 Q_UNUSED(preferredCanvasSurfaceBitMode)
1059#endif
1060
1061 renderersToTest[defaultRenderer] = info;
1062
1063 for (auto it = renderersToTest.begin(); it != renderersToTest.end(); ++it) {
1064 Info info = it.value();
1065
1066 if (!info) {
1067 const RendererConfig config = generateSurfaceConfig(it.key(), makeDefaultSurfaceFormatPair(), false, shouldInhibitCompatibilityProfile);
1068 dbgOpenGL << "Probing" << it.key() << "from default:" << config.format << config.angleRenderer
1069 << config.rendererId();
1071 *it = info;
1072 } else {
1073 dbgOpenGL << "Already probed:" << it.key();
1074 }
1075
1076 compareOp.setOpenGLBlacklisted(
1077 !info ||
1078 isOpenGLRendererBlacklisted(info->rendererString(),
1079 info->driverVersionString(),
1080 &warningMessages));
1081
1082 if (info) {
1083 dbgOpenGL << "Result:" << info->rendererString() << info->driverVersionString()
1084 << info->isSupportedVersion();
1085 }
1086
1087 if (info) {
1088 g_detectedRenderers << std::make_tuple(info->rendererString(),
1089 info->driverVersionString(),
1090 info->isSupportedVersion());
1091 }
1092
1093 if (info && info->isSupportedVersion()) {
1094 supportedRenderers |= it.key();
1095 }
1096 }
1097
1098 OpenGLRenderer preferredByQt = preferredAutoRenderer;
1099
1100 if (preferredByQt == RendererDesktopGL &&
1101 supportedRenderers & RendererDesktopGL &&
1102 compareOp.isOpenGLBlacklisted()) {
1103
1104 preferredByQt = RendererOpenGLES;
1105
1106 } else if (preferredByQt == RendererOpenGLES &&
1107 supportedRenderers & RendererOpenGLES &&
1108 compareOp.isOpenGLESBlacklisted()) {
1109
1110 preferredByQt = RendererDesktopGL;
1111 }
1112
1113 QVector<RendererConfig> preferredConfigs;
1114 for (auto it = renderersToTest.begin(); it != renderersToTest.end(); ++it) {
1115 // if default mode of the renderer doesn't work, then custom won't either
1116 if (!it.value()) continue;
1117
1118 Q_FOREACH (const auto &formatPair, formatSymbolPairs) {
1119 preferredConfigs << generateSurfaceConfig(it.key(), formatPair, enableDebug, shouldInhibitCompatibilityProfile);
1120 }
1121 }
1122
1123 std::stable_sort(preferredConfigs.begin(), preferredConfigs.end(), compareOp);
1124
1125 dbgDetection() << "Supported renderers:" << supportedRenderers;
1126
1127 dbgDetection() << "Surface format preference list:";
1128 Q_FOREACH (const KisOpenGL::RendererConfig &config, preferredConfigs) {
1129 dbgDetection() << "*" << config.format;
1130 dbgDetection() << " " << config.rendererId();
1131 }
1132
1133 KisOpenGL::RendererConfig resultConfig = defaultConfig;
1134
1135 if (preferredRenderer != RendererNone) {
1136 Q_FOREACH (const KisOpenGL::RendererConfig &config, preferredConfigs) {
1137 dbgDetection() <<"Probing format..." << config.format.colorSpace() << config.rendererId();
1138 Info info = KisOpenGLModeProber::instance()->probeFormat(config);
1139
1140 if (info && info->isSupportedVersion()) {
1141
1142#ifdef Q_OS_WIN
1143 // HACK: Block ANGLE with Direct3D9
1144 // Direct3D9 does not give OpenGL ES 3.0
1145 // Some versions of ANGLE returns OpenGL version 3.0 incorrectly
1146
1147 if (info->isUsingAngle() &&
1148 info->rendererString().contains("Direct3D9", Qt::CaseInsensitive)) {
1149
1150 dbgDetection() << "Skipping Direct3D 9 Angle implementation, it shouldn't have happened.";
1151
1152 continue;
1153 }
1154#endif
1155
1156 dbgDetection() << "Found format:" << config.format;
1157 dbgDetection() << " " << config.rendererId();
1158
1159 resultConfig = config;
1160 break;
1161 }
1162 }
1163
1164 {
1165 const bool colorSpaceIsCorrect =
1166 KisOpenGLModeProber::fuzzyCompareColorSpaces(compareOp.preferredColorSpace(),
1167 KisSurfaceColorSpaceWrapper::fromQtColorSpace(resultConfig.format.colorSpace()));
1168
1169 const bool rendererIsCorrect =
1170 compareOp.preferredRendererByUser() == KisOpenGL::RendererAuto ||
1171 compareOp.preferredRendererByUser() == resultConfig.rendererId();
1172
1173 if (!rendererIsCorrect && colorSpaceIsCorrect) {
1174 warningMessages << ki18n("Preferred renderer doesn't support requested surface format. Another renderer has been selected.");
1175 } else if (!colorSpaceIsCorrect) {
1176 warningMessages << ki18n("Preferred output format is not supported by available renderers");
1177 }
1178
1179 }
1180 } else {
1181 resultConfig.format = QSurfaceFormat();
1182 resultConfig.angleRenderer = AngleRendererDefault;
1183 }
1184
1185 overrideSupportedRenderers(supportedRenderers, preferredByQt);
1186 overrideOpenGLWarningString(warningMessages);
1187
1188 return resultConfig;
1189}
static bool fuzzyCompareColorSpaces(const KisSurfaceColorSpaceWrapper &lhs, const KisSurfaceColorSpaceWrapper &rhs)
static KisSurfaceColorSpaceWrapper fromQtColorSpace(const QColorSpace &colorSpace)
#define dbgDetection()
AngleRenderer angleRenderer
Definition kis_opengl.h:58
OpenGLRenderer rendererId() const

References KisOpenGL::RendererConfig::angleRenderer, AngleRendererDefault, KisSurfaceColorSpaceWrapper::bt2020PQColorSpace, KisConfig::BT709_G10, KisConfig::BT709_G22, dbgDetection, dbgOpenGL, KisSurfaceColorSpaceWrapper::DefaultColorSpace, KisConfig::Depth8Bit, KisOpenGL::RendererConfig::format, KisSurfaceColorSpaceWrapper::fromQtColorSpace(), KisOpenGLModeProber::fuzzyCompareColorSpaces(), KisOpenGLModeProber::instance(), KisOpenGLModeProber::probeFormat(), RendererAuto, RendererDesktopGL, KisOpenGL::RendererConfig::rendererId(), RendererNone, RendererOpenGLES, RendererSoftware, KisSurfaceColorSpaceWrapper::scRGBColorSpace, and KisSurfaceColorSpaceWrapper::sRGBColorSpace.

◆ setDebugSynchronous()

void KisOpenGL::setDebugSynchronous ( bool value)
static

Definition at line 436 of file kis_opengl.cpp.

437{
438 g_isDebugSynchronous = value;
439}
float value(const T *src, size_t ch)

References value().

◆ setDefaultSurfaceConfig()

void KisOpenGL::setDefaultSurfaceConfig ( const RendererConfig & config)
static

Definition at line 1191 of file kis_opengl.cpp.

1192{
1193 KIS_SAFE_ASSERT_RECOVER_NOOP(!g_sanityDefaultFormatIsSet);
1194
1195 g_sanityDefaultFormatIsSet = true;
1196 QSurfaceFormat::setDefaultFormat(config.format);
1197
1198 if (config.format.renderableType() == QSurfaceFormat::OpenGLES) {
1199 QCoreApplication::setAttribute(Qt::AA_UseOpenGLES, true);
1200#ifdef Q_OS_WIN
1201 if (!qEnvironmentVariableIsSet("QT_ANGLE_PLATFORM")) {
1202 // Force ANGLE to use Direct3D11. D3D9 doesn't support OpenGL ES 3 and WARP
1203 // might get weird crashes atm.
1204 qputenv("QT_ANGLE_PLATFORM", KisOpenGLModeProber::angleRendererToString(config.angleRenderer).toLatin1());
1205 }
1206#endif
1207 } else if (config.format.renderableType() == QSurfaceFormat::OpenGL) {
1208 QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL, true);
1209 }
1210}
static QString angleRendererToString(KisOpenGL::AngleRenderer renderer)

References KisOpenGL::RendererConfig::angleRenderer, KisOpenGLModeProber::angleRendererToString(), KisOpenGL::RendererConfig::format, and KIS_SAFE_ASSERT_RECOVER_NOOP.

◆ setUserPreferredOpenGLRendererConfig()

void KisOpenGL::setUserPreferredOpenGLRendererConfig ( KisOpenGL::OpenGLRenderer renderer)
static

Definition at line 469 of file kis_opengl.cpp.

470{
471 const QString configPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);
472 QSettings kritarc(configPath + QStringLiteral("/kritadisplayrc"), QSettings::IniFormat);
473 kritarc.setValue("OpenGLRenderer", KisOpenGL::convertOpenGLRendererToConfig(renderer));
474}
static QString convertOpenGLRendererToConfig(OpenGLRenderer renderer)

References convertOpenGLRendererToConfig().

◆ shouldUseTextureBuffers()

bool KisOpenGL::shouldUseTextureBuffers ( bool userPreference)
static

Definition at line 400 of file kis_opengl.cpp.

401{
402 initialize();
403 return !g_forceDisableTextureBuffers && userPreference;
404}

References initialize().

◆ supportsBufferMapping()

bool KisOpenGL::supportsBufferMapping ( )
static

Definition at line 388 of file kis_opengl.cpp.

389{
390 initialize();
391 return openGLCheckResult && openGLCheckResult->supportsBufferMapping();
392}

References initialize().

◆ supportsFenceSync()

bool KisOpenGL::supportsFenceSync ( )
static

supportsFilter

Returns
True if OpenGL provides fence sync methods.

Definition at line 382 of file kis_opengl.cpp.

383{
384 initialize();
385 return openGLCheckResult && openGLCheckResult->supportsFenceSync();
386}

References initialize().

◆ supportsLoD()

bool KisOpenGL::supportsLoD ( )
static

Definition at line 358 of file kis_opengl.cpp.

359{
360 initialize();
361 return openGLCheckResult && openGLCheckResult->supportsLoD();
362}

References initialize().

◆ supportsVAO()

bool KisOpenGL::supportsVAO ( )
static

Definition at line 370 of file kis_opengl.cpp.

371{
372 initialize();
373 return openGLCheckResult && openGLCheckResult->supportsVAO();
374}

References initialize().

◆ testingInitializeDefaultSurfaceFormat()

void KisOpenGL::testingInitializeDefaultSurfaceFormat ( )
static

Definition at line 431 of file kis_opengl.cpp.

432{
434}
static RendererConfig selectSurfaceConfig(KisOpenGL::OpenGLRenderer preferredRenderer, KisConfig::RootSurfaceFormat preferredRootSurfaceFormat, KisConfig::CanvasSurfaceBitDepthMode preferredCanvasSurfaceBitMode, bool enableDebug)
static void setDefaultSurfaceConfig(const RendererConfig &config)

References KisConfig::BT709_G22, KisConfig::DepthAuto, RendererAuto, selectSurfaceConfig(), and setDefaultSurfaceConfig().

◆ useFBOForToolOutlineRendering()

bool KisOpenGL::useFBOForToolOutlineRendering ( )
static

supportsRenderToFBO

Returns
True if OpenGL can render to FBO, used currently for rendering cursor with image overlay fx.

Definition at line 413 of file kis_opengl.cpp.

414{
415 initialize();
416 return openGLCheckResult && openGLCheckResult->supportsFBO();
417}

References initialize().

◆ useTextureBufferInvalidation()

bool KisOpenGL::useTextureBufferInvalidation ( )
static

Definition at line 406 of file kis_opengl.cpp.

407{
408 initialize();
409 return g_useBufferInvalidation &&
410 openGLCheckResult && openGLCheckResult->supportsBufferInvalidation();
411}

References initialize().

◆ xcbGlProviderProtocol()

std::optional< KisOpenGL::XcbGLProviderProtocol > KisOpenGL::xcbGlProviderProtocol ( )
static

Definition at line 419 of file kis_opengl.cpp.

420{
421 initialize();
422 return openGLCheckResult ? openGLCheckResult->xcbGlProviderProtocol() : std::nullopt;
423}

References initialize().


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