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
}
 

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

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

Constructor & Destructor Documentation

◆ KisOpenGL()

KisOpenGL::KisOpenGL ( )
private

Member Function Documentation

◆ convertConfigToOpenGLRenderer()

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

Definition at line 468 of file kis_opengl.cpp.

469{
470 if (renderer == "desktop") {
471 return RendererDesktopGL;
472 } else if (renderer == "angle") {
473 return RendererOpenGLES;
474 } else if (renderer == "software") {
475 return RendererSoftware;
476 } else if (renderer == "none") {
477 return RendererNone;
478 } else {
479 return RendererAuto;
480 }
481}

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

◆ convertOpenGLRendererToConfig()

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

Definition at line 452 of file kis_opengl.cpp.

453{
454 switch (renderer) {
455 case RendererNone:
456 return QStringLiteral("none");
457 case RendererSoftware:
458 return QStringLiteral("software");
460 return QStringLiteral("desktop");
461 case RendererOpenGLES:
462 return QStringLiteral("angle");
463 default:
464 return QStringLiteral("auto");
465 }
466}

References RendererDesktopGL, RendererNone, RendererOpenGLES, and RendererSoftware.

◆ currentDriver()

QString KisOpenGL::currentDriver ( )
static

Definition at line 329 of file kis_opengl.cpp.

330{
331 initialize();
332 if (openGLCheckResult) {
333 return openGLCheckResult->driverVersionString();
334 }
335 return QString();
336}
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 376 of file kis_opengl.cpp.

377{
378 initialize();
379 return g_forceDisableTextureBuffers;
380}

References initialize().

◆ getCurrentOpenGLRenderer()

KisOpenGL::OpenGLRenderer KisOpenGL::getCurrentOpenGLRenderer ( )
static

Definition at line 422 of file kis_opengl.cpp.

423{
424 if (!openGLCheckResult) return RendererAuto;
425 return getRendererFromProbeResult(*openGLCheckResult);
426}

References RendererAuto.

◆ getDebugText()

const QString & KisOpenGL::getDebugText ( )
static

Definition at line 315 of file kis_opengl.cpp.

316{
317 initialize();
318 return g_debugText;
319}

References initialize().

◆ getOpenGLWarnings()

QStringList KisOpenGL::getOpenGLWarnings ( )
static

Definition at line 321 of file kis_opengl.cpp.

321 {
322 QStringList strings;
323 Q_FOREACH (const KLocalizedString &item, g_openglWarningStrings) {
324 strings << item.toString();
325 }
326 return strings;
327}

◆ getQtPreferredOpenGLRenderer()

KisOpenGL::OpenGLRenderer KisOpenGL::getQtPreferredOpenGLRenderer ( )
static

Definition at line 428 of file kis_opengl.cpp.

429{
430 return g_rendererPreferredByQt;
431}

◆ getSupportedOpenGLRenderers()

KisOpenGL::OpenGLRenderers KisOpenGL::getSupportedOpenGLRenderers ( )
static

Definition at line 433 of file kis_opengl.cpp.

434{
435 return g_supportedRenderers;
436}

◆ getUserPreferredOpenGLRendererConfig()

KisOpenGL::OpenGLRenderer KisOpenGL::getUserPreferredOpenGLRendererConfig ( )
static

Definition at line 438 of file kis_opengl.cpp.

439{
440 const QString configPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);
441 QSettings kritarc(configPath + QStringLiteral("/kritadisplayrc"), QSettings::IniFormat);
442 return convertConfigToOpenGLRenderer(kritarc.value("OpenGLRenderer", "auto").toString());
443}
static OpenGLRenderer convertConfigToOpenGLRenderer(QString renderer)

References convertConfigToOpenGLRenderer().

◆ glInvalidateBufferData()

void KisOpenGL::glInvalidateBufferData ( uint buffer)
static

Definition at line 417 of file kis_opengl.cpp.

418{
419 g_glInvalidateBufferData(buffer);
420}

◆ hasOpenGL()

bool KisOpenGL::hasOpenGL ( )
static

Check for OpenGL.

Definition at line 1187 of file kis_opengl.cpp.

