summaryrefslogtreecommitdiffstats
path: root/src/plugins/wmf/evrd3dpresentengine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/wmf/evrd3dpresentengine.cpp')
-rw-r--r--src/plugins/wmf/evrd3dpresentengine.cpp171
1 files changed, 116 insertions, 55 deletions
diff --git a/src/plugins/wmf/evrd3dpresentengine.cpp b/src/plugins/wmf/evrd3dpresentengine.cpp
index 01a5c3341..42d0dea4e 100644
--- a/src/plugins/wmf/evrd3dpresentengine.cpp
+++ b/src/plugins/wmf/evrd3dpresentengine.cpp
@@ -1,40 +1,32 @@
/****************************************************************************
**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL$
+** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
+** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
** $QT_END_LICENSE$
**
****************************************************************************/
@@ -51,11 +43,11 @@
#include <qvideoframe.h>
#include <QDebug>
#include <qopenglcontext.h>
+#include <qopenglfunctions.h>
#include <qwindow.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
-#include <GLES2/gl2.h>
#include <d3d9.h>
#include <dxva2api.h>
#include <WinUser.h>
@@ -88,6 +80,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 +157,7 @@ D3DPresentEngine::D3DPresentEngine()
, m_eglSurface(0)
, m_glTexture(0)
, m_texture(0)
+ , m_egl(0)
{
ZeroMemory(&m_displayMode, sizeof(m_displayMode));
@@ -126,15 +180,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()
@@ -275,34 +330,36 @@ void D3DPresentEngine::presentSample(void *opaque, qint64)
IMFMediaBuffer* buffer = NULL;
IDirect3DSurface9* surface = NULL;
- if (sample) {
- // Get the buffer from the sample.
- hr = sample->GetBufferByIndex(0, &buffer);
- if (FAILED(hr))
- goto done;
+ if (m_surface && m_surface->isActive()) {
+ if (sample) {
+ // Get the buffer from the sample.
+ hr = sample->GetBufferByIndex(0, &buffer);
+ if (FAILED(hr))
+ goto done;
+
+ // Get the surface from the buffer.
+ hr = MFGetService(buffer, MR_BUFFER_SERVICE, IID_PPV_ARGS(&surface));
+ if (FAILED(hr))
+ goto done;
+ }
- // Get the surface from the buffer.
- hr = MFGetService(buffer, MR_BUFFER_SERVICE, IID_PPV_ARGS(&surface));
- if (FAILED(hr))
- goto done;
- }
+ if (surface && updateTexture(surface)) {
+ QVideoFrame frame = QVideoFrame(new TextureVideoBuffer(m_glTexture),
+ m_surfaceFormat.frameSize(),
+ m_surfaceFormat.pixelFormat());
- if (surface && updateTexture(surface)) {
- QVideoFrame frame = QVideoFrame(new TextureVideoBuffer(m_glTexture),
- m_surfaceFormat.frameSize(),
- m_surfaceFormat.pixelFormat());
+ // WMF uses 100-nanosecond units, Qt uses microseconds
+ LONGLONG startTime = -1;
+ if (SUCCEEDED(sample->GetSampleTime(&startTime))) {
+ frame.setStartTime(startTime * 0.1);
- // WMF uses 100-nanosecond units, Qt uses microseconds
- LONGLONG startTime = -1;
- if (SUCCEEDED(sample->GetSampleTime(&startTime))) {
- frame.setStartTime(startTime * 0.1);
+ LONGLONG duration = -1;
+ if (SUCCEEDED(sample->GetSampleDuration(&duration)))
+ frame.setEndTime((startTime + duration) * 0.1);
+ }
- LONGLONG duration = -1;
- if (SUCCEEDED(sample->GetSampleDuration(&duration)))
- frame.setEndTime((startTime + duration) * 0.1);
+ m_surface->present(frame);
}
-
- m_surface->present(frame);
}
done:
@@ -358,31 +415,35 @@ 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*>(
+ m_eglConfig = static_cast<EGLConfig*>(
nativeInterface->nativeResourceForContext("eglConfig", currentContext));
- glGenTextures(1, &m_glTexture);
-
+ currentContext->functions()->glGenTextures(1, &m_glTexture);
int w = m_surfaceFormat.frameWidth();
int h = m_surfaceFormat.frameHeight();
+ bool hasAlpha = currentContext->format().hasAlpha();
EGLint attribs[] = {
EGL_WIDTH, w,
EGL_HEIGHT, h,
- EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB,
+ EGL_TEXTURE_FORMAT, hasAlpha ? EGL_TEXTURE_RGBA : EGL_TEXTURE_RGB,
EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
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,
@@ -391,7 +452,7 @@ void D3DPresentEngine::createOffscreenTexture()
m_device->CreateTexture(w, h, 1,
D3DUSAGE_RENDERTARGET,
- D3DFMT_X8R8G8B8,
+ hasAlpha ? D3DFMT_A8R8G8B8 : D3DFMT_X8R8G8B8,
D3DPOOL_DEFAULT,
&m_texture,
&share_handle);
@@ -410,7 +471,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 +485,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);