10 #include <QGuiApplication>
24 #define LOC QString("OpenGL: ")
27 #include <android/log.h>
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"));
394 static 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.greenBufferSize()).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!");
546 m_window->setSurfaceType(QWindow::OpenGLSurface);
547 if (native && native->windowHandle())
548 native->windowHandle()->setSurfaceType(QWindow::OpenGLSurface);
551 #ifdef USING_QTWEBENGINE
552 auto * globalcontext = QOpenGLContext::globalShareContext();
555 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Using global shared OpenGL context");
556 setShareContext(globalcontext);
561 LOG(VB_GENERAL, LOG_CRIT,
LOC +
"Failed to create OpenGLContext!");
563 Widget->setAttribute(Qt::WA_PaintOnScreen);
570 if (!QOpenGLContext::makeCurrent(
m_window))
571 LOG(VB_GENERAL, LOG_ERR,
LOC +
"makeCurrent failed");
580 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Mis-matched calls to makeCurrent()");
620 int32_t
tmp = (Red << 24) + (Green << 16) + (Blue << 8) + Alpha;
626 glClearColor(Red / 255.0F, Green / 255.0F, Blue / 255.0F, Alpha / 255.0F);
636 auto *texture =
new QOpenGLTexture(*Image, QOpenGLTexture::DontGenerateMipMaps);
637 if (!texture->textureId())
639 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Failed to create texure");
643 texture->setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear);
644 texture->setWrapMode(QOpenGLTexture::ClampToEdge);
646 result->m_texture = texture;
648 result->m_totalSize =
GetTextureSize(Image->size(), result->m_target != QOpenGLTexture::TargetRectangle);
650 result->m_pixelFormat = QOpenGLTexture::RGBA;
651 result->m_pixelType = QOpenGLTexture::UInt8;
652 result->m_bufferSize =
GetBufferSize(result->m_totalSize, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8);
653 result->m_size = Image->size();
654 result->m_crop =
true;
660 if (((
m_features & NPOTTextures) != 0U) || !Normalised)
665 while (w < Size.width())
667 while (h < Size.height())
689 Texture->
m_texture->setMinMagFilters(Filter, Filter);
694 glTexParameteri(Texture->
m_target, GL_TEXTURE_MIN_FILTER, Filter);
695 glTexParameteri(Texture->
m_target, GL_TEXTURE_MAG_FILTER, Filter);
696 glTexParameteri(Texture->
m_target, GL_TEXTURE_WRAP_S, Wrap);
697 glTexParameteri(Texture->
m_target, GL_TEXTURE_WRAP_T, Wrap);
710 glActiveTexture(ActiveTex);
724 delete [] Texture->
m_data;
725 delete Texture->
m_vbo;
737 QOpenGLFramebufferObject *framebuffer =
nullptr;
740 framebuffer =
new QOpenGLFramebufferObject(Size, QOpenGLFramebufferObject::NoAttachment,
741 GL_TEXTURE_2D, QOpenGLTexture::RGBA16_UNorm);
745 framebuffer =
new QOpenGLFramebufferObject(Size);
747 if (framebuffer->isValid())
749 if (framebuffer->isBound())
757 LOG(VB_GENERAL, LOG_ERR,
"Failed to create framebuffer object");
769 texture->m_size = texture->m_totalSize = Framebuffer->size();
771 texture->m_flip =
false;
792 if (Framebuffer ==
nullptr)
794 QOpenGLFramebufferObject::bindDefault();
808 glClear(GL_COLOR_BUFFER_BIT);
813 QOpenGLShaderProgram *Program,
float TimeVal)
824 Program->setUniformValue(
"u_time", TimeVal);
825 Program->setUniformValue(
"u_alpha",
static_cast<float>(Alpha / 255.0F));
826 Program->setUniformValue(
"u_res", QVector2D(
m_window->width(),
m_window->height()));
827 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
828 QOpenGLBuffer::release(QOpenGLBuffer::VertexBuffer);
834 const QRect
Source,
const QRect Destination,
835 QOpenGLShaderProgram *Program,
int Alpha, qreal Scale)
842 if (Program ==
nullptr)
848 GLenum textarget = Texture->
m_target;
849 Program->setUniformValue(
"s_texture0", 0);
856 QOpenGLBuffer* buffer = Texture->
m_vbo;
862 void* target = buffer->map(QOpenGLBuffer::WriteOnly);
867 static_cast<GLfloat*
>(target));
880 glVertexAttrib4f(
COLOR_INDEX, 1.0F, 1.0F, 1.0F, Alpha / 255.0F);
882 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
885 QOpenGLBuffer::release(QOpenGLBuffer::VertexBuffer);
890 QOpenGLFramebufferObject *Target,
891 const QRect
Source,
const QRect Destination,
892 QOpenGLShaderProgram *Program,
895 if (Textures.empty())
901 if (Program ==
nullptr)
911 for (
uint i = 0; i < Textures.size(); i++)
913 QString uniform = QString(
"s_texture%1").arg(i);
914 Program->setUniformValue(qPrintable(uniform), i);
916 if (Textures[i]->m_texture)
917 Textures[i]->m_texture->bind();
919 glBindTexture(textarget, Textures[i]->m_textureId);
922 QOpenGLBuffer* buffer = first->
m_vbo;
928 void* target = buffer->map(QOpenGLBuffer::WriteOnly);
933 static_cast<GLfloat*
>(target));
948 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
951 QOpenGLBuffer::release(QOpenGLBuffer::VertexBuffer);
967 glVertexAttrib4f(
COLOR_INDEX, color, color, color, Alpha / 255.0F);
972 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
974 QOpenGLBuffer::release(QOpenGLBuffer::VertexBuffer);
980 const QRect Area,
const QBrush &FillBrush,
981 const QPen &LinePen,
int Alpha)
988 const QRect Area,
int CornerRadius,
989 const QBrush &FillBrush,
990 const QPen &LinePen,
int Alpha)
992 bool fill = FillBrush.style() != Qt::NoBrush;
993 bool edge = LinePen.style() != Qt::NoPen;
997 auto SetColor = [&](
const QColor&
Color)
1002 Color.blue() / 255.0F, (
Color.alpha() / 255.0F) * (Alpha / 255.0F));
1008 (
Color.alpha() / 255.0F) * (Alpha / 255.0F));
1011 float halfwidth = Area.width() / 2.0F;
1012 float halfheight = Area.height() / 2.0F;
1013 float radius = CornerRadius;
1014 if (radius < 1.0F) radius = 1.0F;
1015 if (radius > halfwidth) radius = halfwidth;
1016 if (radius > halfheight) radius = halfheight;
1035 SetColor(FillBrush.color());
1038 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1043 float innerradius = radius - LinePen.width();
1044 if (innerradius < 1.0F) innerradius = 1.0F;
1049 SetColor(LinePen.color());
1052 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1055 QOpenGLBuffer::release(QOpenGLBuffer::VertexBuffer);
1061 GLsizei Stride,
const GLuint Value)
1063 #pragma GCC diagnostic push
1064 #pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
1065 glVertexAttribPointer(Index, Size,
Type, Normalize, Stride,
reinterpret_cast<const char *
>(Value));
1066 #pragma GCC diagnostic pop
1072 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1073 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1074 glDisable(GL_DEPTH_TEST);
1075 glDepthMask(GL_FALSE);
1076 glDisable(GL_CULL_FACE);
1077 glClearColor(0.0F, 0.0F, 0.0F, 0.0F);
1078 glClear(GL_COLOR_BUFFER_BIT);
1079 QOpenGLFramebufferObject::bindDefault();
1086 static const std::array<const QString,4> kExts {
"",
"ARB",
"EXT",
"OES" };
1087 QFunctionPointer result =
nullptr;
1088 for (
const auto & ext : kExts)
1090 result = getProcAddress((Proc + ext).toLocal8Bit().constData());
1094 if (result ==
nullptr)
1095 LOG(VB_GENERAL, LOG_DEBUG,
LOC + QString(
"Extension not found: %1").arg(Proc));
1102 auto* buffer =
new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
1103 if (buffer->create())
1105 buffer->setUsagePattern(QOpenGLBuffer::StreamDraw);
1107 buffer->allocate(Size);
1109 QOpenGLBuffer::release(QOpenGLBuffer::VertexBuffer);
1126 extraFunctions()->glDeleteVertexArrays(1, &
m_vao);
1146 result.append(tr(
"QPA platform") +
"\t: " + QGuiApplication::platformName());
1147 result.append(tr(
"OpenGL vendor") +
"\t: " +
reinterpret_cast<const char*
>(glGetString(GL_VENDOR)));
1148 result.append(tr(
"OpenGL renderer") +
"\t: " +
reinterpret_cast<const char*
>(glGetString(GL_RENDERER)));
1149 result.append(tr(
"OpenGL version") +
"\t: " +
reinterpret_cast<const char*
>(glGetString(GL_VERSION)));
1150 QSurfaceFormat fmt = format();
1151 result.append(tr(
"Color depth (RGBA)") +
"\t: " + QString(
"%1:%2:%3:%4")
1152 .arg(fmt.redBufferSize()).arg(fmt.greenBufferSize())
1153 .arg(fmt.blueBufferSize()).arg(fmt.alphaBufferSize()));
1158 const QRect Destination,
int Rotation, qreal Scale)
1160 if (!Texture || Texture->
m_size.isEmpty())
1172 QSize size = Texture->
m_size;
1174 int width = Texture->
m_crop ? std::min(
Source.width(), size.width()) :
Source.width();
1175 int height = Texture->
m_crop ? std::min(
Source.height(), size.height()) :
Source.height();
1177 if (Texture->
m_target != QOpenGLTexture::TargetRectangle)
1180 data[(Texture->
m_flip ? 7 : 1) +
TEX_OFFSET] = (
Source.top() + height) /
static_cast<GLfloat
>(size.height());
1181 data[6 +
TEX_OFFSET] = (
Source.left() + width) /
static_cast<GLfloat
>(size.width());
1197 width = Texture->
m_crop ? std::min(
static_cast<int>(width * Scale), Destination.width()) : Destination.width();
1198 height = Texture->
m_crop ? std::min(
static_cast<int>(height * Scale), Destination.height()) : Destination.height();
1200 data[2] = data[0] = Destination.left();
1201 data[5] = data[1] = Destination.top();
1202 data[4] = data[6] = Destination.left() + width;
1203 data[3] = data[7] = Destination.top() + height;
1243 uint64_t ref = (
static_cast<uint64_t
>(Area.left()) & 0xfff) +
1244 ((
static_cast<uint64_t
>(Area.top()) & 0xfff) << 12) +
1245 ((
static_cast<uint64_t
>(Area.width()) & 0xfff) << 24) +
1246 ((
static_cast<uint64_t
>(Area.height()) & 0xfff) << 36) +
1247 ((
static_cast<uint64_t
>(
Type & 0xfff)) << 48);
1256 auto *vertices =
new GLfloat[8];
1258 vertices[2] = vertices[0] = Area.left();
1259 vertices[5] = vertices[1] = Area.top();
1260 vertices[4] = vertices[6] = Area.left() + Area.width();
1261 vertices[3] = vertices[7] = Area.top() + Area.height();
1263 if (
Type == GL_LINE_LOOP)
1265 vertices[7] = vertices[1];
1266 vertices[5] = vertices[3];
1282 GLfloat *vertices =
nullptr;
1292 uint64_t ref = (
static_cast<uint64_t
>(Area.left()) & 0xfff) +
1293 ((
static_cast<uint64_t
>(Area.top()) & 0xfff) << 12) +
1294 ((
static_cast<uint64_t
>(Area.width()) & 0xfff) << 24) +
1295 ((
static_cast<uint64_t
>(Area.height()) & 0xfff) << 36) +
1296 ((
static_cast<uint64_t
>(
Type & 0xfff)) << 48);
1313 void* target = vbo->map(QOpenGLBuffer::WriteOnly);
1347 case QOpenGLTexture::RGBA_Integer:
1348 case QOpenGLTexture::BGRA_Integer:
1349 case QOpenGLTexture::BGRA:
1350 case QOpenGLTexture::RGBA: bpp = 4;
break;
1351 case QOpenGLTexture::RGB_Integer:
1352 case QOpenGLTexture::BGR_Integer:
1353 case QOpenGLTexture::BGR:
1354 case QOpenGLTexture::RGB: bpp = 3;
break;
1355 case QOpenGLTexture::RG_Integer:
1356 case QOpenGLTexture::RG: bpp = 2;
break;
1357 case QOpenGLTexture::Red:
1358 case QOpenGLTexture::Red_Integer:
1359 case QOpenGLTexture::Alpha:
1360 case QOpenGLTexture::Luminance: bpp = 1;
break;
1366 case QOpenGLTexture::Int8:
bytes =
sizeof(GLbyte);
break;
1367 case QOpenGLTexture::UInt8:
bytes =
sizeof(GLubyte);
break;
1368 case QOpenGLTexture::Int16:
bytes =
sizeof(GLshort);
break;
1369 case QOpenGLTexture::UInt16:
bytes =
sizeof(GLushort);
break;
1370 case QOpenGLTexture::Int32:
bytes =
sizeof(GLint);
break;
1371 case QOpenGLTexture::UInt32:
bytes =
sizeof(GLuint);
break;
1372 case QOpenGLTexture::Float32:
bytes =
sizeof(GLfloat);
break;
1373 case QOpenGLTexture::UInt32_RGB10A2:
bytes =
sizeof(GLuint);
break;
1377 if (!bpp || !
bytes || Size.isEmpty())
1380 return Size.width() * Size.height() * bpp *
bytes;
1388 newtop.translate(
static_cast<GLfloat
>(Center.x()),
static_cast<GLfloat
>(Center.y()));
1390 newtop.rotate(Fx.
m_angle, 0, 0, 1);
1391 newtop.translate(
static_cast<GLfloat
>(-Center.x()),
static_cast<GLfloat
>(-Center.y()));
1403 QString
type =
Source.isEmpty() ?
"Shader link" :
"Shader compile";
1404 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"%1 error").arg(
type));
1405 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Log:"));
1406 LOG(VB_GENERAL, LOG_ERR,
"\n" + Shader->log());
1409 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Source:"));
1410 LOG(VB_GENERAL, LOG_ERR,
"\n" +
Source);
1424 auto *program =
new QOpenGLShaderProgram();
1425 if (!program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertex))
1427 if (!program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragment))
1431 QList<QOpenGLShader*> shaders = program->shaders();
1432 for (QOpenGLShader* shader : qAsConst(shaders))
1433 LOG(VB_GENERAL, LOG_DEBUG,
"\n" + shader->sourceCode());
1435 program->bindAttributeLocation(
"a_position",
VERTEX_INDEX);
1436 program->bindAttributeLocation(
"a_color",
COLOR_INDEX);
1437 program->bindAttributeLocation(
"a_texcoord0",
TEXTURE_INDEX);
1438 if (!program->link())
1449 auto *program =
new QOpenGLShaderProgram();
1450 if (!program->addShaderFromSourceCode(QOpenGLShader::Compute,
Source))
1455 QList<QOpenGLShader*> shaders = program->shaders();
1456 for (QOpenGLShader* shader : qAsConst(shaders))
1457 LOG(VB_GENERAL, LOG_DEBUG,
"\n" + shader->sourceCode());
1460 if (!program->link())
1506 QString tag = QString(
"%1-%2").arg(Program->programId()).arg(Uniform);
1510 else if (!qFuzzyCompare(Value, it.value()))
1516 QByteArray uniform(Uniform);
1519 if (uniforms.contains(uniform))
1521 location = uniforms[uniform];
1525 location = Program->uniformLocation(Uniform);
1526 uniforms.insert(uniform, location);
1529 Program->setUniformValue(location, Value);
1563 GLint dedicated = 0;
1564 GLint available = 0;
1568 return { total / 1024, dedicated / 1024, available / 1024 };
1586 QSize size{256, 256};