1188{
1189 return openGLCheckResult->isSupportedVersion();
1190}

◆ hasOpenGL3()

bool KisOpenGL::hasOpenGL3 ( )
static

Definition at line 346 of file kis_opengl.cpp.

347{
348 initialize();
349 return openGLCheckResult && openGLCheckResult->hasOpenGL3();
350}

References initialize().

◆ hasOpenGLES()

bool KisOpenGL::hasOpenGLES ( )
static

Definition at line 358 of file kis_opengl.cpp.

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

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

129{
130 if (openGLCheckResult) return;
131
132 KIS_SAFE_ASSERT_RECOVER_NOOP(g_sanityDefaultFormatIsSet);
133
135 config.format = QSurfaceFormat::defaultFormat();
136
137 openGLCheckResult =
139
140#ifdef Q_OS_WIN
141
142 if (!qEnvironmentVariableIsSet("KRITA_UNLOCK_TEXTURE_BUFFERS") &&
143 openGLCheckResult->rendererString().toUpper().contains("ANGLE")) {
144
145 // Angle should always be openGLES...
147
159 g_forceDisableTextureBuffers = true;
160 appendOpenGLWarningString(
161 ki18n("Texture buffers are explicitly disabled on ANGLE renderer due "
162 "to performance issues."));
163 }
164#endif
165
166
167 g_debugText.clear();
168 QDebug debugOut(&g_debugText);
169 debugOut << "OpenGL Info\n";
170
171 if (openGLCheckResult) {
172 debugOut << "\n Qt Platform Name: " << QGuiApplication::platformName();
173 debugOut << "\n Vendor: " << openGLCheckResult->vendorString();
174 debugOut << "\n Renderer: " << openGLCheckResult->rendererString();
175 debugOut << "\n Driver version: " << openGLCheckResult->driverVersionString();
176 debugOut << "\n Shading language: " << openGLCheckResult->shadingLanguageString();
177 debugOut << "\n Requested format: " << QSurfaceFormat::defaultFormat();
178 debugOut << "\n Current format: " << openGLCheckResult->format();
179 {
180 QDebugStateSaver saver(debugOut);
181 debugOut.nospace() << "\n GL version: " << openGLCheckResult->glMajorVersion() << "."
182 << openGLCheckResult->glMinorVersion();
183 }
184 debugOut << "\n Supports deprecated functions" << openGLCheckResult->supportsDeprecatedFunctions();
185 debugOut << "\n Is OpenGL ES:" << openGLCheckResult->isOpenGLES();
186 debugOut << "\n supportsBufferMapping:" << openGLCheckResult->supportsBufferMapping();
187 debugOut << "\n supportsBufferInvalidation:" << openGLCheckResult->supportsBufferInvalidation();
188 debugOut << "\n forceDisableTextureBuffers:" << g_forceDisableTextureBuffers;
189 debugOut << "\n Extensions:";
190 {
191 QDebugStateSaver saver(debugOut);
192 Q_FOREACH (const QByteArray &i, openGLCheckResult->extensions()) {
193 debugOut.noquote() << "\n " << QString::fromLatin1(i);
194 }
195 }
196 }
197
198 debugOut << "\n\nQPA OpenGL Detection Info";
199 debugOut << "\n supportsDesktopGL:" << bool(g_supportedRenderers & RendererDesktopGL);
200#ifdef Q_OS_WIN
201 debugOut << "\n supportsAngleD3D11:" << bool(g_supportedRenderers & RendererOpenGLES);
202 debugOut << "\n isQtPreferAngle:" << bool(g_rendererPreferredByQt == RendererOpenGLES);
203#else
204 debugOut << "\n supportsOpenGLES:" << bool(g_supportedRenderers & RendererOpenGLES);
205 debugOut << "\n isQtPreferOpenGLES:" << bool(g_rendererPreferredByQt == RendererOpenGLES);
206#endif
207 debugOut << "\n Detected renderers:";
208 {
209 QDebugStateSaver saver(debugOut);
210 Q_FOREACH (const DetectedRenderer &x, g_detectedRenderers) {
211 debugOut.noquote().nospace() << "\n " << (std::get<2>(x) ? "(Supported)" : "(Unsupported)") << " "
212 << std::get<0>(x) << " (" << std::get<1>(x) << ") ";
213 }
214 }
215
216// debugOut << "\n== log ==\n";
217// debugOut.noquote();
218// debugOut << g_surfaceFormatDetectionLog;
219// debugOut.resetFormat();
220// debugOut << "\n== end log ==";
221
222 dbgOpenGL.noquote().nospace() << g_debugText;
223 KisUsageLogger::writeSysInfo(g_debugText);
224
225 if (!openGLCheckResult) {
226 return;
227 }
228
229
230 // Check if we have a bugged driver that needs fence workaround
231 bool isOnX11 = false;
232#ifdef HAVE_X11
233 isOnX11 = true;
234#endif
235
236 KisConfig cfg(true);
237
238 g_useBufferInvalidation = cfg.readEntry("useBufferInvalidation", false);
239 KisUsageLogger::writeSysInfo(QString("\nuseBufferInvalidation (config option): %1\n").arg(g_useBufferInvalidation ? "true" : "false"));
240
241 if ((isOnX11 && openGLCheckResult->rendererString().startsWith("AMD")) || cfg.forceOpenGLFenceWorkaround()) {
242 g_needsFenceWorkaround = true;
243 }
244
257 if (cfg.assistantsDrawMode() == KisConfig::ASSISTANTS_DRAW_MODE_LARGE_PIXMAP_CACHE) {
258 const qreal devicePixelRatio = QGuiApplication::primaryScreen()->devicePixelRatio();
259 const QSize screenSize = QGuiApplication::primaryScreen()->size() * devicePixelRatio;
260 const int minCacheSize = 20 * 1024;
261
262 // reserve space for at least 4 textures
263 const int cacheSize = 2048 + 5 * 4 * screenSize.width() * screenSize.height() / 1024; // KiB
264
265 QPixmapCache::setCacheLimit(qMax(minCacheSize, cacheSize));
266 }
267}
@ ASSISTANTS_DRAW_MODE_LARGE_PIXMAP_CACHE
Definition kis_config.h:800
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, and KisUsageLogger::writeSysInfo().

