summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@digia.com>2014-02-05 15:54:36 +0100
committerLaszlo Agocs <laszlo.agocs@digia.com>2014-07-29 12:18:37 +0200
commit66ba21971b24942c7481eeb4a4ff156f54ea658a (patch)
tree15cd4c61a7c9966e9a2f2ce7732bf5dcf736daf9 /src/plugins
parent49cde1b2c4cdc44d1efd5f2d34b58d6a4fda56c8 (diff)
Support dynamic opengl32 - ANGLE switching on Windows
Change-Id: I38532db3ab0ad4fcb8dbabd0cbb528f7d8e4ba06 Reviewed-by: Andrew Knight <andrew.knight@digia.com> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/wmf/evrd3dpresentengine.cpp85
-rw-r--r--src/plugins/wmf/evrd3dpresentengine.h26
-rw-r--r--src/plugins/wmf/player/mfvideorenderercontrol.cpp32
-rw-r--r--src/plugins/wmf/player/mfvideorenderercontrol.h4
-rw-r--r--src/plugins/wmf/player/player.pri2
-rw-r--r--src/plugins/wmf/wmf.pro2
6 files changed, 121 insertions, 30 deletions
diff --git a/src/plugins/wmf/evrd3dpresentengine.cpp b/src/plugins/wmf/evrd3dpresentengine.cpp
index 01a5c3341..8af76403e 100644
--- a/src/plugins/wmf/evrd3dpresentengine.cpp
+++ b/src/plugins/wmf/evrd3dpresentengine.cpp
@@ -51,6 +51,7 @@
#include <qvideoframe.h>
#include <QDebug>
#include <qopenglcontext.h>
+#include <qopenglfunctions.h>
#include <qwindow.h>
#include <EGL/egl.h>
@@ -88,6 +89,67 @@ private:
GLuint m_textureId;
};
+EGLWrapper::EGLWrapper()
+{
+#ifndef QT_OPENGL_ES_2_ANGLE_STATIC
+ // Resolve the EGL functions we use. When configured for dynamic OpenGL, no
+ // component in Qt will link to libEGL.lib and libGLESv2.lib. We know
+ // however that libEGL is loaded for sure, since this is an ANGLE-only path.
+
+# ifdef QT_DEBUG
+ HMODULE eglHandle = GetModuleHandle(L"libEGLd.dll");
+# else
+ HMODULE eglHandle = GetModuleHandle(L"libEGL.dll");
+# endif
+
+ if (!eglHandle)
+ qWarning("No EGL library loaded");
+
+ m_eglGetProcAddress = (EglGetProcAddress) GetProcAddress(eglHandle, "eglGetProcAddress");
+ m_eglCreatePbufferSurface = (EglCreatePbufferSurface) GetProcAddress(eglHandle, "eglCreatePbufferSurface");
+ m_eglDestroySurface = (EglDestroySurface) GetProcAddress(eglHandle, "eglDestroySurface");
+ m_eglBindTexImage = (EglBindTexImage) GetProcAddress(eglHandle, "eglBindTexImage");
+ m_eglReleaseTexImage = (EglReleaseTexImage) GetProcAddress(eglHandle, "eglReleaseTexImage");
+#else
+ // Static ANGLE-only build. There is no libEGL.dll in use.
+
+ m_eglGetProcAddress = ::eglGetProcAddress;
+ m_eglCreatePbufferSurface = ::eglCreatePbufferSurface;
+ m_eglDestroySurface = ::eglDestroySurface;
+ m_eglBindTexImage = ::eglBindTexImage;
+ m_eglReleaseTexImage = ::eglReleaseTexImage;
+#endif
+}
+
+__eglMustCastToProperFunctionPointerType EGLWrapper::getProcAddress(const char *procname)
+{
+ Q_ASSERT(m_eglGetProcAddress);
+ return m_eglGetProcAddress(procname);
+}
+
+EGLSurface EGLWrapper::createPbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
+{
+ Q_ASSERT(m_eglCreatePbufferSurface);
+ return m_eglCreatePbufferSurface(dpy, config, attrib_list);
+}
+
+EGLBoolean EGLWrapper::destroySurface(EGLDisplay dpy, EGLSurface surface)
+{
+ Q_ASSERT(m_eglDestroySurface);
+ return m_eglDestroySurface(dpy, surface);
+}
+
+EGLBoolean EGLWrapper::bindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+ Q_ASSERT(m_eglBindTexImage);
+ return m_eglBindTexImage(dpy, surface, buffer);
+}
+
+EGLBoolean EGLWrapper::releaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+ Q_ASSERT(m_eglReleaseTexImage);
+ return m_eglReleaseTexImage(dpy, surface, buffer);
+}
D3DPresentEngine::D3DPresentEngine()
: QObject()
@@ -104,6 +166,7 @@ D3DPresentEngine::D3DPresentEngine()
, m_eglSurface(0)
, m_glTexture(0)
, m_texture(0)
+ , m_egl(0)
{
ZeroMemory(&m_displayMode, sizeof(m_displayMode));
@@ -126,15 +189,16 @@ D3DPresentEngine::~D3DPresentEngine()
qt_wmf_safeRelease(&m_D3D9);
if (m_eglSurface) {
- eglReleaseTexImage(m_eglDisplay, m_eglSurface, EGL_BACK_BUFFER);
- eglDestroySurface(m_eglDisplay, m_eglSurface);
+ m_egl->releaseTexImage(m_eglDisplay, m_eglSurface, EGL_BACK_BUFFER);
+ m_egl->destroySurface(m_eglDisplay, m_eglSurface);
m_eglSurface = NULL;
}
if (m_glTexture)
- glDeleteTextures(1, &m_glTexture);
+ QOpenGLContext::currentContext()->functions()->glDeleteTextures(1, &m_glTexture);
delete m_glContext;
delete m_offscreenSurface;
+ delete m_egl;
}
void D3DPresentEngine::start()
@@ -358,14 +422,16 @@ void D3DPresentEngine::createOffscreenTexture()
if (m_glContext)
m_glContext->makeCurrent(m_offscreenSurface);
+ if (!m_egl)
+ m_egl = new EGLWrapper;
+
QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
m_eglDisplay = static_cast<EGLDisplay*>(
nativeInterface->nativeResourceForContext("eglDisplay", currentContext));
m_eglConfig = static_cast<EGLDisplay*>(
nativeInterface->nativeResourceForContext("eglConfig", currentContext));
- glGenTextures(1, &m_glTexture);
-
+ currentContext->functions()->glGenTextures(1, &m_glTexture);
int w = m_surfaceFormat.frameWidth();
int h = m_surfaceFormat.frameHeight();
@@ -378,11 +444,12 @@ void D3DPresentEngine::createOffscreenTexture()
EGL_NONE
};
- EGLSurface pbuffer = eglCreatePbufferSurface(m_eglDisplay, m_eglConfig, attribs);
+ EGLSurface pbuffer = m_egl->createPbufferSurface(m_eglDisplay, m_eglConfig, attribs);
HANDLE share_handle = 0;
PFNEGLQUERYSURFACEPOINTERANGLEPROC eglQuerySurfacePointerANGLE =
- reinterpret_cast<PFNEGLQUERYSURFACEPOINTERANGLEPROC>(eglGetProcAddress("eglQuerySurfacePointerANGLE"));
+ reinterpret_cast<PFNEGLQUERYSURFACEPOINTERANGLEPROC>(m_egl->getProcAddress("eglQuerySurfacePointerANGLE"));
+ Q_ASSERT(eglQuerySurfacePointerANGLE);
eglQuerySurfacePointerANGLE(
m_eglDisplay,
pbuffer,
@@ -410,7 +477,7 @@ bool D3DPresentEngine::updateTexture(IDirect3DSurface9 *src)
if (m_glContext)
m_glContext->makeCurrent(m_offscreenSurface);
- glBindTexture(GL_TEXTURE_2D, m_glTexture);
+ QOpenGLContext::currentContext()->functions()->glBindTexture(GL_TEXTURE_2D, m_glTexture);
IDirect3DSurface9 *dest = NULL;
@@ -424,7 +491,7 @@ bool D3DPresentEngine::updateTexture(IDirect3DSurface9 *src)
qWarning("Failed to copy D3D surface");
if (hr == S_OK)
- eglBindTexImage(m_eglDisplay, m_eglSurface, EGL_BACK_BUFFER);
+ m_egl->bindTexImage(m_eglDisplay, m_eglSurface, EGL_BACK_BUFFER);
done:
qt_wmf_safeRelease(&dest);
diff --git a/src/plugins/wmf/evrd3dpresentengine.h b/src/plugins/wmf/evrd3dpresentengine.h
index 87b3e9606..42b65f291 100644
--- a/src/plugins/wmf/evrd3dpresentengine.h
+++ b/src/plugins/wmf/evrd3dpresentengine.h
@@ -70,6 +70,31 @@ QT_BEGIN_NAMESPACE
class QAbstractVideoSurface;
class QOpenGLContext;
+class EGLWrapper
+{
+public:
+ EGLWrapper();
+
+ __eglMustCastToProperFunctionPointerType getProcAddress(const char *procname);
+ EGLSurface createPbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
+ EGLBoolean destroySurface(EGLDisplay dpy, EGLSurface surface);
+ EGLBoolean bindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+ EGLBoolean releaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+
+private:
+ typedef __eglMustCastToProperFunctionPointerType (EGLAPIENTRYP EglGetProcAddress)(const char *procname);
+ typedef EGLSurface (EGLAPIENTRYP EglCreatePbufferSurface)(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
+ typedef EGLBoolean (EGLAPIENTRYP EglDestroySurface)(EGLDisplay dpy, EGLSurface surface);
+ typedef EGLBoolean (EGLAPIENTRYP EglBindTexImage)(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+ typedef EGLBoolean (EGLAPIENTRYP EglReleaseTexImage)(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+
+ EglGetProcAddress m_eglGetProcAddress;
+ EglCreatePbufferSurface m_eglCreatePbufferSurface;
+ EglDestroySurface m_eglDestroySurface;
+ EglBindTexImage m_eglBindTexImage;
+ EglReleaseTexImage m_eglReleaseTexImage;
+};
+
class D3DPresentEngine : public QObject
{
Q_OBJECT
@@ -123,6 +148,7 @@ private:
EGLSurface m_eglSurface;
unsigned int m_glTexture;
IDirect3DTexture9 *m_texture;
+ EGLWrapper *m_egl;
};
QT_END_NAMESPACE
diff --git a/src/plugins/wmf/player/mfvideorenderercontrol.cpp b/src/plugins/wmf/player/mfvideorenderercontrol.cpp
index 420473666..d4e4930ca 100644
--- a/src/plugins/wmf/player/mfvideorenderercontrol.cpp
+++ b/src/plugins/wmf/player/mfvideorenderercontrol.cpp
@@ -41,9 +41,15 @@
#include "mfvideorenderercontrol.h"
#include "mfglobal.h"
-#ifdef QT_OPENGL_ES_2_ANGLE
+
+#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
+#define MAYBE_ANGLE
+#endif
+
+#ifdef MAYBE_ANGLE
#include "evrcustompresenter.h"
#endif
+
#include <qabstractvideosurface.h>
#include <qvideosurfaceformat.h>
#include <qtcore/qtimer.h>
@@ -53,6 +59,7 @@
#include <qtcore/qthread.h>
#include "guiddef.h"
#include <qtcore/qdebug.h>
+#include <QtMultimedia/private/qmediaopenglhelper_p.h>
//#define DEBUG_MEDIAFOUNDATION
#define PAD_TO_DWORD(x) (((x) + 3) & ~3)
@@ -2228,9 +2235,7 @@ MFVideoRendererControl::MFVideoRendererControl(QObject *parent)
, m_surface(0)
, m_currentActivate(0)
, m_callback(0)
-#ifdef QT_OPENGL_ES_2_ANGLE
, m_presenterActivate(0)
-#endif
{
}
@@ -2244,7 +2249,7 @@ void MFVideoRendererControl::clear()
if (m_surface)
m_surface->stop();
-#ifdef QT_OPENGL_ES_2_ANGLE
+#ifdef MAYBE_ANGLE
if (m_presenterActivate) {
m_presenterActivate->ShutdownObject();
m_presenterActivate->Release();
@@ -2279,7 +2284,7 @@ void MFVideoRendererControl::setSurface(QAbstractVideoSurface *surface)
connect(m_surface, SIGNAL(supportedFormatsChanged()), this, SLOT(supportedFormatsChanged()));
}
-#ifdef QT_OPENGL_ES_2_ANGLE
+#ifdef MAYBE_ANGLE
if (m_presenterActivate)
m_presenterActivate->setSurface(m_surface);
else
@@ -2290,10 +2295,8 @@ void MFVideoRendererControl::setSurface(QAbstractVideoSurface *surface)
void MFVideoRendererControl::customEvent(QEvent *event)
{
-#ifdef QT_OPENGL_ES_2_ANGLE
if (m_presenterActivate)
return;
-#endif
if (!m_currentActivate)
return;
@@ -2324,7 +2327,7 @@ void MFVideoRendererControl::customEvent(QEvent *event)
void MFVideoRendererControl::supportedFormatsChanged()
{
-#ifdef QT_OPENGL_ES_2_ANGLE
+#ifdef MAYBE_ANGLE
if (m_presenterActivate)
m_presenterActivate->supportedFormatsChanged();
else
@@ -2335,10 +2338,8 @@ void MFVideoRendererControl::supportedFormatsChanged()
void MFVideoRendererControl::present()
{
-#ifdef QT_OPENGL_ES_2_ANGLE
if (m_presenterActivate)
return;
-#endif
if (m_currentActivate)
static_cast<VideoRendererActivate*>(m_currentActivate)->present();
@@ -2350,20 +2351,21 @@ IMFActivate* MFVideoRendererControl::createActivate()
clear();
-#ifdef QT_OPENGL_ES_2_ANGLE
+#ifdef MAYBE_ANGLE
// We can use the EVR with our custom presenter only if the surface supports OpenGL
- // texture handles
- if (!m_surface->supportedPixelFormats(QAbstractVideoBuffer::GLTextureHandle).isEmpty()) {
+ // texture handles. We also require ANGLE (due to the D3D interop).
+ if (!m_surface->supportedPixelFormats(QAbstractVideoBuffer::GLTextureHandle).isEmpty()
+ && QMediaOpenGLHelper::isANGLE()) {
// Create the EVR media sink, but replace the presenter with our own
if (SUCCEEDED(MFCreateVideoRendererActivate(::GetShellWindow(), &m_currentActivate))) {
m_presenterActivate = new EVRCustomPresenterActivate;
m_currentActivate->SetUnknown(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_ACTIVATE, m_presenterActivate);
}
}
+#endif
if (!m_currentActivate)
-#endif
- m_currentActivate = new VideoRendererActivate(this);
+ m_currentActivate = new VideoRendererActivate(this);
setSurface(m_surface);
diff --git a/src/plugins/wmf/player/mfvideorenderercontrol.h b/src/plugins/wmf/player/mfvideorenderercontrol.h
index d796ce36d..1c05a656f 100644
--- a/src/plugins/wmf/player/mfvideorenderercontrol.h
+++ b/src/plugins/wmf/player/mfvideorenderercontrol.h
@@ -48,9 +48,7 @@
QT_BEGIN_NAMESPACE
-#ifdef QT_OPENGL_ES_2_ANGLE
class EVRCustomPresenterActivate;
-#endif
QT_END_NAMESPACE
@@ -83,9 +81,7 @@ private:
IMFActivate *m_currentActivate;
IMFSampleGrabberSinkCallback *m_callback;
-#ifdef QT_OPENGL_ES_2_ANGLE
EVRCustomPresenterActivate *m_presenterActivate;
-#endif
};
#endif
diff --git a/src/plugins/wmf/player/player.pri b/src/plugins/wmf/player/player.pri
index a72708b3f..dd5c9dc12 100644
--- a/src/plugins/wmf/player/player.pri
+++ b/src/plugins/wmf/player/player.pri
@@ -1,6 +1,6 @@
INCLUDEPATH += $$PWD
-LIBS += -lstrmiids -ldmoguids -luuid -lmsdmo -lole32 -loleaut32 -lMf -lMfuuid -lMfplat -lPropsys
+LIBS += -lstrmiids -ldmoguids -luuid -lmsdmo -lgdi32 -luser32 -lole32 -loleaut32 -lMf -lMfuuid -lMfplat -lPropsys
DEFINES += QMEDIA_MEDIAFOUNDATION_PLAYER
diff --git a/src/plugins/wmf/wmf.pro b/src/plugins/wmf/wmf.pro
index b1d157a9c..60fc3f641 100644
--- a/src/plugins/wmf/wmf.pro
+++ b/src/plugins/wmf/wmf.pro
@@ -32,7 +32,7 @@ SOURCES += \
mfactivate.cpp \
mfglobal.cpp
-contains(QT_CONFIG, angle) {
+contains(QT_CONFIG, angle)|contains(QT_CONFIG, dynamicgl) {
LIBS += -ld3d9 -ldxva2 -lwinmm -levr
QT += gui-private