10#include <boost/optional.hpp>
14#include <QOpenGLContext>
15#include <QOpenGLDebugLogger>
16#include <QOpenGLFunctions>
18#include <QApplication>
20#include <QPixmapCache>
25#include <QStandardPaths>
28#include <QRegularExpression>
32#include <klocalizedstring.h>
44#include <config-hdr.h>
45#include <config-use-surface-color-management-api.h>
48# define GL_RENDERER 0x1F01
51#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
54#if !defined APIENTRYP && defined GL_APIENTRYP
55#define APIENTRYP GL_APIENTRYP
58typedef void (APIENTRYP PFNGLINVALIDATEBUFFERDATAPROC) (GLuint buffer);
60typedef void (QOPENGLF_APIENTRYP PFNGLINVALIDATEBUFFERDATAPROC) (GLuint buffer);
66 bool g_isDebugSynchronous =
false;
68 bool g_sanityDefaultFormatIsSet =
false;
70 boost::optional<KisOpenGLModeProber::Result> openGLCheckResult;
72 bool g_needsFenceWorkaround =
false;
74 QString g_surfaceFormatDetectionLog;
75 QString g_debugText(
"OpenGL Info\n **OpenGL not initialized**");
79 using DetectedRenderer = std::tuple<QString, QString, bool>;
81 KisOpenGL::OpenGLRenderers g_supportedRenderers;
84 bool g_useBufferInvalidation =
false;
85 PFNGLINVALIDATEBUFFERDATAPROC g_glInvalidateBufferData =
nullptr;
87 bool g_forceDisableTextureBuffers =
false;
90 g_supportedRenderers = supportedRenderers;
91 g_rendererPreferredByQt = preferredByQt;
94 void appendOpenGLWarningString(KLocalizedString warning)
96 g_openglWarningStrings << warning;
101 g_openglWarningStrings = warnings;
104 void openglOnMessageLogged(
const QOpenGLDebugMessage& debugMessage) {
105 qDebug() <<
"OpenGL:" << debugMessage;
115 if (rendererString.contains(
"basic render driver") ||
116 rendererString.contains(
"software")) {
130 if (openGLCheckResult)
return;
135 config.
format = QSurfaceFormat::defaultFormat();
142 if (!qEnvironmentVariableIsSet(
"KRITA_UNLOCK_TEXTURE_BUFFERS") &&
143 openGLCheckResult->rendererString().toUpper().contains(
"ANGLE")) {
159 g_forceDisableTextureBuffers =
true;
160 appendOpenGLWarningString(
161 ki18n(
"Texture buffers are explicitly disabled on ANGLE renderer due "
162 "to performance issues."));
168 QDebug debugOut(&g_debugText);
169 debugOut <<
"OpenGL Info\n";
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();
180 QDebugStateSaver saver(debugOut);
181 debugOut.nospace() <<
"\n GL version: " << openGLCheckResult->glMajorVersion() <<
"."
182 << openGLCheckResult->glMinorVersion();
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:";
191 QDebugStateSaver saver(debugOut);
192 Q_FOREACH (
const QByteArray &i, openGLCheckResult->extensions()) {
193 debugOut.noquote() <<
"\n " << QString::fromLatin1(i);
198 debugOut <<
"\n\nQPA OpenGL Detection Info";
199 debugOut <<
"\n supportsDesktopGL:" << bool(g_supportedRenderers &
RendererDesktopGL);
201 debugOut <<
"\n supportsAngleD3D11:" << bool(g_supportedRenderers &
RendererOpenGLES);
202 debugOut <<
"\n isQtPreferAngle:" << bool(g_rendererPreferredByQt ==
RendererOpenGLES);
204 debugOut <<
"\n supportsOpenGLES:" << bool(g_supportedRenderers &
RendererOpenGLES);
205 debugOut <<
"\n isQtPreferOpenGLES:" << bool(g_rendererPreferredByQt ==
RendererOpenGLES);
207 debugOut <<
"\n Detected renderers:";
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) <<
") ";
222 dbgOpenGL.noquote().nospace() << g_debugText;
225 if (!openGLCheckResult) {
231 bool isOnX11 =
false;
238 g_useBufferInvalidation = cfg.
readEntry(
"useBufferInvalidation",
false);
242 g_needsFenceWorkaround =
true;
258 const qreal devicePixelRatio = QGuiApplication::primaryScreen()->devicePixelRatio();
259 const QSize screenSize = QGuiApplication::primaryScreen()->size() * devicePixelRatio;
260 const int minCacheSize = 20 * 1024;
263 const int cacheSize = 2048 + 5 * 4 * screenSize.width() * screenSize.height() / 1024;
265 QPixmapCache::setCacheLimit(qMax(minCacheSize, cacheSize));
274 const bool isDebugEnabled = ctx->format().testOption(QSurfaceFormat::DebugContext);
276 dbgUI <<
"OpenGL: Opening new context";
277 if (isDebugEnabled) {
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.")));
288 qDebug() <<
"QOpenGLDebugLogger cannot be initialized.";
294 QSurfaceFormat format = ctx->format();
295 QOpenGLFunctions *f = ctx->functions();
296 f->initializeOpenGLFunctions();
298 if (openGLCheckResult->supportsBufferInvalidation()) {
299 QOpenGLContext *ctx = QOpenGLContext::currentContext();
300 g_glInvalidateBufferData = (PFNGLINVALIDATEBUFFERDATAPROC)ctx->getProcAddress(
"glInvalidateBufferData");
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());
308 log.write(openGLCheckResult->rendererString().toLatin1());
310 QString version((
const char*)f->glGetString(GL_VERSION));
311 log.write(version.toLatin1());
323 Q_FOREACH (
const KLocalizedString &item, g_openglWarningStrings) {
324 strings << item.toString();
332 if (openGLCheckResult) {
333 return openGLCheckResult->driverVersionString();
343 return openGLCheckResult && openGLCheckResult->supportsLoD();
349 return openGLCheckResult && openGLCheckResult->hasOpenGL3();
355 return openGLCheckResult && openGLCheckResult->supportsVAO();
361 return openGLCheckResult && openGLCheckResult->isOpenGLES();
367 return openGLCheckResult && openGLCheckResult->supportsFenceSync();
373 return openGLCheckResult && openGLCheckResult->supportsBufferMapping();
379 return g_forceDisableTextureBuffers;
385 return !g_forceDisableTextureBuffers && userPreference;
391 return g_useBufferInvalidation &&
392 openGLCheckResult && openGLCheckResult->supportsBufferInvalidation();
398 return openGLCheckResult && openGLCheckResult->supportsFBO();
404 return g_needsFenceWorkaround;
414 g_isDebugSynchronous =
value;
419 g_glInvalidateBufferData(buffer);
425 return getRendererFromProbeResult(*openGLCheckResult);
430 return g_rendererPreferredByQt;
435 return g_supportedRenderers;
440 const QString configPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);
441 QSettings kritarc(configPath + QStringLiteral(
"/kritadisplayrc"), QSettings::IniFormat);
447 const QString configPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);
448 QSettings kritarc(configPath + QStringLiteral(
"/kritadisplayrc"), QSettings::IniFormat);
456 return QStringLiteral(
"none");
458 return QStringLiteral(
"software");
460 return QStringLiteral(
"desktop");
462 return QStringLiteral(
"angle");
464 return QStringLiteral(
"auto");
470 if (renderer ==
"desktop") {
472 }
else if (renderer ==
"angle") {
474 }
else if (renderer ==
"software") {
476 }
else if (renderer ==
"none") {
487 if (
format.renderableType() == QSurfaceFormat::OpenGLES &&
492 }
else if (
format.renderableType() == QSurfaceFormat::OpenGLES) {
496 }
else if (
format.renderableType() == QSurfaceFormat::OpenGL) {
498 }
else if (
format.renderableType() == QSurfaceFormat::DefaultRenderableType &&
510typedef std::pair<QSurfaceFormat::RenderableType, KisOpenGL::AngleRenderer> RendererInfo;
514 RendererInfo info = {QSurfaceFormat::DefaultRenderableType,
537QOpenGLContext::OpenGLModuleType determineOpenGLImplementation(
const RendererInfo &info)
539 switch (info.first) {
540 case QSurfaceFormat::OpenGLES:
541#if defined(Q_OS_WINDOWS)
543 switch (info.second) {
547 return QOpenGLContext::LibGLES;
552 return QOpenGLContext::LibGL;
556 return QOpenGLContext::LibGLES;
558 case QSurfaceFormat::DefaultRenderableType:
561 return QOpenGLContext::LibGL;
564#if defined(QT_OPENGL_ES_2)
565 return QOpenGLContext::LibGLES;
567 return QOpenGLContext::LibGL;
570 case QSurfaceFormat::OpenGL:
575 return QOpenGLContext::LibGL;
580 std::pair<KisSurfaceColorSpaceWrapper, int> rootSurfaceFormat,
582 bool inhibitCompatibilityProfile)
584 RendererInfo info = getRendererInfo(renderer);
590 dbgOpenGL <<
"Requesting configuration for" << info.first << info.second;
591 dbgOpenGL <<
"Requesting root surface format" << rootSurfaceFormat;
593 QSurfaceFormat &format = config.
format;
594 const auto openGLModuleType = determineOpenGLImplementation(info);
595 switch (openGLModuleType) {
596 case QOpenGLContext::LibGL:
597#if defined Q_OS_MACOS
598 format.setVersion(4, 1);
599 format.setProfile(QSurfaceFormat::CoreProfile);
605 format.setVersion(3, 3);
609 if (!inhibitCompatibilityProfile) {
610 format.setProfile(QSurfaceFormat::CompatibilityProfile);
616 format.setOptions(QSurfaceFormat::DeprecatedFunctions);
620 case QOpenGLContext::LibGLES:
621 format.setVersion(3, 0);
622 format.setProfile(QSurfaceFormat::NoProfile);
626 dbgOpenGL <<
"Version selected:" << openGLModuleType << format.version();
628 format.setDepthBufferSize(24);
629 format.setStencilBufferSize(8);
633 format.setRenderableType(info.first);
634 format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
635 format.setSwapInterval(0);
639 format.setSwapInterval(1);
642 format.setOption(QSurfaceFormat::DebugContext,
true);
648bool isOpenGLRendererBlacklisted(
const QString &rendererString,
649 const QString &driverVersionString,
652 bool isBlacklisted =
false;
654 Q_UNUSED(rendererString);
655 Q_UNUSED(driverVersionString);
656 Q_UNUSED(warningMessage);
663 if (rendererString.startsWith(
"Intel")) {
664 KLocalizedString knownBadIntelWarning = ki18n(
"The Intel graphics driver in use is known to have issues with OpenGL.");
665 KLocalizedString grossIntelWarning = ki18n(
666 "Intel graphics drivers tend to have issues with OpenGL so ANGLE will be used by default. "
667 "You may manually switch to OpenGL but it is not guaranteed to work properly."
669 QRegularExpression regex(
"\\b\\d{1,2}\\.\\d{1,2}\\.(\\d{1,3})\\.(\\d{4})\\b");
670 QRegularExpressionMatch match = regex.match(driverVersionString);
671 if (match.hasMatch()) {
672 const int thirdPart = match.captured(1).toInt();
673 const int fourthPart = match.captured(2).toInt();
675 if (thirdPart >= 100) {
676 driverBuild = thirdPart * 10000 + fourthPart;
678 driverBuild = fourthPart;
680 qDebug() <<
"Detected Intel driver build number as" << driverBuild;
681 if (driverBuild > 4636 && driverBuild < 4729) {
686 qDebug() <<
"Detected Intel driver build between 4636 and 4729, making ANGLE the preferred renderer";
687 isBlacklisted =
true;
688 *warningMessage << knownBadIntelWarning;
689 }
else if (driverBuild == 4358) {
692 qDebug() <<
"Detected Intel driver build 4358, making ANGLE the preferred renderer";
693 isBlacklisted =
true;
694 *warningMessage << knownBadIntelWarning;
699 qDebug() <<
"Detected Intel driver with unknown version format, making ANGLE the preferred renderer";
700 isBlacklisted =
true;
701 *warningMessage << grossIntelWarning;
705 return isBlacklisted;
708boost::optional<bool> orderPreference(
bool lhs,
bool rhs)
710 if (lhs == rhs)
return boost::none;
711 if (lhs && !rhs)
return true;
712 if (!lhs && rhs)
return false;
716#define ORDER_BY(lhs, rhs) if (auto res = orderPreference((lhs), (rhs))) { return *res; }
718class FormatPositionLess
733 isPreferredColorSpace(rhs.
format));
743 rhs.
rendererId() == m_preferredRendererByUser);
752 rhs.
rendererId() == m_preferredRendererByHDR);
762 rhs.
format.redBufferSize() == m_userPreferredBitDepth);
770 m_preferredColorSpace = preferredColorSpace;
774 m_preferredRendererByQt = preferredRendererByQt;
778 m_preferredRendererByUser = preferredRendererByUser;
782 m_preferredRendererByHDR = preferredRendererByHDR;
785 void setOpenGLBlacklisted(
bool openGLBlacklisted) {
786 m_openGLBlacklisted = openGLBlacklisted;
789 void setOpenGLESBlacklisted(
bool openGLESBlacklisted) {
790 m_openGLESBlacklisted = openGLESBlacklisted;
793 void setUserPreferredBitDepth(
int value) {
794 m_userPreferredBitDepth =
value;
797 bool isOpenGLBlacklisted()
const {
798 return m_openGLBlacklisted;
801 bool isOpenGLESBlacklisted()
const {
802 return m_openGLESBlacklisted;
806 return m_preferredColorSpace;
810 return m_preferredRendererByUser;
813 int userPreferredBitDepth()
const {
814 return m_userPreferredBitDepth;
818 bool isHDRFormat(
const QSurfaceFormat &f)
const {
844 bool doPreferHDR()
const {
853 bool isPreferredColorSpace(
const QSurfaceFormat & surfaceFormat)
const {
855 m_preferredColorSpace,
864 bool m_openGLBlacklisted =
false;
865 bool m_openGLESBlacklisted =
false;
866 int m_userPreferredBitDepth = 8;
869struct DetectionDebug :
public QDebug
871 DetectionDebug(QString *
string)
874 m_originalSize(string->
size())
876 ~DetectionDebug() {
dbgOpenGL << m_string->right(m_string->size() - m_originalSize); *
this << Qt::endl; }
883#define dbgDetection() DetectionDebug(&g_surfaceFormatDetectionLog)
892 using Info = boost::optional<KisOpenGLModeProber::Result>;
894 QHash<OpenGLRenderer, Info> renderersToTest;
904 auto makeDefaultSurfaceFormatPair = [] () -> std::pair<KisSurfaceColorSpaceWrapper, int> {
909 std::vector<std::pair<KisSurfaceColorSpaceWrapper, int>> formatSymbolPairs(
916#elif KRITA_USE_SURFACE_COLOR_MANAGEMENT_API
917 std::vector<std::pair<KisSurfaceColorSpaceWrapper, int>> formatSymbolPairs(
923 std::vector<std::pair<KisSurfaceColorSpaceWrapper, int>> formatSymbolPairs(
929 bool shouldInhibitCompatibilityProfile =
false;
931 makeDefaultSurfaceFormatPair(),
933 shouldInhibitCompatibilityProfile);
946 dbgOpenGL <<
"Failed to probe default Qt's openGL format.. Trying DesktopGL with compatibility enabled...";
947 shouldInhibitCompatibilityProfile =
false;
949 makeDefaultSurfaceFormatPair(),
951 shouldInhibitCompatibilityProfile);
956 dbgOpenGL <<
"Failed again.. Trying DesktopGL with compatibility disabled...";
957 shouldInhibitCompatibilityProfile =
true;
959 makeDefaultSurfaceFormatPair(),
961 shouldInhibitCompatibilityProfile);
966 dbgOpenGL <<
"Failed again.. Trying OpenGLES...";
967 shouldInhibitCompatibilityProfile =
false;
969 makeDefaultSurfaceFormatPair(),
981 makeDefaultSurfaceFormatPair(),
983 shouldInhibitCompatibilityProfile);
993 dbgOpenGL <<
"Failed to probe default openGL format! No openGL support will be available in Krita";
997 const OpenGLRenderer defaultRenderer = getRendererFromProbeResult(*info);
1010 FormatPositionLess compareOp;
1011 compareOp.setPreferredRendererByQt(preferredAutoRenderer);
1014 compareOp.setPreferredColorSpace(
1019 Q_UNUSED(preferredRootSurfaceFormat);
1026 compareOp.setPreferredRendererByUser(preferredRenderer);
1027 compareOp.setOpenGLESBlacklisted(
false);
1029#if KRITA_USE_SURFACE_COLOR_MANAGEMENT_API
1033 Q_UNUSED(preferredCanvasSurfaceBitMode)
1036 renderersToTest[defaultRenderer] = info;
1038 for (
auto it = renderersToTest.begin(); it != renderersToTest.end(); ++it) {
1039 Info info = it.value();
1042 const RendererConfig config = generateSurfaceConfig(it.key(), makeDefaultSurfaceFormatPair(),
false, shouldInhibitCompatibilityProfile);
1048 dbgOpenGL <<
"Already probed:" << it.key();
1051 compareOp.setOpenGLBlacklisted(
1053 isOpenGLRendererBlacklisted(info->rendererString(),
1054 info->driverVersionString(),
1058 dbgOpenGL <<
"Result:" << info->rendererString() << info->driverVersionString()
1059 << info->isSupportedVersion();
1063 g_detectedRenderers << std::make_tuple(info->rendererString(),
1064 info->driverVersionString(),
1065 info->isSupportedVersion());
1068 if (info && info->isSupportedVersion()) {
1069 supportedRenderers |= it.key();
1077 compareOp.isOpenGLBlacklisted()) {
1083 compareOp.isOpenGLESBlacklisted()) {
1089 for (
auto it = renderersToTest.begin(); it != renderersToTest.end(); ++it) {
1091 if (!it.value())
continue;
1093 Q_FOREACH (
const auto &formatPair, formatSymbolPairs) {
1094 preferredConfigs << generateSurfaceConfig(it.key(), formatPair, enableDebug, shouldInhibitCompatibilityProfile);
1098 std::stable_sort(preferredConfigs.begin(), preferredConfigs.end(), compareOp);
1100 dbgDetection() <<
"Supported renderers:" << supportedRenderers;
1115 if (info && info->isSupportedVersion()) {
1122 if (info->isUsingAngle() &&
1123 info->rendererString().contains(
"Direct3D9", Qt::CaseInsensitive)) {
1125 dbgDetection() <<
"Skipping Direct3D 9 Angle implementation, it shouldn't have happened.";
1134 resultConfig = config;
1140 const bool colorSpaceIsCorrect =
1144 const bool rendererIsCorrect =
1146 compareOp.preferredRendererByUser() == resultConfig.
rendererId();
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");
1156 resultConfig.
format = QSurfaceFormat();
1160 overrideSupportedRenderers(supportedRenderers, preferredByQt);
1161 overrideOpenGLWarningString(warningMessages);
1163 return resultConfig;
1170 g_sanityDefaultFormatIsSet =
true;
1171 QSurfaceFormat::setDefaultFormat(config.
format);
1173 if (config.
format.renderableType() == QSurfaceFormat::OpenGLES) {
1174 QCoreApplication::setAttribute(Qt::AA_UseOpenGLES,
true);
1176 if (!qEnvironmentVariableIsSet(
"QT_ANGLE_PLATFORM")) {
1182 }
else if (config.
format.renderableType() == QSurfaceFormat::OpenGL) {
1183 QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL,
true);
1189 return openGLCheckResult->isSupportedVersion();
float value(const T *src, size_t ch)
@ ASSISTANTS_DRAW_MODE_LARGE_PIXMAP_CACHE
bool forceOpenGLFenceWorkaround(bool defaultValue=false) const
T readEntry(const QString &name, const T &defaultValue=T())
CanvasSurfaceBitDepthMode
AssistantsDrawMode assistantsDrawMode(bool defaultValue=false) const
QString rendererString() const
static KisOpenGLModeProber * instance()
boost::optional< Result > probeFormat(const KisOpenGL::RendererConfig &rendererConfig, bool adjustGlobalState=true)
static void initSurfaceFormatFromConfig(std::pair< KisSurfaceColorSpaceWrapper, int > rootSurfaceFormat, QSurfaceFormat *format)
static QString angleRendererToString(KisOpenGL::AngleRenderer renderer)
static bool fuzzyCompareColorSpaces(const KisSurfaceColorSpaceWrapper &lhs, const KisSurfaceColorSpaceWrapper &rhs)
static bool useFBOForToolOutlineRendering()
supportsRenderToFBO
static OpenGLRenderer getCurrentOpenGLRenderer()
static bool hasOpenGLES()
static RendererConfig selectSurfaceConfig(KisOpenGL::OpenGLRenderer preferredRenderer, KisConfig::RootSurfaceFormat preferredRootSurfaceFormat, KisConfig::CanvasSurfaceBitDepthMode preferredCanvasSurfaceBitMode, bool enableDebug)
static bool shouldUseTextureBuffers(bool userPreference)
static bool needsFenceWorkaround()
static void testingInitializeDefaultSurfaceFormat()
static OpenGLRenderers getSupportedOpenGLRenderers()
static bool useTextureBufferInvalidation()
static QStringList getOpenGLWarnings()
static void initialize()
Request OpenGL version 3.2.
static void glInvalidateBufferData(uint buffer)
static bool hasOpenGL()
Check for OpenGL.
static bool supportsLoD()
static QString currentDriver()
static void initializeContext(QOpenGLContext *ctx)
Initialize shared OpenGL context.
static OpenGLRenderer getUserPreferredOpenGLRendererConfig()
static OpenGLRenderer getQtPreferredOpenGLRenderer()
static OpenGLRenderer convertConfigToOpenGLRenderer(QString renderer)
static bool supportsFenceSync()
supportsFilter
static bool supportsBufferMapping()
static bool forceDisableTextureBuffers()
static void setDebugSynchronous(bool value)
static QString convertOpenGLRendererToConfig(OpenGLRenderer renderer)
static void setDefaultSurfaceConfig(const RendererConfig &config)
static bool supportsVAO()
static const QString & getDebugText()
static void setUserPreferredOpenGLRendererConfig(OpenGLRenderer renderer)
static constexpr KisSurfaceColorSpaceWrapper makeSCRGBColorSpace()
static KisSurfaceColorSpaceWrapper fromQtColorSpace(const QColorSpace &colorSpace)
static constexpr KisSurfaceColorSpaceWrapper makeBt2020PQColorSpace()
static void writeSysInfo(const QString &message)
Writes to the system information file and Krita log.
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
typedef void(QOPENGLF_APIENTRYP PFNGLINVALIDATEBUFFERDATAPROC)(GLuint buffer)
#define ORDER_BY(lhs, rhs)
int size(const Forest< T > &forest)
AngleRenderer angleRenderer
OpenGLRenderer rendererId() const