◆ initializeContext()

void KisOpenGL::initializeContext ( QOpenGLContext * ctx)
static

Initialize shared OpenGL context.

Definition at line 269 of file kis_opengl.cpp.

270{
271 KisConfig cfg(true);
272 initialize();
273
274 const bool isDebugEnabled = ctx->format().testOption(QSurfaceFormat::DebugContext);
275
276 dbgUI << "OpenGL: Opening new context";
277 if (isDebugEnabled) {
278 // Passing ctx for ownership management only, not specifying context.
279 // QOpenGLDebugLogger only function on the current active context.
280 // FIXME: Do we need to make sure ctx is the active context?
281 QOpenGLDebugLogger* openglLogger = new QOpenGLDebugLogger(ctx);
282 if (openglLogger->initialize()) {
283 qDebug() << "QOpenGLDebugLogger is initialized. Check whether you get a message below.";
284 QObject::connect(openglLogger, &QOpenGLDebugLogger::messageLogged, &openglOnMessageLogged);
285 openglLogger->startLogging(g_isDebugSynchronous ? QOpenGLDebugLogger::SynchronousLogging : QOpenGLDebugLogger::AsynchronousLogging);
286 openglLogger->logMessage(QOpenGLDebugMessage::createApplicationMessage(QStringLiteral("QOpenGLDebugLogger is logging.")));
287 } else {
288 qDebug() << "QOpenGLDebugLogger cannot be initialized.";
289 delete openglLogger;
290 }
291 }
292
293 // Double check we were given the version we requested
294 QSurfaceFormat format = ctx->format();
295 QOpenGLFunctions *f = ctx->functions();
296 f->initializeOpenGLFunctions();
297
298 if (openGLCheckResult->supportsBufferInvalidation()) {
299 QOpenGLContext *ctx = QOpenGLContext::currentContext();
300 g_glInvalidateBufferData = (PFNGLINVALIDATEBUFFERDATAPROC)ctx->getProcAddress("glInvalidateBufferData");
301 }
302
303 QFile log(QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/krita-opengl.txt");
304 log.open(QFile::WriteOnly);
305 QString vendor((const char*)f->glGetString(GL_VENDOR));
306 log.write(vendor.toLatin1());
307 log.write(", ");
308 log.write(openGLCheckResult->rendererString().toLatin1());
309 log.write(", ");
310 QString version((const char*)f->glGetString(GL_VERSION));
311 log.write(version.toLatin1());
312 log.close();
313}
#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 401 of file kis_opengl.cpp.

402{
403 initialize();
404 return g_needsFenceWorkaround;
405}

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

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

413{
414 g_isDebugSynchronous = value;
415}
float value(const T *src, size_t ch)

References value().

◆ setDefaultSurfaceConfig()

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

Definition at line 1166 of file kis_opengl.cpp.

1167{
1168 KIS_SAFE_ASSERT_RECOVER_NOOP(!g_sanityDefaultFormatIsSet);
1169
1170 g_sanityDefaultFormatIsSet = true;
1171 QSurfaceFormat::setDefaultFormat(config.format);
1172
1173 if (config.format.renderableType() == QSurfaceFormat::OpenGLES) {
1174 QCoreApplication::setAttribute(Qt::AA_UseOpenGLES, true);
1175#ifdef Q_OS_WIN
1176 if (!qEnvironmentVariableIsSet("QT_ANGLE_PLATFORM")) {
1177 // Force ANGLE to use Direct3D11. D3D9 doesn't support OpenGL ES 3 and WARP
1178 // might get weird crashes atm.
1179 qputenv("QT_ANGLE_PLATFORM", KisOpenGLModeProber::angleRendererToString(config.angleRenderer).toLatin1());
1180 }
1181#endif
1182 } else if (config.format.renderableType() == QSurfaceFormat::OpenGL) {
1183 QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL, true);
1184 }
1185}
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 445 of file kis_opengl.cpp.

