summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVal Doroshchuk <valentyn.doroshchuk@qt.io>2017-10-24 14:45:29 +0200
committerVaL Doroshchuk <valentyn.doroshchuk@qt.io>2017-11-30 09:24:42 +0000
commit06eac9ba70ace125ea2835ef9aec854f231405b2 (patch)
tree6b2941d3b17abe3c6167240227a71373fd55526e
parenta621c53dd9103c3d41cb16763f7b7dba372b67a6 (diff)
downloadqtmultimedia-06eac9ba70ace125ea2835ef9aec854f231405b2.tar.gz
Windows: Fix EVR's rendering of GLTextureHandle frames
When ANGLE is used and video frames have GLTextureHandle handle type black screen is shown while audio is working correctly. Fixed a bug when opengl texture has not been ever creating. Fixed a crash when releasing resources due to empty QOpenGLContext. Also moved gl initialization related code to OpenGLResources. Task-number: QTBUG-61407 Change-Id: Ifc92a4a2fa2e769494ef962203446a9b3e7dd86d Reviewed-by: Christian Stromme <christian.stromme@qt.io>
-rw-r--r--src/plugins/common/evr/evrd3dpresentengine.cpp159
1 files changed, 86 insertions, 73 deletions
diff --git a/src/plugins/common/evr/evrd3dpresentengine.cpp b/src/plugins/common/evr/evrd3dpresentengine.cpp
index 043d0ad73..754faef2d 100644
--- a/src/plugins/common/evr/evrd3dpresentengine.cpp
+++ b/src/plugins/common/evr/evrd3dpresentengine.cpp
@@ -47,6 +47,7 @@
#include <QDebug>
#include <qthread.h>
#include <private/qmediaopenglhelper_p.h>
+#include <QOffscreenSurface>
#ifdef MAYBE_ANGLE
# include <qtgui/qguiapplication.h>
@@ -128,11 +129,65 @@ class OpenGLResources : public QObject
{
public:
OpenGLResources()
- : egl(new EGLWrapper)
- , eglDisplay(0)
- , eglSurface(0)
- , glTexture(0)
- {}
+ : m_egl(new EGLWrapper)
+ , m_eglDisplay(nullptr)
+ , m_eglSurface(nullptr)
+ , m_glTexture(0)
+ , m_glContext(QOpenGLContext::currentContext())
+ {
+ Q_ASSERT(m_glContext);
+ }
+
+ unsigned int glTexture() const
+ {
+ return m_glTexture;
+ }
+
+ bool createTexture(const QVideoSurfaceFormat &format, IDirect3DDevice9Ex *device,
+ IDirect3DTexture9 **texture)
+ {
+ if (!m_glContext)
+ return false;
+
+ m_glContext->functions()->glGenTextures(1, &m_glTexture);
+ QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
+ m_eglDisplay = static_cast<EGLDisplay*>(
+ nativeInterface->nativeResourceForContext("eglDisplay", m_glContext));
+ EGLConfig *eglConfig = static_cast<EGLConfig*>(
+ nativeInterface->nativeResourceForContext("eglConfig", m_glContext));
+
+ const bool hasAlpha = m_glContext->format().hasAlpha();
+
+ EGLint attribs[] = {
+ EGL_WIDTH, format.frameWidth(),
+ EGL_HEIGHT, format.frameHeight(),
+ EGL_TEXTURE_FORMAT, (hasAlpha ? EGL_TEXTURE_RGBA : EGL_TEXTURE_RGB),
+ EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
+ EGL_NONE
+ };
+
+ m_eglSurface = m_egl->createPbufferSurface(m_eglDisplay, eglConfig, attribs);
+
+ HANDLE share_handle = 0;
+ PFNEGLQUERYSURFACEPOINTERANGLEPROC eglQuerySurfacePointerANGLE =
+ reinterpret_cast<PFNEGLQUERYSURFACEPOINTERANGLEPROC>(
+ m_egl->getProcAddress("eglQuerySurfacePointerANGLE"));
+ Q_ASSERT(eglQuerySurfacePointerANGLE);
+ eglQuerySurfacePointerANGLE(
+ m_eglDisplay,
+ m_eglSurface,
+ EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, &share_handle);
+
+ device->CreateTexture(format.frameWidth(), format.frameHeight(), 1,
+ D3DUSAGE_RENDERTARGET,
+ (hasAlpha ? D3DFMT_A8R8G8B8 : D3DFMT_X8R8G8B8),
+ D3DPOOL_DEFAULT, texture, &share_handle);
+
+ m_glContext->functions()->glBindTexture(GL_TEXTURE_2D, m_glTexture);
+ m_egl->bindTexImage(m_eglDisplay, m_eglSurface, EGL_BACK_BUFFER);
+
+ return texture != NULL;
+ }
void release()
{
@@ -142,24 +197,32 @@ public:
deleteLater();
}
- EGLWrapper *egl;
- EGLDisplay *eglDisplay;
- EGLSurface eglSurface;
- unsigned int glTexture;
-
private:
+ EGLWrapper *m_egl;
+ EGLDisplay *m_eglDisplay;
+ EGLSurface m_eglSurface;
+ unsigned int m_glTexture;
+ QOpenGLContext *m_glContext;
+
~OpenGLResources()
{
- Q_ASSERT(QOpenGLContext::currentContext() != NULL);
+ QScopedPointer<QOffscreenSurface> surface;
+ if (m_glContext != QOpenGLContext::currentContext()) {
+ surface.reset(new QOffscreenSurface);
+ surface->create();
+ m_glContext->makeCurrent(surface.data());
+ }
- if (eglSurface && egl) {
- egl->releaseTexImage(eglDisplay, eglSurface, EGL_BACK_BUFFER);
- egl->destroySurface(eglDisplay, eglSurface);
+ if (m_eglSurface && m_egl) {
+ m_egl->releaseTexImage(m_eglDisplay, m_eglSurface, EGL_BACK_BUFFER);
+ m_egl->destroySurface(m_eglDisplay, m_eglSurface);
}
- if (glTexture)
- QOpenGLContext::currentContext()->functions()->glDeleteTextures(1, &glTexture);
+ if (m_glTexture)
+ m_glContext->functions()->glDeleteTextures(1, &m_glTexture);
- delete egl;
+ delete m_egl;
+ if (surface)
+ m_glContext->doneCurrent();
}
};
@@ -257,9 +320,9 @@ QVariant IMFSampleVideoBuffer::handle() const
if (handleType() != GLTextureHandle)
return handle;
- if (m_engine->m_glResources && (m_textureUpdated || m_engine->updateTexture(m_surface))) {
+ if (m_textureUpdated || m_engine->updateTexture(m_surface)) {
m_textureUpdated = true;
- handle = QVariant::fromValue<unsigned int>(m_engine->m_glResources->glTexture);
+ handle = QVariant::fromValue<unsigned int>(m_engine->m_glResources->glTexture());
}
#endif
@@ -553,61 +616,11 @@ QVideoFrame D3DPresentEngine::makeVideoFrame(IMFSample *sample)
bool D3DPresentEngine::createRenderTexture()
{
- if (m_texture)
- return true;
-
- Q_ASSERT(QOpenGLContext::currentContext() != NULL);
-
- if (!m_glResources)
- m_glResources = new OpenGLResources;
-
- QOpenGLContext *currentContext = QOpenGLContext::currentContext();
- if (!currentContext)
- return false;
-
- QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
- m_glResources->eglDisplay = static_cast<EGLDisplay*>(
- nativeInterface->nativeResourceForContext("eglDisplay", currentContext));
- EGLConfig *eglConfig = static_cast<EGLConfig*>(
- nativeInterface->nativeResourceForContext("eglConfig", currentContext));
-
- currentContext->functions()->glGenTextures(1, &m_glResources->glTexture);
-
- bool hasAlpha = currentContext->format().hasAlpha();
-
- EGLint attribs[] = {
- EGL_WIDTH, m_surfaceFormat.frameWidth(),
- EGL_HEIGHT, m_surfaceFormat.frameHeight(),
- EGL_TEXTURE_FORMAT, hasAlpha ? EGL_TEXTURE_RGBA : EGL_TEXTURE_RGB,
- EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
- EGL_NONE
- };
-
- EGLSurface pbuffer = m_glResources->egl->createPbufferSurface(m_glResources->eglDisplay, eglConfig, attribs);
-
- HANDLE share_handle = 0;
- PFNEGLQUERYSURFACEPOINTERANGLEPROC eglQuerySurfacePointerANGLE =
- reinterpret_cast<PFNEGLQUERYSURFACEPOINTERANGLEPROC>(m_glResources->egl->getProcAddress("eglQuerySurfacePointerANGLE"));
- Q_ASSERT(eglQuerySurfacePointerANGLE);
- eglQuerySurfacePointerANGLE(
- m_glResources->eglDisplay,
- pbuffer,
- EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, &share_handle);
-
-
- m_device->CreateTexture(m_surfaceFormat.frameWidth(), m_surfaceFormat.frameHeight(), 1,
- D3DUSAGE_RENDERTARGET,
- hasAlpha ? D3DFMT_A8R8G8B8 : D3DFMT_X8R8G8B8,
- D3DPOOL_DEFAULT,
- &m_texture,
- &share_handle);
-
- m_glResources->eglSurface = pbuffer;
-
- QOpenGLContext::currentContext()->functions()->glBindTexture(GL_TEXTURE_2D, m_glResources->glTexture);
- m_glResources->egl->bindTexImage(m_glResources->eglDisplay, m_glResources->eglSurface, EGL_BACK_BUFFER);
+ if (m_glResources)
+ m_glResources->release();
- return m_texture != NULL;
+ m_glResources = new OpenGLResources;
+ return m_glResources->createTexture(m_surfaceFormat, m_device, &m_texture);
}
bool D3DPresentEngine::updateTexture(IDirect3DSurface9 *src)