10#include <QGuiApplication>
13#include <libmythbase/mythconfig.h>
25#define LOC QString("OpenGL: ")
28#include <android/log.h>
49 : m_textureId(Texture)
90 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"OpenGL is disabled for Remote X Session");
96 bool opengles = !qEnvironmentVariableIsEmpty(
"MYTHTV_OPENGL_ES");
97 bool core = !qEnvironmentVariableIsEmpty(
"MYTHTV_OPENGL_CORE");
98 QSurfaceFormat format = QSurfaceFormat::defaultFormat();
101 format.setProfile(QSurfaceFormat::CoreProfile);
102 format.setMajorVersion(4);
103 format.setMinorVersion(3);
110 format.setProfile(QSurfaceFormat::CoreProfile);
111 format.setMajorVersion(3);
112 format.setMinorVersion(1);
114 format.setRenderableType(QSurfaceFormat::OpenGLES);
118 format.setOption(QSurfaceFormat::DebugContext);
138 LOG(VB_GENERAL, LOG_INFO,
LOC +
"MythRenderOpenGL closing");
152 QString source(
"Unknown");
153 QString
type(
"Unknown");
155 switch (Message.source())
157 case QOpenGLDebugMessage::ApplicationSource:
return;
158 case QOpenGLDebugMessage::APISource: source =
"API";
break;
159 case QOpenGLDebugMessage::WindowSystemSource: source =
"WinSys";
break;
160 case QOpenGLDebugMessage::ShaderCompilerSource: source =
"ShaderComp";
break;
161 case QOpenGLDebugMessage::ThirdPartySource: source =
"3rdParty";
break;
162 case QOpenGLDebugMessage::OtherSource: source =
"Other";
break;
168 switch (Message.type())
170 case QOpenGLDebugMessage::ErrorType:
171 type =
"Error";
break;
172 case QOpenGLDebugMessage::DeprecatedBehaviorType:
173 type =
"Deprecated";
break;
174 case QOpenGLDebugMessage::UndefinedBehaviorType:
175 type =
"Undef behaviour";
break;
176 case QOpenGLDebugMessage::PortabilityType:
177 type =
"Portability";
break;
178 case QOpenGLDebugMessage::PerformanceType:
179 type =
"Performance";
break;
180 case QOpenGLDebugMessage::OtherType:
181 type =
"Other";
break;
182 case QOpenGLDebugMessage::MarkerType:
183 type =
"Marker";
break;
184 case QOpenGLDebugMessage::GroupPushType:
185 type =
"GroupPush";
break;
186 case QOpenGLDebugMessage::GroupPopType:
187 type =
"GroupPop";
break;
190 LOG(VB_GPU, LOG_INFO,
LOC + QString(
"Src: %1 Type: %2 Msg: %3")
191 .arg(source,
type, Message.message()));
198 QOpenGLDebugMessage message = QOpenGLDebugMessage::createApplicationMessage(
199 Message, 0, QOpenGLDebugMessage::NotificationSeverity, QOpenGLDebugMessage::MarkerType);
208 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Context about to be destroyed");
215 LOG(VB_GENERAL, LOG_ERR,
LOC +
"MythRenderOpenGL is not a valid OpenGL rendering context");
220 initializeOpenGLFunctions();
231 QOpenGLDebugLogger::LoggingMode mode = QOpenGLDebugLogger::AsynchronousLogging;
234 if (!qEnvironmentVariableIsEmpty(
"MYTHTV_OPENGL_SYNCHRONOUS"))
235 mode = QOpenGLDebugLogger::SynchronousLogging;
238 if (mode == QOpenGLDebugLogger::AsynchronousLogging)
239 LOG(VB_GENERAL, LOG_INFO,
LOC +
"GPU debug logging started (async)");
241 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Started synchronous GPU debug logging (will hurt performance)");
245 QString filter = qgetenv(
"MYTHTV_OPENGL_LOGFILTER");
246 if (filter.contains(
"other", Qt::CaseInsensitive))
251 if (filter.contains(
"error", Qt::CaseInsensitive))
256 if (filter.contains(
"deprecated", Qt::CaseInsensitive))
259 debug <<
"Deprecated";
261 if (filter.contains(
"undefined", Qt::CaseInsensitive))
264 debug <<
"Undefined";
266 if (filter.contains(
"portability", Qt::CaseInsensitive))
269 debug <<
"Portability";
271 if (filter.contains(
"performance", Qt::CaseInsensitive))
274 debug <<
"Performance";
276 if (filter.contains(
"grouppush", Qt::CaseInsensitive))
279 debug <<
"GroupPush";
281 if (filter.contains(
"grouppop", Qt::CaseInsensitive))
287 if (!
debug.isEmpty())
288 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Filtering out GPU messages for: %1")
289 .arg(
debug.join(
", ")));
293 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Failed to initialise OpenGL logging");
307 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxtexsz);
308 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxunits);
311 QSurfaceFormat fmt = format();
319 if ((isOpenGLES() && hasExtension(
"GL_OES_mapbuffer") && buffer_procs) ||
320 (hasExtension(
"GL_ARB_vertex_buffer_object") && buffer_procs))
324 if (!isOpenGLES() && (hasExtension(
"GL_NV_texture_rectangle") ||
325 hasExtension(
"GL_ARB_texture_rectangle") ||
326 hasExtension(
"GL_EXT_texture_rectangle")))
330 if ((isOpenGLES() && format().majorVersion() < 3) ||
331 (!isOpenGLES() && format().majorVersion() < 2))
336 if (!isOpenGLES() || (isOpenGLES() && ((fmt.majorVersion() >= 3) || hasExtension(
"GL_EXT_unpack_subimage"))))
340 if (fmt.profile() == QSurfaceFormat::OpenGLContextProfile::CoreProfile)
344 extraFunctions()->glGenVertexArrays(1, &
m_vao);
345 extraFunctions()->glBindVertexArray(
m_vao);
355 static const std::array<const QByteArray,3> kTiled {
"videocore",
"vc4",
"v3d" };
356 auto renderer = QByteArray(
reinterpret_cast<const char*
>(glGetString(GL_RENDERER))).toLower();
357 for (
const auto & name : kTiled)
359 if (renderer.contains(name))
367 if (hasExtension(
"GL_NVX_gpu_memory_info"))
374 if (QOpenGLShader::hasOpenGLShaders(QOpenGLShader::Compute))
376 if (QOpenGLShader::hasOpenGLShaders(QOpenGLShader::Geometry))
384 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Failed to create default shaders");
388 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Initialised MythRenderOpenGL");
389 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Using %1 range output").arg(
m_fullRange ?
"full" :
"limited"));
395static constexpr QLatin1String
GLYesNo (
bool v)
397 return v ? QLatin1String(
"Yes") : QLatin1String(
"No");
402 QSurfaceFormat fmt = format();
403 QString qtglversion = QString(
"OpenGL%1 %2.%3")
404 .arg(fmt.renderableType() == QSurfaceFormat::OpenGLES ?
"ES" :
"")
405 .arg(fmt.majorVersion()).arg(fmt.minorVersion());
406 QString qtglsurface = QString(
"RGBA: %1:%2:%3:%4 Depth: %5 Stencil: %6")
407 .arg(fmt.redBufferSize()).arg(fmt.greenBufferSize())
408 .arg(fmt.blueBufferSize()).arg(fmt.alphaBufferSize())
409 .arg(fmt.depthBufferSize()).arg(fmt.stencilBufferSize());
410 QStringList shaders {
"None"};
413 shaders = QStringList {
"Vertex",
"Fragment" };
415 shaders <<
"Geometry";
417 shaders <<
"Compute";
419 const QString module = QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL ?
"OpenGL (not ES)" :
"OpenGL ES";
420 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"OpenGL vendor : %1").arg(
reinterpret_cast<const char*
>(glGetString(GL_VENDOR))));
421 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"OpenGL renderer : %1").arg(
reinterpret_cast<const char*
>(glGetString(GL_RENDERER))));
422 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"OpenGL version : %1").arg(
reinterpret_cast<const char*
>(glGetString(GL_VERSION))));
423 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Qt platform : %1").arg(QGuiApplication::platformName()));
425 bool eglfuncs =
IsEGL();
427 LOG(VB_PLAYBACK, LOG_INFO,
LOC + QString(
"EGL images : %1").arg(
GLYesNo(eglfuncs)));
429 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Qt OpenGL module : %1").arg(module));
430 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Qt OpenGL format : %1").arg(qtglversion));
431 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Qt OpenGL surface : %1").arg(qtglsurface));
433 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Shaders : %1").arg(shaders.join(
",")));
443 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Warning: Insufficient texture units for some features.");
471 bool recommended =
true;
473 QString renderer =
reinterpret_cast<const char*
>(glGetString(GL_RENDERER));
475 if (!(openGLFeatures() & Shaders))
477 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"OpenGL has no shader support");
480 else if (!(openGLFeatures() & Framebuffers))
482 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"OpenGL has no framebuffer support");
485 else if (renderer.contains(
"Software Rasterizer", Qt::CaseInsensitive))
487 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"OpenGL is using software rasterizer.");
490 else if (renderer.contains(
"softpipe", Qt::CaseInsensitive))
492 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"OpenGL seems to be using software "
493 "fallback. Please check your OpenGL driver installation, "
494 "configuration, and device permissions.");
500 LOG(VB_GENERAL, LOG_INFO,
LOC +
501 "OpenGL not recommended with this system's hardware/drivers.");
514 QOpenGLContext::swapBuffers(
m_window);
529 LOG(VB_GENERAL, LOG_CRIT,
LOC +
"No widget!");
535 QWidget* native = Widget->nativeParentWidget();
541 LOG(VB_GENERAL, LOG_CRIT,
LOC +
"No window surface!");
545#if defined(Q_OS_ANDROID) || (QT_VERSION > QT_VERSION_CHECK(6,3,0))
547 m_window->setSurfaceType(QWindow::OpenGLSurface);
548 if (native && native->windowHandle())
549 native->windowHandle()->setSurfaceType(QWindow::OpenGLSurface);
552#ifdef CONFIG_QTWEBENGINE
553 auto * globalcontext = QOpenGLContext::globalShareContext();
556 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Using global shared OpenGL context");
557 setShareContext(globalcontext);
562 LOG(VB_GENERAL, LOG_CRIT,
LOC +
"Failed to create OpenGLContext!");
565 Widget->setAttribute(Qt::WA_PaintOnScreen);
573 if (!QOpenGLContext::makeCurrent(
m_window))
574 LOG(VB_GENERAL, LOG_ERR,
LOC +
"makeCurrent failed");
583 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Mis-matched calls to makeCurrent()");
623 int32_t
tmp = (Red << 24) + (Green << 16) + (Blue << 8) + Alpha;
629 glClearColor(Red / 255.0F, Green / 255.0F, Blue / 255.0F, Alpha / 255.0F);
639 auto *texture =
new QOpenGLTexture(*Image, QOpenGLTexture::DontGenerateMipMaps);
640 if (!texture->textureId())
642 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Failed to create texure");
646 texture->setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear);
647 texture->setWrapMode(QOpenGLTexture::ClampToEdge);
649 result->m_texture = texture;
651 result->m_totalSize =
GetTextureSize(Image->size(), result->m_target != QOpenGLTexture::TargetRectangle);
653 result->m_pixelFormat = QOpenGLTexture::RGBA;
654 result->m_pixelType = QOpenGLTexture::UInt8;
655 result->m_bufferSize =
GetBufferSize(result->m_totalSize, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8);
656 result->m_size = Image->size();
657 result->m_crop =
true;
663 if (((
m_features & NPOTTextures) != 0U) || !Normalised)
668 while (w < Size.width())
670 while (h < Size.height())
692 Texture->
m_texture->setMinMagFilters(Filter, Filter);
697 glTexParameteri(Texture->
m_target, GL_TEXTURE_MIN_FILTER, Filter);
698 glTexParameteri(Texture->
m_target, GL_TEXTURE_MAG_FILTER, Filter);
699 glTexParameteri(Texture->
m_target, GL_TEXTURE_WRAP_S, Wrap);
700 glTexParameteri(Texture->
m_target, GL_TEXTURE_WRAP_T, Wrap);
713 glActiveTexture(ActiveTex);
727 delete [] Texture->
m_data;
728 delete Texture->
m_vbo;
740 QOpenGLFramebufferObject *framebuffer =
nullptr;
743 framebuffer =
new QOpenGLFramebufferObject(Size, QOpenGLFramebufferObject::NoAttachment,
744 GL_TEXTURE_2D, QOpenGLTexture::RGBA16_UNorm);
748 framebuffer =
new QOpenGLFramebufferObject(Size);
750 if (framebuffer->isValid())
752 if (framebuffer->isBound())
760 LOG(VB_GENERAL, LOG_ERR,
"Failed to create framebuffer object");
772 texture->m_size = texture->m_totalSize = Framebuffer->size();
774 texture->m_flip =
false;
795 if (Framebuffer ==
nullptr)
797 QOpenGLFramebufferObject::bindDefault();
811 glClear(GL_COLOR_BUFFER_BIT);
816 QOpenGLShaderProgram *Program,
float TimeVal)
827 Program->setUniformValue(
"u_time", TimeVal);
828 Program->setUniformValue(
"u_alpha",
static_cast<float>(Alpha / 255.0F));
829 Program->setUniformValue(
"u_res", QVector2D(
m_window->width(),
m_window->height()));
830 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
831 QOpenGLBuffer::release(QOpenGLBuffer::VertexBuffer);
837 const QRect
Source,
const QRect Destination,
838 QOpenGLShaderProgram *Program,
int Alpha, qreal Scale)
845 if (Program ==
nullptr)
851 GLenum textarget = Texture->
m_target;
852 Program->setUniformValue(
"s_texture0", 0);
859 QOpenGLBuffer* buffer = Texture->
m_vbo;
865 void* target = buffer->map(QOpenGLBuffer::WriteOnly);
870 static_cast<GLfloat*
>(target));
883 glVertexAttrib4f(
COLOR_INDEX, 1.0F, 1.0F, 1.0F, Alpha / 255.0F);
885 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
888 QOpenGLBuffer::release(QOpenGLBuffer::VertexBuffer);
893 QOpenGLFramebufferObject *Target,
894 const QRect
Source,
const QRect Destination,
895 QOpenGLShaderProgram *Program,
898 if (Textures.empty())
904 if (Program ==
nullptr)
914 for (
uint i = 0; i < Textures.size(); i++)
916 QString uniform = QString(
"s_texture%1").arg(i);
917 Program->setUniformValue(qPrintable(uniform), i);
919 if (Textures[i]->m_texture)
920 Textures[i]->m_texture->bind();
922 glBindTexture(textarget, Textures[i]->m_textureId);
925 QOpenGLBuffer* buffer = first->
m_vbo;
931 void* target = buffer->map(QOpenGLBuffer::WriteOnly);
936 static_cast<GLfloat*
>(target));
951 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
954 QOpenGLBuffer::release(QOpenGLBuffer::VertexBuffer);
970 glVertexAttrib4f(
COLOR_INDEX, color, color, color, Alpha / 255.0F);
975 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
977 QOpenGLBuffer::release(QOpenGLBuffer::VertexBuffer);
983 const QRect Area,
const QBrush &FillBrush,
984 const QPen &LinePen,
int Alpha)
991 const QRect Area,
int CornerRadius,
992 const QBrush &FillBrush,
993 const QPen &LinePen,
int Alpha)
995 bool fill = FillBrush.style() != Qt::NoBrush;
996 bool edge = LinePen.style() != Qt::NoPen;
1000 auto SetColor = [&](
const QColor&
Color)
1005 Color.blue() / 255.0F, (
Color.alpha() / 255.0F) * (Alpha / 255.0F));
1011 (
Color.alpha() / 255.0F) * (Alpha / 255.0F));
1014 float halfwidth = Area.width() / 2.0F;
1015 float halfheight = Area.height() / 2.0F;
1016 float radius = CornerRadius;
1017 radius = std::max(radius, 1.0F);
1018 radius = std::min(radius, halfwidth);
1019 radius = std::min(radius, halfheight);
1038 SetColor(FillBrush.color());
1041 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1046 float innerradius = radius - LinePen.width();
1047 innerradius = std::max(innerradius, 1.0F);
1052 SetColor(LinePen.color());
1055 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1058 QOpenGLBuffer::release(QOpenGLBuffer::VertexBuffer);
1064 GLsizei Stride,
const GLuint Value)
1066#pragma GCC diagnostic push
1067#pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
1069 glVertexAttribPointer(Index, Size,
Type, Normalize, Stride,
reinterpret_cast<const char *
>(Value));
1070#pragma GCC diagnostic pop
1076 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1077 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1078 glDisable(GL_DEPTH_TEST);
1079 glDepthMask(GL_FALSE);
1080 glDisable(GL_CULL_FACE);
1081 glClearColor(0.0F, 0.0F, 0.0F, 0.0F);
1082 glClear(GL_COLOR_BUFFER_BIT);
1083 QOpenGLFramebufferObject::bindDefault();
1090 static const std::array<const QString,4> kExts {
"",
"ARB",
"EXT",
"OES" };
1091 QFunctionPointer result =
nullptr;
1092 for (
const auto & ext : kExts)
1094 result = getProcAddress((Proc + ext).toLocal8Bit().constData());
1098 if (result ==
nullptr)
1099 LOG(VB_GENERAL, LOG_DEBUG,
LOC + QString(
"Extension not found: %1").arg(Proc));
1106 auto* buffer =
new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
1107 if (buffer->create())
1109 buffer->setUsagePattern(QOpenGLBuffer::StreamDraw);
1111 buffer->allocate(Size);
1113 QOpenGLBuffer::release(QOpenGLBuffer::VertexBuffer);
1130 extraFunctions()->glDeleteVertexArrays(1, &
m_vao);
1150 result.append(tr(
"QPA platform") +
"\t: " + QGuiApplication::platformName());
1151 result.append(tr(
"OpenGL vendor") +
"\t: " +
reinterpret_cast<const char*
>(glGetString(GL_VENDOR)));
1152 result.append(tr(
"OpenGL renderer") +
"\t: " +
reinterpret_cast<const char*
>(glGetString(GL_RENDERER)));
1153 result.append(tr(
"OpenGL version") +
"\t: " +
reinterpret_cast<const char*
>(glGetString(GL_VERSION)));
1154 QSurfaceFormat fmt = format();
1155 result.append(tr(
"Color depth (RGBA)") +
"\t: " + QString(
"%1:%2:%3:%4")
1156 .arg(fmt.redBufferSize()).arg(fmt.greenBufferSize())
1157 .arg(fmt.blueBufferSize()).arg(fmt.alphaBufferSize()));
1162 const QRect Destination,
int Rotation, qreal Scale)
1164 if (!Texture || Texture->
m_size.isEmpty())
1176 QSize size = Texture->
m_size;
1178 int width = Texture->
m_crop ? std::min(
Source.width(), size.width()) :
Source.width();
1179 int height = Texture->
m_crop ? std::min(
Source.height(), size.height()) :
Source.height();
1181 if (Texture->
m_target != QOpenGLTexture::TargetRectangle)
1184 data[(Texture->
m_flip ? 7 : 1) +
TEX_OFFSET] = (
Source.top() + height) /
static_cast<GLfloat
>(size.height());
1185 data[6 +
TEX_OFFSET] = (
Source.left() + width) /
static_cast<GLfloat
>(size.width());
1201 width = Texture->
m_crop ? std::min(
static_cast<int>(width * Scale), Destination.width()) : Destination.width();
1202 height = Texture->
m_crop ? std::min(
static_cast<int>(height * Scale), Destination.height()) : Destination.height();
1204 data[2] = data[0] = Destination.left();
1205 data[5] = data[1] = Destination.top();
1206 data[4] = data[6] = Destination.left() + width;
1207 data[3] = data[7] = Destination.top() + height;
1247 uint64_t ref = (
static_cast<uint64_t
>(Area.left()) & 0xfff) +
1248 ((
static_cast<uint64_t
>(Area.top()) & 0xfff) << 12) +
1249 ((
static_cast<uint64_t
>(Area.width()) & 0xfff) << 24) +
1250 ((
static_cast<uint64_t
>(Area.height()) & 0xfff) << 36) +
1251 ((
static_cast<uint64_t
>(
Type & 0xfff)) << 48);
1260 auto *vertices =
new GLfloat[8];
1262 vertices[2] = vertices[0] = Area.left();
1263 vertices[5] = vertices[1] = Area.top();
1264 vertices[4] = vertices[6] = Area.left() + Area.width();
1265 vertices[3] = vertices[7] = Area.top() + Area.height();
1267 if (
Type == GL_LINE_LOOP)
1269 vertices[7] = vertices[1];
1270 vertices[5] = vertices[3];
1286 GLfloat *vertices =
nullptr;
1296 uint64_t ref = (
static_cast<uint64_t
>(Area.left()) & 0xfff) +
1297 ((
static_cast<uint64_t
>(Area.top()) & 0xfff) << 12) +
1298 ((
static_cast<uint64_t
>(Area.width()) & 0xfff) << 24) +
1299 ((
static_cast<uint64_t
>(Area.height()) & 0xfff) << 36) +
1300 ((
static_cast<uint64_t
>(
Type & 0xfff)) << 48);
1317 void* target = vbo->map(QOpenGLBuffer::WriteOnly);
1351 case QOpenGLTexture::RGBA_Integer:
1352 case QOpenGLTexture::BGRA_Integer:
1353 case QOpenGLTexture::BGRA:
1354 case QOpenGLTexture::RGBA: bpp = 4;
break;
1355 case QOpenGLTexture::RGB_Integer:
1356 case QOpenGLTexture::BGR_Integer:
1357 case QOpenGLTexture::BGR:
1358 case QOpenGLTexture::RGB: bpp = 3;
break;
1359 case QOpenGLTexture::RG_Integer:
1360 case QOpenGLTexture::RG: bpp = 2;
break;
1361 case QOpenGLTexture::Red:
1362 case QOpenGLTexture::Red_Integer:
1363 case QOpenGLTexture::Alpha:
1364 case QOpenGLTexture::Luminance: bpp = 1;
break;
1370 case QOpenGLTexture::Int8:
bytes =
sizeof(GLbyte);
break;
1371 case QOpenGLTexture::UInt8:
bytes =
sizeof(GLubyte);
break;
1372 case QOpenGLTexture::Int16:
bytes =
sizeof(GLshort);
break;
1373 case QOpenGLTexture::UInt16:
bytes =
sizeof(GLushort);
break;
1374 case QOpenGLTexture::Int32:
bytes =
sizeof(GLint);
break;
1375 case QOpenGLTexture::UInt32:
bytes =
sizeof(GLuint);
break;
1376 case QOpenGLTexture::Float32:
bytes =
sizeof(GLfloat);
break;
1377 case QOpenGLTexture::UInt32_RGB10A2:
bytes =
sizeof(GLuint);
break;
1381 if (!bpp || !
bytes || Size.isEmpty())
1384 return Size.width() * Size.height() * bpp *
bytes;
1392 newtop.translate(
static_cast<GLfloat
>(Center.x()),
static_cast<GLfloat
>(Center.y()));
1394 newtop.rotate(Fx.
m_angle, 0, 0, 1);
1395 newtop.translate(
static_cast<GLfloat
>(-Center.x()),
static_cast<GLfloat
>(-Center.y()));
1407 QString
type =
Source.isEmpty() ?
"Shader link" :
"Shader compile";
1408 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"%1 error").arg(
type));
1409 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Log:"));
1410 LOG(VB_GENERAL, LOG_ERR,
"\n" + Shader->log());
1413 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Source:"));
1414 LOG(VB_GENERAL, LOG_ERR,
"\n" +
Source);
1428 auto *program =
new QOpenGLShaderProgram();
1429 if (!program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertex))
1431 if (!program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragment))
1435 QList<QOpenGLShader*> shaders = program->shaders();
1436 for (QOpenGLShader* shader : std::as_const(shaders))
1437 LOG(VB_GENERAL, LOG_DEBUG,
"\n" + shader->sourceCode());
1439 program->bindAttributeLocation(
"a_position",
VERTEX_INDEX);
1440 program->bindAttributeLocation(
"a_color",
COLOR_INDEX);
1441 program->bindAttributeLocation(
"a_texcoord0",
TEXTURE_INDEX);
1442 if (!program->link())
1453 auto *program =
new QOpenGLShaderProgram();
1454 if (!program->addShaderFromSourceCode(QOpenGLShader::Compute,
Source))
1459 QList<QOpenGLShader*> shaders = program->shaders();
1460 for (QOpenGLShader* shader : std::as_const(shaders))
1461 LOG(VB_GENERAL, LOG_DEBUG,
"\n" + shader->sourceCode());
1464 if (!program->link())
1510 QString tag = QString(
"%1-%2").arg(Program->programId()).arg(Uniform);
1514 else if (!qFuzzyCompare(Value, it.value()))
1520 QByteArray uniform(Uniform);
1523 if (uniforms.contains(uniform))
1525 location = uniforms[uniform];
1529 location = Program->uniformLocation(Uniform);
1530 uniforms.insert(uniform, location);
1533 Program->setUniformValue(location, Value);
1567 GLint dedicated = 0;
1568 GLint available = 0;
1572 return { total / 1024, dedicated / 1024, available / 1024 };
1590 QSize size{256, 256};
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