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

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

◆ 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:804
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 904 of file kis_opengl.cpp.

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

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