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

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

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

◆ convertOpenGLRendererToConfig()

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

Definition at line 471 of file kis_opengl.cpp.

472{
473 switch (renderer) {
474 case RendererNone:
475 return QStringLiteral("none");
476 case RendererSoftware:
477 return QStringLiteral("software");
479 return QStringLiteral("desktop");
480 case RendererOpenGLES:
481 return QStringLiteral("angle");
482 default:
483 return QStringLiteral("auto");
484 }
485}

References RendererDesktopGL, RendererNone, RendererOpenGLES, and RendererSoftware.

◆ currentDriver()

QString KisOpenGL::currentDriver ( )
static

Definition at line 342 of file kis_opengl.cpp.

343{
344 initialize();
345 if (openGLCheckResult) {
346 return openGLCheckResult->driverVersionString();
347 }
348 return QString();
349}
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 389 of file kis_opengl.cpp.

390{
391 initialize();
392 return g_forceDisableTextureBuffers;
393}

References initialize().

◆ getCurrentOpenGLRenderer()

KisOpenGL::OpenGLRenderer KisOpenGL::getCurrentOpenGLRenderer ( )
static

Definition at line 441 of file kis_opengl.cpp.

442{
443 if (!openGLCheckResult) return RendererAuto;
444 return getRendererFromProbeResult(*openGLCheckResult);
445}

References RendererAuto.

◆ getDebugText()

const QString & KisOpenGL::getDebugText ( )
static

Definition at line 328 of file kis_opengl.cpp.

329{
330 initialize();
331 return g_debugText;
332}

References initialize().

◆ getOpenGLWarnings()

QStringList KisOpenGL::getOpenGLWarnings ( )
static

Definition at line 334 of file kis_opengl.cpp.

334 {
335 QStringList strings;
336 Q_FOREACH (const KLocalizedString &item, g_openglWarningStrings) {
337 strings << item.toString();
338 }
339 return strings;
340}

◆ getQtPreferredOpenGLRenderer()

KisOpenGL::OpenGLRenderer KisOpenGL::getQtPreferredOpenGLRenderer ( )
static

Definition at line 447 of file kis_opengl.cpp.

448{
449 return g_rendererPreferredByQt;
450}

◆ getSupportedOpenGLRenderers()

KisOpenGL::OpenGLRenderers KisOpenGL::getSupportedOpenGLRenderers ( )
static

Definition at line 452 of file kis_opengl.cpp.

453{
454 return g_supportedRenderers;
455}

◆ getUserPreferredOpenGLRendererConfig()

KisOpenGL::OpenGLRenderer KisOpenGL::getUserPreferredOpenGLRendererConfig ( )
static

Definition at line 457 of file kis_opengl.cpp.

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

References convertConfigToOpenGLRenderer().

◆ glInvalidateBufferData()

void KisOpenGL::glInvalidateBufferData ( uint buffer)
static

Definition at line 436 of file kis_opengl.cpp.

437{
438 g_glInvalidateBufferData(buffer);
439}

◆ hasOpenGL()

bool KisOpenGL::hasOpenGL ( )
static

Check for OpenGL.

Definition at line 1207 of file kis_opengl.cpp.

1208{
1209 return openGLCheckResult->isSupportedVersion();
1210}

◆ hasOpenGL3()

bool KisOpenGL::hasOpenGL3 ( )
static

Definition at line 359 of file kis_opengl.cpp.

360{
361 initialize();
362 return openGLCheckResult && openGLCheckResult->hasOpenGL3();
363}

References initialize().

◆ hasOpenGLES()

bool KisOpenGL::hasOpenGLES ( )
static

Definition at line 371 of file kis_opengl.cpp.

372{
373 initialize();
374 return openGLCheckResult && openGLCheckResult->isOpenGLES();
375}

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 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}
#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 420 of file kis_opengl.cpp.

421{
422 initialize();
423 return g_needsFenceWorkaround;
424}

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

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

432{
433 g_isDebugSynchronous = value;
434}
float value(const T *src, size_t ch)

References value().

◆ setDefaultSurfaceConfig()

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

Definition at line 1186 of file kis_opengl.cpp.

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

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

References convertOpenGLRendererToConfig().

◆ shouldUseTextureBuffers()

bool KisOpenGL::shouldUseTextureBuffers ( bool userPreference)
static

Definition at line 395 of file kis_opengl.cpp.

396{
397 initialize();
398 return !g_forceDisableTextureBuffers && userPreference;
399}

References initialize().

◆ supportsBufferMapping()

bool KisOpenGL::supportsBufferMapping ( )
static

Definition at line 383 of file kis_opengl.cpp.

384{
385 initialize();
386 return openGLCheckResult && openGLCheckResult->supportsBufferMapping();
387}

References initialize().

◆ supportsFenceSync()

bool KisOpenGL::supportsFenceSync ( )
static

supportsFilter

Returns
True if OpenGL provides fence sync methods.

Definition at line 377 of file kis_opengl.cpp.

378{
379 initialize();
380 return openGLCheckResult && openGLCheckResult->supportsFenceSync();
381}

References initialize().

◆ supportsLoD()

bool KisOpenGL::supportsLoD ( )
static

Definition at line 353 of file kis_opengl.cpp.

354{
355 initialize();
356 return openGLCheckResult && openGLCheckResult->supportsLoD();
357}

References initialize().

◆ supportsVAO()

bool KisOpenGL::supportsVAO ( )
static

Definition at line 365 of file kis_opengl.cpp.

366{
367 initialize();
368 return openGLCheckResult && openGLCheckResult->supportsVAO();
369}

References initialize().

◆ testingInitializeDefaultSurfaceFormat()

void KisOpenGL::testingInitializeDefaultSurfaceFormat ( )
static

Definition at line 426 of file kis_opengl.cpp.

427{
429}
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 408 of file kis_opengl.cpp.

409{
410 initialize();
411 return openGLCheckResult && openGLCheckResult->supportsFBO();
412}

References initialize().

◆ useTextureBufferInvalidation()

bool KisOpenGL::useTextureBufferInvalidation ( )
static

Definition at line 401 of file kis_opengl.cpp.

402{
403 initialize();
404 return g_useBufferInvalidation &&
405 openGLCheckResult && openGLCheckResult->supportsBufferInvalidation();
406}

References initialize().

◆ xcbGlProviderProtocol()

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

Definition at line 414 of file kis_opengl.cpp.

415{
416 initialize();
417 return openGLCheckResult ? openGLCheckResult->xcbGlProviderProtocol() : std::nullopt;
418}

References initialize().


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