From 8983c746ce71c9d40fe657db694a53b0c5929f71 Mon Sep 17 00:00:00 2001 From: Gus Grubba Date: Wed, 21 Oct 2015 10:23:56 -0400 Subject: [PATCH] Fixing OpenGL issues for Windows (Video Streaming) --- .../delegates/qtvideosinkdelegate.cpp | 17 +- .../painters/openglsurfacepainter.cpp | 155 ++++++++++-------- .../gstqtvideosink/painters/videomaterial.cpp | 59 ++++--- 3 files changed, 135 insertions(+), 96 deletions(-) diff --git a/src/VideoStreaming/gstqtvideosink/delegates/qtvideosinkdelegate.cpp b/src/VideoStreaming/gstqtvideosink/delegates/qtvideosinkdelegate.cpp index f03fefc3e..ef2e9e843 100644 --- a/src/VideoStreaming/gstqtvideosink/delegates/qtvideosinkdelegate.cpp +++ b/src/VideoStreaming/gstqtvideosink/delegates/qtvideosinkdelegate.cpp @@ -27,6 +27,7 @@ #include #include +#include QtVideoSinkDelegate::QtVideoSinkDelegate(GstElement *sink, QObject *parent) : BaseDelegate(sink, parent) @@ -137,20 +138,22 @@ void QtVideoSinkDelegate::setGLContext(QGLContext *context) if (m_glContext) { m_glContext->makeCurrent(); - - const QByteArray extensions(reinterpret_cast(glGetString(GL_EXTENSIONS))); - GST_LOG_OBJECT(m_sink, "Available GL extensions: %s", extensions.constData()); + QOpenGLFunctions_2_0 *funcs = QOpenGLContext::currentContext()->versionFunctions(); + if (funcs) { + const QByteArray extensions(reinterpret_cast(funcs->glGetString(GL_EXTENSIONS))); + GST_LOG_OBJECT(m_sink, "Available GL extensions: %s", extensions.constData()); #ifndef QT_OPENGL_ES - if (extensions.contains("ARB_fragment_program")) - m_supportedPainters |= ArbFp; + if (extensions.contains("ARB_fragment_program")) + m_supportedPainters |= ArbFp; #endif #ifndef QT_OPENGL_ES_2 - if (QGLShaderProgram::hasOpenGLShaderPrograms(m_glContext) + if (QGLShaderProgram::hasOpenGLShaderPrograms(m_glContext) && extensions.contains("ARB_shader_objects")) #endif - m_supportedPainters |= Glsl; + m_supportedPainters |= Glsl; + } } GST_LOG_OBJECT(m_sink, "Done setting GL context. m_supportedPainters=%x", (int) m_supportedPainters); diff --git a/src/VideoStreaming/gstqtvideosink/painters/openglsurfacepainter.cpp b/src/VideoStreaming/gstqtvideosink/painters/openglsurfacepainter.cpp index 0acbb4ab7..cd320d44d 100644 --- a/src/VideoStreaming/gstqtvideosink/painters/openglsurfacepainter.cpp +++ b/src/VideoStreaming/gstqtvideosink/painters/openglsurfacepainter.cpp @@ -23,6 +23,7 @@ #include "openglsurfacepainter.h" #include +#include #ifndef GL_TEXTURE0 # define GL_TEXTURE0 0x84C0 @@ -58,8 +59,7 @@ OpenGLSurfacePainter::OpenGLSurfacePainter() , m_videoColorMatrix(GST_VIDEO_COLOR_MATRIX_UNKNOWN) { #ifndef QT_OPENGL_ES - glActiveTexture = (_glActiveTexture) QGLContext::currentContext()->getProcAddress( - QLatin1String("glActiveTexture")); + glActiveTexture = (_glActiveTexture) QGLContext::currentContext()->getProcAddress(QLatin1String("glActiveTexture")); #endif } @@ -178,24 +178,28 @@ void OpenGLSurfacePainter::paint(quint8 *data, QPainter *painter, const PaintAreas & areas) { + QOpenGLFunctions_2_0 *funcs = QOpenGLContext::currentContext()->versionFunctions(); + if (!funcs) + return; + // if these are enabled, we need to reenable them after beginNativePainting() // has been called, as they may get disabled - bool stencilTestEnabled = glIsEnabled(GL_STENCIL_TEST); - bool scissorTestEnabled = glIsEnabled(GL_SCISSOR_TEST); + bool stencilTestEnabled = funcs->glIsEnabled(GL_STENCIL_TEST); + bool scissorTestEnabled = funcs->glIsEnabled(GL_SCISSOR_TEST); painter->beginNativePainting(); if (stencilTestEnabled) - glEnable(GL_STENCIL_TEST); + funcs->glEnable(GL_STENCIL_TEST); if (scissorTestEnabled) - glEnable(GL_SCISSOR_TEST); + funcs->glEnable(GL_SCISSOR_TEST); const GLfloat vertexCoordArray[] = QRECT_TO_GLMATRIX(areas.videoArea); - const GLfloat txLeft = areas.sourceRect.left(); - const GLfloat txRight = areas.sourceRect.right(); - const GLfloat txTop = areas.sourceRect.top(); - const GLfloat txBottom = areas.sourceRect.bottom(); + const GLfloat txLeft = areas.sourceRect.left(); + const GLfloat txRight = areas.sourceRect.right(); + const GLfloat txTop = areas.sourceRect.top(); + const GLfloat txBottom = areas.sourceRect.bottom(); const GLfloat textureCoordArray[] = { @@ -206,8 +210,8 @@ void OpenGLSurfacePainter::paint(quint8 *data, }; for (int i = 0; i < m_textureCount; ++i) { - glBindTexture(GL_TEXTURE_2D, m_textureIds[i]); - glTexImage2D( + funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[i]); + funcs->glTexImage2D( GL_TEXTURE_2D, 0, m_textureInternalFormat, @@ -217,10 +221,10 @@ void OpenGLSurfacePainter::paint(quint8 *data, m_textureFormat, m_textureType, data + m_textureOffsets[i]); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } paintImpl(painter, vertexCoordArray, textureCoordArray); @@ -392,22 +396,24 @@ ArbFpSurfacePainter::ArbFpSurfacePainter() , m_programId(0) { const QGLContext *context = QGLContext::currentContext(); - - glProgramStringARB = (_glProgramStringARB) context->getProcAddress( - QLatin1String("glProgramStringARB")); - glBindProgramARB = (_glBindProgramARB) context->getProcAddress( - QLatin1String("glBindProgramARB")); - glDeleteProgramsARB = (_glDeleteProgramsARB) context->getProcAddress( - QLatin1String("glDeleteProgramsARB")); - glGenProgramsARB = (_glGenProgramsARB) context->getProcAddress( - QLatin1String("glGenProgramsARB")); - glProgramLocalParameter4fARB = (_glProgramLocalParameter4fARB) context->getProcAddress( - QLatin1String("glProgramLocalParameter4fARB")); + glProgramStringARB = (_glProgramStringARB) context->getProcAddress( + QLatin1String("glProgramStringARB")); + glBindProgramARB = (_glBindProgramARB) context->getProcAddress( + QLatin1String("glBindProgramARB")); + glDeleteProgramsARB = (_glDeleteProgramsARB) context->getProcAddress( + QLatin1String("glDeleteProgramsARB")); + glGenProgramsARB = (_glGenProgramsARB) context->getProcAddress( + QLatin1String("glGenProgramsARB")); + glProgramLocalParameter4fARB = (_glProgramLocalParameter4fARB) context->getProcAddress( + QLatin1String("glProgramLocalParameter4fARB")); } void ArbFpSurfacePainter::init(const BufferFormat &format) { Q_ASSERT(m_textureCount == 0); + QOpenGLFunctions_2_0 *funcs = QOpenGLContext::currentContext()->versionFunctions(); + if (!funcs) + return; const char *program = 0; @@ -467,7 +473,7 @@ void ArbFpSurfacePainter::init(const BufferFormat &format) glGenProgramsARB(1, &m_programId); - GLenum glError = glGetError(); + GLenum glError = funcs->glGetError(); if (glError != GL_NO_ERROR) { throw QString("ARBfb Shader allocation error ") + QString::number(static_cast(glError), 16); @@ -479,27 +485,28 @@ void ArbFpSurfacePainter::init(const BufferFormat &format) qstrlen(program), reinterpret_cast(program)); - if ((glError = glGetError()) != GL_NO_ERROR) { - const GLubyte* errorString = glGetString(GL_PROGRAM_ERROR_STRING_ARB); - + if ((glError = funcs->glGetError()) != GL_NO_ERROR) { + const GLubyte* errorString = funcs->glGetString(GL_PROGRAM_ERROR_STRING_ARB); glDeleteProgramsARB(1, &m_programId); m_textureCount = 0; m_programId = 0; - throw QString("ARBfp Shader compile error ") + QString::number(static_cast(glError), 16) + reinterpret_cast(errorString); } else { - glGenTextures(m_textureCount, m_textureIds); + funcs->glGenTextures(m_textureCount, m_textureIds); } } } void ArbFpSurfacePainter::cleanup() { - glDeleteTextures(m_textureCount, m_textureIds); - glDeleteProgramsARB(1, &m_programId); - + QOpenGLFunctions_2_0 *funcs = QOpenGLContext::currentContext()->versionFunctions(); + if (funcs) + { + funcs->glDeleteTextures(m_textureCount, m_textureIds); + glDeleteProgramsARB(1, &m_programId); + } m_textureCount = 0; m_programId = 0; } @@ -509,8 +516,11 @@ void ArbFpSurfacePainter::paintImpl(const QPainter *painter, const GLfloat *textureCoordArray) { Q_UNUSED(painter); + QOpenGLFunctions_2_0 *funcs = QOpenGLContext::currentContext()->versionFunctions(); + if (!funcs) + return; - glEnable(GL_FRAGMENT_PROGRAM_ARB); + funcs->glEnable(GL_FRAGMENT_PROGRAM_ARB); glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_programId); glProgramLocalParameter4fARB( @@ -535,28 +545,28 @@ void ArbFpSurfacePainter::paintImpl(const QPainter *painter, m_colorMatrix(2, 2), m_colorMatrix(2, 3)); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, m_textureIds[0]); + funcs->glActiveTexture(GL_TEXTURE0); + funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[0]); if (m_textureCount == 3) { - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, m_textureIds[1]); - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, m_textureIds[2]); - glActiveTexture(GL_TEXTURE0); + funcs->glActiveTexture(GL_TEXTURE1); + funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[1]); + funcs->glActiveTexture(GL_TEXTURE2); + funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[2]); + funcs->glActiveTexture(GL_TEXTURE0); } - glVertexPointer(2, GL_FLOAT, 0, vertexCoordArray); - glTexCoordPointer(2, GL_FLOAT, 0, textureCoordArray); + funcs->glVertexPointer(2, GL_FLOAT, 0, vertexCoordArray); + funcs->glTexCoordPointer(2, GL_FLOAT, 0, textureCoordArray); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); + funcs->glEnableClientState(GL_VERTEX_ARRAY); + funcs->glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + funcs->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisable(GL_FRAGMENT_PROGRAM_ARB); + funcs->glDisableClientState(GL_VERTEX_ARRAY); + funcs->glDisableClientState(GL_TEXTURE_COORD_ARRAY); + funcs->glDisable(GL_FRAGMENT_PROGRAM_ARB); } #endif @@ -724,14 +734,19 @@ void GlslSurfacePainter::init(const BufferFormat &format) throw QString("Shader link error ") + m_program.log(); } - glGenTextures(m_textureCount, m_textureIds); + QOpenGLFunctions_2_0 *funcs = QOpenGLContext::currentContext()->versionFunctions(); + if (funcs) + funcs->glGenTextures(m_textureCount, m_textureIds); } void GlslSurfacePainter::cleanup() { - glDeleteTextures(m_textureCount, m_textureIds); - m_program.removeAllShaders(); - + QOpenGLFunctions_2_0 *funcs = QOpenGLContext::currentContext()->versionFunctions(); + if (funcs) + { + funcs->glDeleteTextures(m_textureCount, m_textureIds); + m_program.removeAllShaders(); + } m_textureCount = 0; } @@ -739,8 +754,8 @@ void GlslSurfacePainter::paintImpl(const QPainter *painter, const GLfloat *vertexCoordArray, const GLfloat *textureCoordArray) { - const int deviceWidth = painter->device()->width(); - const int deviceHeight = painter->device()->height(); + const int deviceWidth = painter->device()->width(); + const int deviceHeight = painter->device()->height(); const QTransform transform = painter->deviceTransform(); @@ -780,27 +795,31 @@ void GlslSurfacePainter::paintImpl(const QPainter *painter, m_program.setAttributeArray("textureCoordArray", textureCoordArray, 2); m_program.setUniformValue("positionMatrix", positionMatrix); + QOpenGLFunctions_2_0 *funcs = QOpenGLContext::currentContext()->versionFunctions(); + if (funcs) + return; + if (m_textureCount == 3) { - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, m_textureIds[0]); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, m_textureIds[1]); - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, m_textureIds[2]); - glActiveTexture(GL_TEXTURE0); + funcs->glActiveTexture(GL_TEXTURE0); + funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[0]); + funcs->glActiveTexture(GL_TEXTURE1); + funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[1]); + funcs->glActiveTexture(GL_TEXTURE2); + funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[2]); + funcs->glActiveTexture(GL_TEXTURE0); m_program.setUniformValue("texY", 0); m_program.setUniformValue("texU", 1); m_program.setUniformValue("texV", 2); } else { - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, m_textureIds[0]); + funcs->glActiveTexture(GL_TEXTURE0); + funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[0]); m_program.setUniformValue("texRgb", 0); } m_program.setUniformValue("colorMatrix", m_colorMatrix); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + funcs->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); m_program.release(); } diff --git a/src/VideoStreaming/gstqtvideosink/painters/videomaterial.cpp b/src/VideoStreaming/gstqtvideosink/painters/videomaterial.cpp index 7ed24f57d..ef360cace 100644 --- a/src/VideoStreaming/gstqtvideosink/painters/videomaterial.cpp +++ b/src/VideoStreaming/gstqtvideosink/painters/videomaterial.cpp @@ -26,7 +26,7 @@ #include #include -#include +#include #include static const char * const qtvideosink_glsl_vertexShader = @@ -256,7 +256,13 @@ VideoMaterial::VideoMaterial() VideoMaterial::~VideoMaterial() { if (!m_textureSize.isEmpty()) - glDeleteTextures(m_textureCount, m_textureIds); + { + QOpenGLFunctions_2_0 *funcs = QOpenGLContext::currentContext()->versionFunctions(); + if (funcs) + { + funcs->glDeleteTextures(m_textureCount, m_textureIds); + } + } gst_buffer_replace(&m_frame, NULL); } @@ -323,9 +329,13 @@ void VideoMaterial::initYuv420PTextureInfo(bool uvSwapped, const QSize &size) void VideoMaterial::init(GstVideoColorMatrix colorMatrixType) { - glGenTextures(m_textureCount, m_textureIds); - m_colorMatrixType = colorMatrixType; - updateColors(0, 0, 0, 0); + QOpenGLFunctions_2_0 *funcs = QOpenGLContext::currentContext()->versionFunctions(); + if (funcs) + { + funcs->glGenTextures(m_textureCount, m_textureIds); + m_colorMatrixType = colorMatrixType; + updateColors(0, 0, 0, 0); + } } void VideoMaterial::setCurrentFrame(GstBuffer *buffer) @@ -411,7 +421,10 @@ void VideoMaterial::updateColors(int brightness, int contrast, int hue, int satu void VideoMaterial::bind() { - QOpenGLFunctions *functions = QOpenGLContext::currentContext()->functions(); + QOpenGLFunctions_2_0 *funcs = QOpenGLContext::currentContext()->versionFunctions(); + if (!funcs) + return; + GstBuffer *frame = NULL; m_frameMutex.lock(); @@ -422,28 +435,32 @@ void VideoMaterial::bind() if (frame) { GstMapInfo info; gst_buffer_map(frame, &info, GST_MAP_READ); - functions->glActiveTexture(GL_TEXTURE1); + funcs->glActiveTexture(GL_TEXTURE1); bindTexture(1, info.data); - functions->glActiveTexture(GL_TEXTURE2); + funcs->glActiveTexture(GL_TEXTURE2); bindTexture(2, info.data); - functions->glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit + funcs->glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit bindTexture(0, info.data); gst_buffer_unmap(frame, &info); gst_buffer_unref(frame); } else { - functions->glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, m_textureIds[1]); - functions->glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, m_textureIds[2]); - functions->glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit - glBindTexture(GL_TEXTURE_2D, m_textureIds[0]); + funcs->glActiveTexture(GL_TEXTURE1); + funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[1]); + funcs->glActiveTexture(GL_TEXTURE2); + funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[2]); + funcs->glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit + funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[0]); } } void VideoMaterial::bindTexture(int i, const quint8 *data) { - glBindTexture(GL_TEXTURE_2D, m_textureIds[i]); - glTexImage2D( + QOpenGLFunctions_2_0 *funcs = QOpenGLContext::currentContext()->versionFunctions(); + if (!funcs) + return; + + funcs->glBindTexture(GL_TEXTURE_2D, m_textureIds[i]); + funcs->glTexImage2D( GL_TEXTURE_2D, 0, m_textureInternalFormat, @@ -453,9 +470,9 @@ void VideoMaterial::bindTexture(int i, const quint8 *data) m_textureFormat, m_textureType, data + m_textureOffsets[i]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } -- 2.22.0