446{
447 const QString configPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);
448 QSettings kritarc(configPath + QStringLiteral("/kritadisplayrc"), QSettings::IniFormat);
449 kritarc.setValue("OpenGLRenderer", KisOpenGL::convertOpenGLRendererToConfig(renderer));
450}
static QString convertOpenGLRendererToConfig(OpenGLRenderer renderer)

References convertOpenGLRendererToConfig().

◆ shouldUseTextureBuffers()

bool KisOpenGL::shouldUseTextureBuffers ( bool userPreference)
static

Definition at line 382 of file kis_opengl.cpp.

383{
384 initialize();
385 return !g_forceDisableTextureBuffers && userPreference;
386}

References initialize().

◆ supportsBufferMapping()

bool KisOpenGL::supportsBufferMapping ( )
static

Definition at line 370 of file kis_opengl.cpp.

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

References initialize().

◆ supportsFenceSync()

bool KisOpenGL::supportsFenceSync ( )
static

supportsFilter

Returns
True if OpenGL provides fence sync methods.

Definition at line 364 of file kis_opengl.cpp.

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

References initialize().

◆ supportsLoD()

bool KisOpenGL::supportsLoD ( )
static

Definition at line 340 of file kis_opengl.cpp.

341{
342 initialize();
343 return openGLCheckResult && openGLCheckResult->supportsLoD();
344}

References initialize().

◆ supportsVAO()

bool KisOpenGL::supportsVAO ( )
static

Definition at line 352 of file kis_opengl.cpp.

353{
354 initialize();
355 return openGLCheckResult && openGLCheckResult->supportsVAO();
356}

References initialize().

◆ testingInitializeDefaultSurfaceFormat()

void KisOpenGL::testingInitializeDefaultSurfaceFormat ( )
static

Definition at line 407 of file kis_opengl.cpp.

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

396{
397 initialize();
398 return openGLCheckResult && openGLCheckResult->supportsFBO();
399}

References initialize().

◆ useTextureBufferInvalidation()

bool KisOpenGL::useTextureBufferInvalidation ( )
static

Definition at line 388 of file kis_opengl.cpp.

389{
390 initialize();
391 return g_useBufferInvalidation &&
392 openGLCheckResult && openGLCheckResult->supportsBufferInvalidation();
393}

References initialize().


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