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< XcbGLProviderProtocolxcbGlProviderProtocol ()
 

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 490 of file kis_opengl.cpp.

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

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

◆ convertOpenGLRendererToConfig()

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

Definition at line 474 of file kis_opengl.cpp.

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

References RendererDesktopGL, RendererNone, RendererOpenGLES, and RendererSoftware.

◆ currentDriver()

QString KisOpenGL::currentDriver ( )
static

Definition at line 345 of file kis_opengl.cpp.

346{
347 initialize();
348 if (openGLCheckResult) {
349 return openGLCheckResult->driverVersionString();
350 }
351 return QString();
352}
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 392 of file kis_opengl.cpp.

393{
394 initialize();
395 return g_forceDisableTextureBuffers;
396}

References initialize().

◆ getCurrentOpenGLRenderer()

KisOpenGL::OpenGLRenderer KisOpenGL::getCurrentOpenGLRenderer ( )
static

Definition at line 444 of file kis_opengl.cpp.

445{
446 if (!openGLCheckResult) return RendererAuto;
447 return getRendererFromProbeResult(*openGLCheckResult);
448}

References RendererAuto.

◆ getDebugText()

const QString & KisOpenGL::getDebugText ( )
static

Definition at line 331 of file kis_opengl.cpp.

332{
333 initialize();
334 return g_debugText;
335}

References initialize().

◆ getOpenGLWarnings()

QStringList KisOpenGL::getOpenGLWarnings ( )
static

Definition at line 337 of file kis_opengl.cpp.

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

◆ getQtPreferredOpenGLRenderer()

KisOpenGL::OpenGLRenderer KisOpenGL::getQtPreferredOpenGLRenderer ( )
static

Definition at line 450 of file kis_opengl.cpp.

451{
452 return g_rendererPreferredByQt;
453}

◆ getSupportedOpenGLRenderers()

KisOpenGL::OpenGLRenderers KisOpenGL::getSupportedOpenGLRenderers ( )
static

Definition at line 455 of file kis_opengl.cpp.

456{
457 return g_supportedRenderers;
458}

◆ getUserPreferredOpenGLRendererConfig()

KisOpenGL::OpenGLRenderer KisOpenGL::getUserPreferredOpenGLRendererConfig ( )
static

Definition at line 460 of file kis_opengl.cpp.

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

References convertConfigToOpenGLRenderer().

◆ glInvalidateBufferData()

void KisOpenGL::glInvalidateBufferData ( uint buffer)
static

Definition at line 439 of file kis_opengl.cpp.

440{
441 g_glInvalidateBufferData(buffer);
442}

◆ hasOpenGL()

bool KisOpenGL::hasOpenGL ( )
static

Check for OpenGL.

Definition at line 1210 of file kis_opengl.cpp.

1211{
1212 return openGLCheckResult->isSupportedVersion();
1213}

◆ hasOpenGL3()

bool KisOpenGL::hasOpenGL3 ( )
static

Definition at line 362 of file kis_opengl.cpp.

363{
364 initialize();
365 return openGLCheckResult && openGLCheckResult->hasOpenGL3();
366}

References initialize().

◆ hasOpenGLES()

bool KisOpenGL::hasOpenGLES ( )
static

Definition at line 374 of file kis_opengl.cpp.

375{
376 initialize();
377 return openGLCheckResult && openGLCheckResult->isOpenGLES();
378}

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 137 of file kis_opengl.cpp.

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

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

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 423 of file kis_opengl.cpp.

424{
425 initialize();
426 return g_needsFenceWorkaround;
427}

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 908 of file kis_opengl.cpp.

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

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

References value().

◆ setDefaultSurfaceConfig()

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

Definition at line 1189 of file kis_opengl.cpp.

1190{
1191 KIS_SAFE_ASSERT_RECOVER_NOOP(!g_sanityDefaultFormatIsSet);
1192
1193 g_sanityDefaultFormatIsSet = true;
1194 QSurfaceFormat::setDefaultFormat(config.format);
1195
1196 if (config.format.renderableType() == QSurfaceFormat::OpenGLES) {
1197 QCoreApplication::setAttribute(Qt::AA_UseOpenGLES, true);
1198#ifdef Q_OS_WIN
1199 if (!qEnvironmentVariableIsSet("QT_ANGLE_PLATFORM")) {
1200 // Force ANGLE to use Direct3D11. D3D9 doesn't support OpenGL ES 3 and WARP
1201 // might get weird crashes atm.
1202 qputenv("QT_ANGLE_PLATFORM", KisOpenGLModeProber::angleRendererToString(config.angleRenderer).toLatin1());
1203 }
1204#endif
1205 } else if (config.format.renderableType() == QSurfaceFormat::OpenGL) {
1206 QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL, true);
1207 }
1208}
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 467 of file kis_opengl.cpp.

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

References convertOpenGLRendererToConfig().

◆ shouldUseTextureBuffers()

bool KisOpenGL::shouldUseTextureBuffers ( bool userPreference)
static

Definition at line 398 of file kis_opengl.cpp.

399{
400 initialize();
401 return !g_forceDisableTextureBuffers && userPreference;
402}

References initialize().

◆ supportsBufferMapping()

bool KisOpenGL::supportsBufferMapping ( )
static

Definition at line 386 of file kis_opengl.cpp.

387{
388 initialize();
389 return openGLCheckResult && openGLCheckResult->supportsBufferMapping();
390}

References initialize().

◆ supportsFenceSync()

bool KisOpenGL::supportsFenceSync ( )
static

supportsFilter

Returns
True if OpenGL provides fence sync methods.

Definition at line 380 of file kis_opengl.cpp.

381{
382 initialize();
383 return openGLCheckResult && openGLCheckResult->supportsFenceSync();
384}

References initialize().

◆ supportsLoD()

bool KisOpenGL::supportsLoD ( )
static

Definition at line 356 of file kis_opengl.cpp.

357{
358 initialize();
359 return openGLCheckResult && openGLCheckResult->supportsLoD();
360}

References initialize().

◆ supportsVAO()

bool KisOpenGL::supportsVAO ( )
static

Definition at line 368 of file kis_opengl.cpp.

369{
370 initialize();
371 return openGLCheckResult && openGLCheckResult->supportsVAO();
372}

References initialize().

◆ testingInitializeDefaultSurfaceFormat()

void KisOpenGL::testingInitializeDefaultSurfaceFormat ( )
static

Definition at line 429 of file kis_opengl.cpp.

430{
432}
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 411 of file kis_opengl.cpp.

412{
413 initialize();
414 return openGLCheckResult && openGLCheckResult->supportsFBO();
415}

References initialize().

◆ useTextureBufferInvalidation()

bool KisOpenGL::useTextureBufferInvalidation ( )
static

Definition at line 404 of file kis_opengl.cpp.

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

References initialize().

◆ xcbGlProviderProtocol()

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

Definition at line 417 of file kis_opengl.cpp.

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

References initialize().


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