summaryrefslogtreecommitdiffstats
path: root/src/multimediawidgets
diff options
context:
space:
mode:
authorVaL Doroshchuk <valentyn.doroshchuk@qt.io>2019-03-12 10:28:46 +0100
committerVaL Doroshchuk <valentyn.doroshchuk@qt.io>2019-05-14 07:55:19 +0000
commit19232dbe27521f60bdd265dbac0419d93c7ea5de (patch)
treefceadad7c4c06bc9762e9864d6bd4ee89f903f01 /src/multimediawidgets
parent72101558b3afc40ef41132e66ce789b92929e911 (diff)
Use QOpenGLContext::makeCurrent if QGLContext::makeCurrent failed
If QPainterVideoSurface::setGLContext(QGLContext::currentContext()) is used and no valid paint device has been provided to QGLContext, it fails to make the context current. Thus there might be no available current context which might also produce crashes. QGLContext::currentContext() creates QGLContext based on current QOpenGLContext instance, and no paint device is available in QGLContext::device() in this case. Currently QVideoWidget and QGraphicsVideoItem are effected. It is relevant when a renderer calls currentContext->doneCurrent() before using the QPainterVideoSurface. After this there is no any current context which could cause a crash, e.g. within compiling the shaders. Task-number: QTBUG-74277 Change-Id: Ia28f4f6843a82a897399fd1ce2463e3b087b6437 Reviewed-by: Christian Strømme <christian.stromme@qt.io>
Diffstat (limited to 'src/multimediawidgets')
-rw-r--r--src/multimediawidgets/qpaintervideosurface.cpp25
1 files changed, 17 insertions, 8 deletions
diff --git a/src/multimediawidgets/qpaintervideosurface.cpp b/src/multimediawidgets/qpaintervideosurface.cpp
index e4762a7e1..440d5c858 100644
--- a/src/multimediawidgets/qpaintervideosurface.cpp
+++ b/src/multimediawidgets/qpaintervideosurface.cpp
@@ -62,6 +62,15 @@
#include <QtDebug>
QT_BEGIN_NAMESPACE
+static void makeCurrent(QGLContext *context)
+{
+ context->makeCurrent();
+
+ auto handle = context->contextHandle();
+ if (handle && QOpenGLContext::currentContext() != handle)
+ handle->makeCurrent(handle->surface());
+}
+
QVideoSurfacePainter::~QVideoSurfacePainter()
{
}
@@ -395,7 +404,7 @@ QAbstractVideoSurface::Error QVideoSurfaceGLPainter::setCurrentFrame(const QVide
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
} else if (m_frame.map(QAbstractVideoBuffer::ReadOnly)) {
- m_context->makeCurrent();
+ makeCurrent(m_context);
for (int i = 0; i < m_textureCount; ++i) {
glBindTexture(GL_TEXTURE_2D, m_textureIds[i]);
@@ -737,7 +746,7 @@ QAbstractVideoSurface::Error QVideoSurfaceArbFpPainter::start(const QVideoSurfac
QAbstractVideoSurface::Error error = QAbstractVideoSurface::NoError;
- m_context->makeCurrent();
+ makeCurrent(m_context);
const char *program = 0;
@@ -862,7 +871,7 @@ QAbstractVideoSurface::Error QVideoSurfaceArbFpPainter::start(const QVideoSurfac
void QVideoSurfaceArbFpPainter::stop()
{
if (m_context) {
- m_context->makeCurrent();
+ makeCurrent(m_context);
if (m_handleType != QAbstractVideoBuffer::GLTextureHandle)
glDeleteTextures(m_textureCount, m_textureIds);
@@ -1115,7 +1124,7 @@ QAbstractVideoSurface::Error QVideoSurfaceGlslPainter::start(const QVideoSurface
QAbstractVideoSurface::Error error = QAbstractVideoSurface::NoError;
- m_context->makeCurrent();
+ makeCurrent(m_context);
const char *fragmentProgram = 0;
@@ -1222,7 +1231,7 @@ QAbstractVideoSurface::Error QVideoSurfaceGlslPainter::start(const QVideoSurface
void QVideoSurfaceGlslPainter::stop()
{
if (m_context) {
- m_context->makeCurrent();
+ makeCurrent(m_context);
if (m_handleType != QAbstractVideoBuffer::GLTextureHandle)
glDeleteTextures(m_textureCount, m_textureIds);
@@ -1623,7 +1632,7 @@ void QPainterVideoSurface::setGLContext(QGLContext *context)
//Set a dynamic property to access the OpenGL context
this->setProperty("GLContext", QVariant::fromValue<QObject*>(m_glContext->contextHandle()));
- m_glContext->makeCurrent();
+ makeCurrent(m_glContext);
const QByteArray extensions(reinterpret_cast<const char *>(
context->contextHandle()->functions()->glGetString(GL_EXTENSIONS)));
@@ -1734,13 +1743,13 @@ void QPainterVideoSurface::createPainter()
#if !defined(QT_OPENGL_ES) && !defined(QT_OPENGL_DYNAMIC)
case FragmentProgramShader:
Q_ASSERT(m_glContext);
- m_glContext->makeCurrent();
+ makeCurrent(m_glContext);
m_painter = new QVideoSurfaceArbFpPainter(m_glContext);
break;
#endif // !QT_OPENGL_ES && !QT_OPENGL_DYNAMIC
case GlslShader:
Q_ASSERT(m_glContext);
- m_glContext->makeCurrent();
+ makeCurrent(m_glContext);
m_painter = new QVideoSurfaceGlslPainter(m_glContext);
break;
default: