7#if QT_VERSION >= QT_VERSION_CHECK(6,5,0)
8#include <QtEnvironmentVariables>
14#include <QGuiApplication>
17#include "libmythbase/mythconfig.h"
29#define LOC QString("OpenGL: ")
48 : m_textureId(Texture)
89 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"OpenGL is disabled for Remote X Session");
95 bool opengles = !qEnvironmentVariableIsEmpty(
"MYTHTV_OPENGL_ES");
96 bool core = !qEnvironmentVariableIsEmpty(
"MYTHTV_OPENGL_CORE");
97 QSurfaceFormat format = QSurfaceFormat::defaultFormat();
100 format.setProfile(QSurfaceFormat::CoreProfile);
101 format.setMajorVersion(4);
102 format.setMinorVersion(3);
109 format.setProfile(QSurfaceFormat::CoreProfile);
110 format.setMajorVersion(3);
111 format.setMinorVersion(1);
113 format.setRenderableType(QSurfaceFormat::OpenGLES);
117 format.setOption(QSurfaceFormat::DebugContext);
137 LOG(VB_GENERAL, LOG_INFO,
LOC +
"MythRenderOpenGL closing");
151 QString source(
"Unknown");
152 QString
type(
"Unknown");
154 switch (Message.source())
156 case QOpenGLDebugMessage::ApplicationSource:
return;
157 case QOpenGLDebugMessage::APISource: source =
"API";
break;
158 case QOpenGLDebugMessage::WindowSystemSource: source =
"WinSys";
break;
159 case QOpenGLDebugMessage::ShaderCompilerSource: source =
"ShaderComp";
break;
160 case QOpenGLDebugMessage::ThirdPartySource: source =
"3rdParty";
break;
161 case QOpenGLDebugMessage::OtherSource: source =
"Other";
break;
167 switch (Message.type())
169 case QOpenGLDebugMessage::ErrorType:
170 type =
"Error";
break;
171 case QOpenGLDebugMessage::DeprecatedBehaviorType:
172 type =
"Deprecated";
break;
173 case QOpenGLDebugMessage::UndefinedBehaviorType:
174 type =
"Undef behaviour";
break;
175 case QOpenGLDebugMessage::PortabilityType:
176 type =
"Portability";
break;
177 case QOpenGLDebugMessage::PerformanceType:
178 type =
"Performance";
break;
179 case QOpenGLDebugMessage::OtherType:
180 type =
"Other";
break;
181 case QOpenGLDebugMessage::MarkerType:
182 type =
"Marker";
break;
183 case QOpenGLDebugMessage::GroupPushType:
184 type =
"GroupPush";
break;
185 case QOpenGLDebugMessage::GroupPopType:
186 type =
"GroupPop";
break;
189 LOG(VB_GPU, LOG_INFO,
LOC + QString(
"Src: %1 Type: %2 Msg: %3")
190 .arg(source,
type, Message.message()));
197 QOpenGLDebugMessage message = QOpenGLDebugMessage::createApplicationMessage(
198 Message, 0, QOpenGLDebugMessage::NotificationSeverity, QOpenGLDebugMessage::MarkerType);
207 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Context about to be destroyed");
214 LOG(VB_GENERAL, LOG_ERR,
LOC +
"MythRenderOpenGL is not a valid OpenGL rendering context");
219 initializeOpenGLFunctions();
230 QOpenGLDebugLogger::LoggingMode mode = QOpenGLDebugLogger::AsynchronousLogging;
233 if (!qEnvironmentVariableIsEmpty(
"MYTHTV_OPENGL_SYNCHRONOUS"))
234 mode = QOpenGLDebugLogger::SynchronousLogging;
237 if (mode == QOpenGLDebugLogger::AsynchronousLogging)
238 LOG(VB_GENERAL, LOG_INFO,
LOC +
"GPU debug logging started (async)");
240 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Started synchronous GPU debug logging (will hurt performance)");
244 QString filter = qgetenv(
"MYTHTV_OPENGL_LOGFILTER");
245 if (filter.contains(
"other", Qt::CaseInsensitive))
250 if (filter.contains(
"error", Qt::CaseInsensitive))
255 if (filter.contains(
"deprecated", Qt::CaseInsensitive))
258 debug <<
"Deprecated";
260 if (filter.contains(
"undefined", Qt::CaseInsensitive))
263 debug <<
"Undefined";
265 if (filter.contains(
"portability", Qt::CaseInsensitive))
268 debug <<
"Portability";
270 if (filter.contains(
"performance", Qt::CaseInsensitive))
273 debug <<
"Performance";
275 if (filter.contains(
"grouppush", Qt::CaseInsensitive))
278 debug <<
"GroupPush";
280 if (filter.contains(
"grouppop", Qt::CaseInsensitive))
286 if (!
debug.isEmpty())
287 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Filtering out GPU messages for: %1")
288 .arg(
debug.join(
", ")));
292 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Failed to initialise OpenGL logging");
306 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxtexsz);
307 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxunits);
310 QSurfaceFormat fmt = format();
318 if ((isOpenGLES() && hasExtension(
"GL_OES_mapbuffer") && buffer_procs) ||
319 (hasExtension(
"GL_ARB_vertex_buffer_object") && buffer_procs))
323 if (!isOpenGLES() && (hasExtension(
"GL_NV_texture_rectangle") ||
324 hasExtension(
"GL_ARB_texture_rectangle") ||
325 hasExtension(
"GL_EXT_texture_rectangle")))
329 if ((isOpenGLES() && format().majorVersion() < 3) ||
330 (!isOpenGLES() && format().majorVersion() < 2))
335 if (!isOpenGLES() || (isOpenGLES() && ((fmt.majorVersion() >= 3) || hasExtension(
"GL_EXT_unpack_subimage"))))
339 if (fmt.profile() == QSurfaceFormat::OpenGLContextProfile::CoreProfile)
343 extraFunctions()->glGenVertexArrays(1, &
m_vao);
344 extraFunctions()->glBindVertexArray(
m_vao);
354 static const std::array<const QByteArray,3> kTiled {
"videocore",
"vc4",
"v3d" };
355 auto renderer = QByteArray(
reinterpret_cast<const char*
>(glGetString(GL_RENDERER))).toLower();
356 for (
const auto & name : kTiled)
358 if (renderer.contains(name))
366 if (hasExtension(
"GL_NVX_gpu_memory_info"))
373 if (QOpenGLShader::hasOpenGLShaders(QOpenGLShader::Compute))
375 if (QOpenGLShader::hasOpenGLShaders(QOpenGLShader::Geometry))
383 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create default shaders");
387 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Initialised MythRenderOpenGL");
388 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Using %1 range output").arg(
m_fullRange ?
"full" :
"limited"));
394static constexpr QLatin1String
GLYesNo (
bool v)
396 return v ? QLatin1String(
"Yes") : QLatin1String(
"No");
401 QSurfaceFormat fmt = format();
402 QString qtglversion = QString(
"OpenGL%1 %2.%3")
403 .arg(fmt.renderableType() == QSurfaceFormat::OpenGLES ?
"ES" :
"")
404 .arg(fmt.majorVersion()).arg(fmt.minorVersion());
405 QString qtglsurface = QString(
"RGBA: %1:%2:%3:%4 Depth: %5 Stencil: %6")
406 .arg(fmt.redBufferSize()).arg(fmt.greenBufferSize())
407 .arg(fmt.blueBufferSize()).arg(fmt.alphaBufferSize())
408 .arg(fmt.depthBufferSize()).arg(fmt.stencilBufferSize());
409 QStringList shaders {
"None"};
412 shaders = QStringList {
"Vertex",
"Fragment" };
414 shaders <<
"Geometry";
416 shaders <<
"Compute";
418 const QString module = QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL ?
"OpenGL (not ES)" :
"OpenGL ES";
419 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"OpenGL vendor : %1").arg(
reinterpret_cast<const char*
>(glGetString(GL_VENDOR))));
420 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"OpenGL renderer : %1").arg(
reinterpret_cast<const char*
>(glGetString(GL_RENDERER))));
421 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"OpenGL version : %1").arg(
reinterpret_cast<const char*
>(glGetString(GL_VERSION))));
422 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Qt platform : %1").arg(QGuiApplication::platformName()));
424 bool eglfuncs =
IsEGL();
426 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"EGL images : %1").arg(
GLYesNo(eglfuncs)));
428 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Qt OpenGL module : %1").arg(module));
429 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Qt OpenGL format : %1").arg(qtglversion));
430 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Qt OpenGL surface : %1").arg(qtglsurface));
432 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Shaders : %1").arg(shaders.join(
",")));
442 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Warning: Insufficient texture units for some features.");
470 bool recommended =
true;
472 QString renderer =
reinterpret_cast<const char*
>(glGetString(GL_RENDERER));
474 if (!(openGLFeatures() & Shaders))
476 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"OpenGL has no shader support");
479 else if (!(openGLFeatures() & Framebuffers))
481 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"OpenGL has no framebuffer support");
484 else if (renderer.contains(
"Software Rasterizer", Qt::CaseInsensitive))
486 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"OpenGL is using software rasterizer.");
489 else if (renderer.contains(
"softpipe", Qt::CaseInsensitive))
491 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"OpenGL seems to be using software "
492 "fallback. Please check your OpenGL driver installation, "
493 "configuration, and device permissions.");
499 LOG(VB_GENERAL, LOG_INFO,
LOC +
500 "OpenGL not recommended with this system's hardware/drivers.");
513 QOpenGLContext::swapBuffers(
m_window);
528 LOG(VB_GENERAL, LOG_CRIT,
LOC +
"No widget!");
534 QWidget* native = Widget->nativeParentWidget();
540 LOG(VB_GENERAL, LOG_CRIT,
LOC +
"No window surface!");
544#ifdef CONFIG_QTWEBENGINE
545 auto * globalcontext = QOpenGLContext::globalShareContext();
548 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Using global shared OpenGL context");
549 setShareContext(globalcontext);
555 LOG(VB_GENERAL, LOG_CRIT,
LOC +
"Failed to create OpenGLContext!");
559 Widget->setAttribute(Qt::WA_PaintOnScreen);
567 if (!QOpenGLContext::makeCurrent(
m_window))
568 LOG(VB_GENERAL, LOG_ERR,
LOC +
"makeCurrent failed");
577 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Mis-matched calls to makeCurrent()");
617 int32_t tmp = (Red << 24) + (Green << 16) + (Blue << 8) + Alpha;
623 glClearColor(Red / 255.0F, Green / 255.0F, Blue / 255.0F, Alpha / 255.0F);
633 auto *texture =
new QOpenGLTexture(*Image, QOpenGLTexture::DontGenerateMipMaps);
634 if (!texture->textureId())
636 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Failed to create texure");
640 texture->setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear);
641 texture->setWrapMode(QOpenGLTexture::ClampToEdge);
643 result->m_texture = texture;
645 result->m_totalSize =
GetTextureSize(Image->size(), result->m_target != QOpenGLTexture::TargetRectangle);
647 result->m_pixelFormat = QOpenGLTexture::RGBA;
648 result->m_pixelType = QOpenGLTexture::UInt8;
649 result->m_bufferSize =
GetBufferSize(result->m_totalSize, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8);
650 result->m_size = Image->size();
651 result->m_crop =
true;
657 if (((
m_features & NPOTTextures) != 0U) || !Normalised)
662 while (w < Size.width())
664 while (h < Size.height())
686 Texture->
m_texture->setMinMagFilters(Filter, Filter);
691 glTexParameteri(Texture->
m_target, GL_TEXTURE_MIN_FILTER, Filter);
692 glTexParameteri(Texture->
m_target, GL_TEXTURE_MAG_FILTER, Filter);
693 glTexParameteri(Texture->
m_target, GL_TEXTURE_WRAP_S, Wrap);
694 glTexParameteri(Texture->
m_target, GL_TEXTURE_WRAP_T, Wrap);
707 glActiveTexture(ActiveTex);
721 delete [] Texture->
m_data;
722 delete Texture->
m_vbo;
734 QOpenGLFramebufferObject *framebuffer =
nullptr;
737 framebuffer =
new QOpenGLFramebufferObject(Size, QOpenGLFramebufferObject::NoAttachment,
738 GL_TEXTURE_2D, QOpenGLTexture::RGBA16_UNorm);
742 framebuffer =
new QOpenGLFramebufferObject(Size);
744 if (framebuffer->isValid())
746 if (framebuffer->isBound())
754 LOG(VB_GENERAL, LOG_ERR,
"Failed to create framebuffer object");
766 texture->m_size = texture->m_totalSize = Framebuffer->size();
768 texture->m_flip =
false;
789 if (Framebuffer ==
nullptr)
791 QOpenGLFramebufferObject::bindDefault();
805 glClear(GL_COLOR_BUFFER_BIT);
810 QOpenGLShaderProgram *Program,
float TimeVal)
821 Program->setUniformValue(
"u_time", TimeVal);
822 Program->setUniformValue(
"u_alpha",
static_cast<float>(Alpha / 255.0F));
823 Program->setUniformValue(
"u_res", QVector2D(
m_window->width(),
m_window->height()));
824 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
825 QOpenGLBuffer::release(QOpenGLBuffer::VertexBuffer);
831 const QRect
Source,
const QRect Destination,
832 QOpenGLShaderProgram *Program,
int Alpha, qreal Scale)
839 if (Program ==
nullptr)
845 GLenum textarget = Texture->
m_target;
846 Program->setUniformValue(
"s_texture0", 0);
853 QOpenGLBuffer* buffer = Texture->
m_vbo;
859 void* target = buffer->map(QOpenGLBuffer::WriteOnly);
863 static_cast<GLfloat*
>(target));
876 glVertexAttrib4f(
COLOR_INDEX, 1.0F, 1.0F, 1.0F, Alpha / 255.0F);
878 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
881 QOpenGLBuffer::release(QOpenGLBuffer::VertexBuffer);
886 QOpenGLFramebufferObject *Target,
887 const QRect
Source,
const QRect Destination,
888 QOpenGLShaderProgram *Program,
891 if (Textures.empty())
897 if (Program ==
nullptr)
907 for (
uint i = 0; i < Textures.size(); i++)
909 QString uniform = QString(
"s_texture%1").arg(i);
910 Program->setUniformValue(qPrintable(uniform), i);
912 if (Textures[i]->m_texture)
913 Textures[i]->m_texture->bind();
915 glBindTexture(textarget, Textures[i]->m_textureId);
918 QOpenGLBuffer* buffer = first->
m_vbo;
924 void* target = buffer->map(QOpenGLBuffer::WriteOnly);
928 static_cast<GLfloat*
>(target));
943 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
946 QOpenGLBuffer::release(QOpenGLBuffer::VertexBuffer);
962 glVertexAttrib4f(
COLOR_INDEX, color, color, color, Alpha / 255.0F);
967 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
969 QOpenGLBuffer::release(QOpenGLBuffer::VertexBuffer);
975 const QRect Area,
const QBrush &FillBrush,
976 const QPen &LinePen,
int Alpha)
983 const QRect Area,
int CornerRadius,
984 const QBrush &FillBrush,
985 const QPen &LinePen,
int Alpha)
987 bool fill = FillBrush.style() != Qt::NoBrush;
988 bool edge = LinePen.style() != Qt::NoPen;
992 auto SetColor = [&](
const QColor&
Color)
997 Color.blue() / 255.0F, (
Color.alpha() / 255.0F) * (Alpha / 255.0F));
1003 (
Color.alpha() / 255.0F) * (Alpha / 255.0F));
1006 float halfwidth = Area.width() / 2.0F;
1007 float halfheight = Area.height() / 2.0F;
1008 float radius = CornerRadius;
1009 radius = std::max(radius, 1.0F);
1010 radius = std::min(radius, halfwidth);
1011 radius = std::min(radius, halfheight);
1030 SetColor(FillBrush.color());
1033 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1038 float innerradius = radius - LinePen.width();
1039 innerradius = std::max(innerradius, 1.0F);
1044 SetColor(LinePen.color());
1047 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1050 QOpenGLBuffer::release(QOpenGLBuffer::VertexBuffer);
1056 GLsizei Stride,
const GLuint Value)
1058#pragma GCC diagnostic push
1059#pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
1061 glVertexAttribPointer(Index, Size,
Type, Normalize, Stride,
reinterpret_cast<const char *
>(Value));
1062#pragma GCC diagnostic pop
1068 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1069 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1070 glDisable(GL_DEPTH_TEST);
1071 glDepthMask(GL_FALSE);
1072 glDisable(GL_CULL_FACE);
1073 glClearColor(0.0F, 0.0F, 0.0F, 0.0F);
1074 glClear(GL_COLOR_BUFFER_BIT);
1075 QOpenGLFramebufferObject::bindDefault();
1082 static const std::array<const QString,4> kExts {
"",
"ARB",
"EXT",
"OES" };
1083 QFunctionPointer result =
nullptr;
1084 for (
const auto & ext : kExts)
1086 result = getProcAddress((Proc + ext).toLocal8Bit().constData());
1090 if (result ==
nullptr)
1091 LOG(VB_GENERAL, LOG_DEBUG,
LOC + QString(
"Extension not found: %1").arg(Proc));
1098 auto* buffer =
new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
1099 if (buffer->create())
1101 buffer->setUsagePattern(QOpenGLBuffer::StreamDraw);
1103 buffer->allocate(Size);
1105 QOpenGLBuffer::release(QOpenGLBuffer::VertexBuffer);
1122 extraFunctions()->glDeleteVertexArrays(1, &
m_vao);
1142 result.append(tr(
"QPA platform") +
"\t: " + QGuiApplication::platformName());
1143 result.append(tr(
"OpenGL vendor") +
"\t: " +
reinterpret_cast<const char*
>(glGetString(GL_VENDOR)));
1144 result.append(tr(
"OpenGL renderer") +
"\t: " +
reinterpret_cast<const char*
>(glGetString(GL_RENDERER)));
1145 result.append(tr(
"OpenGL version") +
"\t: " +
reinterpret_cast<const char*
>(glGetString(GL_VERSION)));
1146 QSurfaceFormat fmt = format();
1147 result.append(tr(
"Color depth (RGBA)") +
"\t: " + QString(
"%1:%2:%3:%4")
1148 .arg(fmt.redBufferSize()).arg(fmt.greenBufferSize())
1149 .arg(fmt.blueBufferSize()).arg(fmt.alphaBufferSize()));
1154 const QRect Destination,
int Rotation, qreal Scale)
1156 if (!Texture || Texture->
m_size.isEmpty())
1168 QSize size = Texture->
m_size;
1170 int width = Texture->
m_crop ? std::min(
Source.width(), size.width()) :
Source.width();
1171 int height = Texture->
m_crop ? std::min(
Source.height(), size.height()) :
Source.height();
1173 if (Texture->
m_target != QOpenGLTexture::TargetRectangle)
1176 data[(Texture->
m_flip ? 7 : 1) +
TEX_OFFSET] = (
Source.top() + height) /
static_cast<GLfloat
>(size.height());
1177 data[6 +
TEX_OFFSET] = (
Source.left() + width) /
static_cast<GLfloat
>(size.width());
1193 width = Texture->
m_crop ? std::min(
static_cast<int>(width * Scale), Destination.width()) : Destination.width();
1194 height = Texture->
m_crop ? std::min(
static_cast<int>(height * Scale), Destination.height()) : Destination.height();
1196 data[2] = data[0] = Destination.left();
1197 data[5] = data[1] = Destination.top();
1198 data[4] = data[6] = Destination.left() + width;
1199 data[3] = data[7] = Destination.top() + height;
1239 uint64_t ref = (
static_cast<uint64_t
>(Area.left()) & 0xfff) +
1240 ((
static_cast<uint64_t
>(Area.top()) & 0xfff) << 12) +
1241 ((
static_cast<uint64_t
>(Area.width()) & 0xfff) << 24) +
1242 ((
static_cast<uint64_t
>(Area.height()) & 0xfff) << 36) +
1243 ((
static_cast<uint64_t
>(
Type & 0xfff)) << 48);
1252 auto *vertices =
new GLfloat[8];
1254 vertices[2] = vertices[0] = Area.left();
1255 vertices[5] = vertices[1] = Area.top();
1256 vertices[4] = vertices[6] = Area.left() + Area.width();
1257 vertices[3] = vertices[7] = Area.top() + Area.height();
1259 if (
Type == GL_LINE_LOOP)
1261 vertices[7] = vertices[1];
1262 vertices[5] = vertices[3];
1278 GLfloat *vertices =
nullptr;
1288 uint64_t ref = (
static_cast<uint64_t
>(Area.left()) & 0xfff) +
1289 ((
static_cast<uint64_t
>(Area.top()) & 0xfff) << 12) +
1290 ((
static_cast<uint64_t
>(Area.width()) & 0xfff) << 24) +
1291 ((
static_cast<uint64_t
>(Area.height()) & 0xfff) << 36) +
1292 ((
static_cast<uint64_t
>(
Type & 0xfff)) << 48);
1309 void* target = vbo->map(QOpenGLBuffer::WriteOnly);
1343 case QOpenGLTexture::RGBA_Integer:
1344 case QOpenGLTexture::BGRA_Integer:
1345 case QOpenGLTexture::BGRA:
1346 case QOpenGLTexture::RGBA: bpp = 4;
break;
1347 case QOpenGLTexture::RGB_Integer:
1348 case QOpenGLTexture::BGR_Integer:
1349 case QOpenGLTexture::BGR:
1350 case QOpenGLTexture::RGB: bpp = 3;
break;
1351 case QOpenGLTexture::RG_Integer:
1352 case QOpenGLTexture::RG: bpp = 2;
break;
1353 case QOpenGLTexture::Red:
1354 case QOpenGLTexture::Red_Integer:
1355 case QOpenGLTexture::Alpha:
1356 case QOpenGLTexture::Luminance: bpp = 1;
break;
1362 case QOpenGLTexture::Int8:
bytes =
sizeof(GLbyte);
break;
1363 case QOpenGLTexture::UInt8:
bytes =
sizeof(GLubyte);
break;
1364 case QOpenGLTexture::Int16:
bytes =
sizeof(GLshort);
break;
1365 case QOpenGLTexture::UInt16:
bytes =
sizeof(GLushort);
break;
1366 case QOpenGLTexture::Int32:
bytes =
sizeof(GLint);
break;
1367 case QOpenGLTexture::UInt32:
bytes =
sizeof(GLuint);
break;
1368 case QOpenGLTexture::Float32:
bytes =
sizeof(GLfloat);
break;
1369 case QOpenGLTexture::UInt32_RGB10A2:
bytes =
sizeof(GLuint);
break;
1373 if (!bpp || !
bytes || Size.isEmpty())
1376 return Size.width() * Size.height() * bpp *
bytes;
1384 newtop.translate(
static_cast<GLfloat
>(Center.x()),
static_cast<GLfloat
>(Center.y()));
1386 newtop.rotate(Fx.
m_angle, 0, 0, 1);
1387 newtop.translate(
static_cast<GLfloat
>(-Center.x()),
static_cast<GLfloat
>(-Center.y()));
1399 QString
type =
Source.isEmpty() ?
"Shader link" :
"Shader compile";
1400 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"%1 error").arg(
type));
1401 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Log:"));
1402 LOG(VB_GENERAL, LOG_ERR,
"\n" + Shader->log());
1405 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Source:"));
1406 LOG(VB_GENERAL, LOG_ERR,
"\n" +
Source);
1420 auto *program =
new QOpenGLShaderProgram();
1421 if (!program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertex))
1423 if (!program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragment))
1427 QList<QOpenGLShader*> shaders = program->shaders();
1428 for (QOpenGLShader* shader : std::as_const(shaders))
1429 LOG(VB_GENERAL, LOG_DEBUG,
"\n" + shader->sourceCode());
1431 program->bindAttributeLocation(
"a_position",
VERTEX_INDEX);
1432 program->bindAttributeLocation(
"a_color",
COLOR_INDEX);
1433 program->bindAttributeLocation(
"a_texcoord0",
TEXTURE_INDEX);
1434 if (!program->link())
1445 auto *program =
new QOpenGLShaderProgram();
1446 if (!program->addShaderFromSourceCode(QOpenGLShader::Compute,
Source))
1451 QList<QOpenGLShader*> shaders = program->shaders();
1452 for (QOpenGLShader* shader : std::as_const(shaders))
1453 LOG(VB_GENERAL, LOG_DEBUG,
"\n" + shader->sourceCode());
1456 if (!program->link())
1502 QString tag = QString(
"%1-%2").arg(Program->programId()).arg(Uniform);
1506 else if (!qFuzzyCompare(Value, it.value()))
1512 QByteArray uniform(Uniform);
1515 if (uniforms.contains(uniform))
1517 location = uniforms[uniform];
1521 location = Program->uniformLocation(Uniform);
1522 uniforms.insert(uniform, location);
1525 Program->setUniformValue(location, Value);
1559 GLint dedicated = 0;
1560 GLint available = 0;
1564 return { total / 1024, dedicated / 1024, available / 1024 };
1582 QSize size{256, 256};
1591#include "moc_mythrenderopengl.cpp"
void * GetEGLDisplay(void)
MythGLTexture(QOpenGLTexture *Texture)
std::array< GLfloat, 16 > m_vertexData
QOpenGLTexture * m_texture
MythRender * GetRenderDevice()
static MythMainWindow * getMainWindow(bool UseDB=true)
Return the existing main window, or create one.
void ExpireVBOS(int Max=0)
void GetCachedVBO(GLuint Type, QRect Area)
void SetShaderProgramParams(QOpenGLShaderProgram *Program, const QMatrix4x4 &Value, const char *Uniform)
QList< uint64_t > m_vertexExpiry
QOpenGLFunctions::OpenGLFeatures m_features
void SetWidget(QWidget *Widget)
MythGLTexture * CreateTextureFromQImage(QImage *Image)
static constexpr GLuint kVertexSize
static int GetBufferSize(QSize Size, QOpenGLTexture::PixelFormat Format, QOpenGLTexture::PixelType Type)
QOpenGLDebugLogger * m_openglDebugger
void ClearRect(QOpenGLFramebufferObject *Target, QRect Area, int Color, int Alpha)
An optimised method to clear a QRect to the given color.
void ActiveTexture(GLuint ActiveTex)
int GetMaxTextureSize(void) const
void DrawProcedural(QRect Area, int Alpha, QOpenGLFramebufferObject *Target, QOpenGLShaderProgram *Program, float TimeVal)
void DrawRoundRect(QOpenGLFramebufferObject *Target, QRect Area, int CornerRadius, const QBrush &FillBrush, const QPen &LinePen, int Alpha)
void contextToBeDestroyed(void)
QStack< QMatrix4x4 > m_transforms
static MythRenderOpenGL * Create(QWidget *Widget)
int GetMaxTextureUnits(void) const
void DrawBitmap(MythGLTexture *Texture, QOpenGLFramebufferObject *Target, QRect Source, QRect Destination, QOpenGLShaderProgram *Program, int Alpha=255, qreal Scale=1.0)
void ClearFramebuffer(void)
QMap< uint64_t, QOpenGLBuffer * > m_cachedVBOS
QHash< QString, QMatrix4x4 > m_cachedMatrixUniforms
void SetViewPort(QRect Rect, bool ViewportOnly=false) override
void DeleteShaderProgram(QOpenGLShaderProgram *Program)
void BindFramebuffer(QOpenGLFramebufferObject *Framebuffer)
QOpenGLShaderProgram * m_activeProgram
void DeleteFramebuffer(QOpenGLFramebufferObject *Framebuffer)
MythRenderOpenGL(const QSurfaceFormat &Format, QWidget *Widget)
void DeleteDefaultShaders(void)
void MessageLogged(const QOpenGLDebugMessage &Message)
void PushTransformation(const UIEffects &Fx, QPointF &Center)
QOpenGLFunctions::OpenGLFeatures GetFeatures(void) const
void PopTransformation(void)
bool EnableShaderProgram(QOpenGLShaderProgram *Program)
void SetBlend(bool Enable)
bool IsRecommendedRenderer(void)
QOpenGLDebugMessage::Types m_openGLDebuggerFilter
QOpenGLBuffer * CreateVBO(int Size, bool Release=true)
~MythRenderOpenGL() override
void logDebugMarker(const QString &Message)
void Check16BitFBO(void)
Check for 16bit framebufferobject support.
GLfloat * GetCachedVertices(GLuint Type, QRect Area)
QHash< QOpenGLShaderProgram *, QHash< QByteArray, GLint > > m_cachedUniformLocations
GLuint m_activeFramebuffer
QOpenGLFramebufferObject * CreateFramebuffer(QSize &Size, bool SixteenBit=false)
void SetBackground(uint8_t Red, uint8_t Green, uint8_t Blue, uint8_t Alpha)
QOpenGLShaderProgram * CreateShaderProgram(const QString &Vertex, const QString &Fragment)
QFunctionPointer GetProcAddress(const QString &Proc) const
void glVertexAttribPointerI(GLuint Index, GLint Size, GLenum Type, GLboolean Normalize, GLsizei Stride, GLuint Value)
static bool UpdateTextureVertices(MythGLTexture *Texture, QRect Source, QRect Destination, int Rotation, qreal Scale=1.0)
QMap< uint64_t, GLfloat * > m_cachedVertices
void DeleteTexture(MythGLTexture *Texture)
static MythRenderOpenGL * GetOpenGLRender(void)
QSize GetTextureSize(QSize Size, bool Normalised)
void DrawRect(QOpenGLFramebufferObject *Target, QRect Area, const QBrush &FillBrush, const QPen &LinePen, int Alpha)
MythGLTexture * CreateFramebufferTexture(QOpenGLFramebufferObject *Framebuffer)
This is no longer used but will probably be needed for future UI enhancements.
std::tuple< int, int, int > GetGPUMemory()
int GetExtraFeatures(void) const
bool CreateDefaultShaders(void)
void SetShaderProjection(QOpenGLShaderProgram *Program)
QList< uint64_t > m_vboExpiry
std::array< QOpenGLShaderProgram *, kShaderCount > m_defaultPrograms
void SetTextureFilters(MythGLTexture *Texture, QOpenGLTexture::Filter Filter, QOpenGLTexture::WrapMode Wrap=QOpenGLTexture::ClampToEdge)
void ReleaseResources(void) override
void ExpireVertices(int Max=0)
QStringList GetDescription(void) override
static int GetTextureDataSize(MythGLTexture *Texture)
QOpenGLShaderProgram * CreateComputeShader(const QString &Source)
RenderType Type(void) const
static bool DisplayIsRemote()
Determine if we are running a remote X11 session.
OpenGLLocker(MythRenderOpenGL *Render)
MythRenderOpenGL * m_render
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
static bool VERBOSE_LEVEL_CHECK(uint64_t mask, LogLevel_t level)
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
bool HasMythMainWindow(void)
static constexpr QLatin1String GLYesNo(bool v)
static constexpr GLuint kTextureOffset
static const float kLimitedRangeScale
static constexpr GLint TEXTURE_SIZE
static constexpr GLuint TEXTURE_INDEX
static constexpr GLuint COLOR_INDEX
QOpenGLShaderProgram * ShaderError(QOpenGLShaderProgram *Shader, const QString &Source)
static const float kLimitedRangeOffset
static constexpr int MAX_VERTEX_CACHE
static constexpr GLuint VERTEX_INDEX
static constexpr GLuint kVertexOffset
static constexpr GLint VERTEX_SIZE
static constexpr size_t TEX_OFFSET
#define GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX
#define GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX
#define GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX
GLboolean(APIENTRY *)(GLenum target) MYTH_GLUNMAPBUFFERPROC
GLvoid *(APIENTRY *)(GLenum target, GLenum access) MYTH_GLMAPBUFFERPROC
static const QString kRoundedEdgeShader
static const QString kDefaultVertexShader
static const QString kRoundedRectShader
static const QString kDrawVertexShader
static const QString kDefaultFragmentShaderLimited
static const QString kSimpleVertexShader
static const QString kDefaultFragmentShader
static const QString kSimpleFragmentShader
MBASE_PUBLIC long long copy(QFile &dst, QFile &src, uint block_size=0)
Copies src file to dst file.
static QString Source(const QNetworkRequest &request)
VERBOSE_PREAMBLE Most true
VERBOSE_PREAMBLE Most debug(nodatabase, notimestamp, noextra)") VERBOSE_MAP(VB_GENERAL