AVFoundation: don't use shared OpenGL contexts unless needed.

We were always using shared OpenGL contexts to render media player
frames into an OpenGL texture. There's no need to do that when there
already is a current context on the current thread. This happens in
non-QtQuick cases, when the OpenGL thread is also the main thread.

Change-Id: Icb97ed49609c764263007a43b6bb481e23768111
Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
This commit is contained in:
Yoann Lopes
2015-06-08 18:09:23 +02:00
parent 269c64f47a
commit 3cb698c0fc

View File

@@ -50,19 +50,13 @@ AVFVideoFrameRenderer::AVFVideoFrameRenderer(QAbstractVideoSurface *surface, QOb
: QObject(parent) : QObject(parent)
, m_videoLayerRenderer(0) , m_videoLayerRenderer(0)
, m_surface(surface) , m_surface(surface)
, m_offscreenSurface(0)
, m_glContext(0) , m_glContext(0)
, m_currentBuffer(1) , m_currentBuffer(1)
, m_isContextShared(true) , m_isContextShared(true)
{ {
m_fbo[0] = 0; m_fbo[0] = 0;
m_fbo[1] = 0; m_fbo[1] = 0;
//Create Hidden QWindow surface to create context in this thread
m_offscreenSurface = new QWindow();
m_offscreenSurface->setSurfaceType(QWindow::OpenGLSurface);
//Needs geometry to be a valid surface, but size is not important
m_offscreenSurface->setGeometry(0, 0, 1, 1);
m_offscreenSurface->create();
} }
AVFVideoFrameRenderer::~AVFVideoFrameRenderer() AVFVideoFrameRenderer::~AVFVideoFrameRenderer()
@@ -94,7 +88,8 @@ GLuint AVFVideoFrameRenderer::renderLayerToTexture(AVPlayerLayer *layer)
return 0; return 0;
renderLayerToFBO(layer, fbo); renderLayerToFBO(layer, fbo);
m_glContext->doneCurrent(); if (m_glContext)
m_glContext->doneCurrent();
return fbo->texture(); return fbo->texture();
} }
@@ -113,7 +108,8 @@ QImage AVFVideoFrameRenderer::renderLayerToImage(AVPlayerLayer *layer)
renderLayerToFBO(layer, fbo); renderLayerToFBO(layer, fbo);
QImage fboImage = fbo->toImage(); QImage fboImage = fbo->toImage();
m_glContext->doneCurrent(); if (m_glContext)
m_glContext->doneCurrent();
return fboImage; return fboImage;
} }
@@ -125,7 +121,14 @@ QOpenGLFramebufferObject *AVFVideoFrameRenderer::initRenderer(AVPlayerLayer *lay
m_targetSize = QSize(layer.bounds.size.width, layer.bounds.size.height); m_targetSize = QSize(layer.bounds.size.width, layer.bounds.size.height);
//Make sure we have an OpenGL context to make current //Make sure we have an OpenGL context to make current
if (!m_glContext) { if (!QOpenGLContext::currentContext() && !m_glContext) {
//Create Hidden QWindow surface to create context in this thread
m_offscreenSurface = new QWindow();
m_offscreenSurface->setSurfaceType(QWindow::OpenGLSurface);
//Needs geometry to be a valid surface, but size is not important
m_offscreenSurface->setGeometry(0, 0, 1, 1);
m_offscreenSurface->create();
//Create OpenGL context and set share context from surface //Create OpenGL context and set share context from surface
QOpenGLContext *shareContext = 0; QOpenGLContext *shareContext = 0;
if (m_surface) { if (m_surface) {
@@ -151,7 +154,8 @@ QOpenGLFramebufferObject *AVFVideoFrameRenderer::initRenderer(AVPlayerLayer *lay
} }
//Need current context //Need current context
m_glContext->makeCurrent(m_offscreenSurface); if (m_glContext)
m_glContext->makeCurrent(m_offscreenSurface);
//Create the CARenderer if needed //Create the CARenderer if needed
if (!m_videoLayerRenderer) { if (!m_videoLayerRenderer) {