aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@theqtcompany.com>2015-05-01 21:45:58 +0200
committerLaszlo Agocs <laszlo.agocs@theqtcompany.com>2015-05-02 16:17:48 +0000
commita098fea659e9dd2cdb8d214c62cfe59f2aecb1a6 (patch)
treeed10b9cc5067c0048c3232cfc8ac92d1efe81940
parent3e01854a0414727e69a656282cf08407a0b13603 (diff)
Make QQuickCLContext public
Change-Id: Icf944ea07d1e690dcda09ca456959002136b8100 Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
-rw-r--r--src/quickcl/qquickclcontext.cpp139
-rw-r--r--src/quickcl/qquickclcontext.h (renamed from src/quickcl/qquickclcontext_p.h)22
-rw-r--r--src/quickcl/qquickclitem.cpp5
-rw-r--r--src/quickcl/quickcl.pro2
4 files changed, 130 insertions, 38 deletions
diff --git a/src/quickcl/qquickclcontext.cpp b/src/quickcl/qquickclcontext.cpp
index 4c07593..14f1647 100644
--- a/src/quickcl/qquickclcontext.cpp
+++ b/src/quickcl/qquickclcontext.cpp
@@ -34,7 +34,7 @@
**
****************************************************************************/
-#include "qquickclcontext_p.h"
+#include "qquickclcontext.h"
#include <QtGui/QOpenGLContext>
#include <QtGui/QOpenGLFunctions>
@@ -45,20 +45,105 @@ QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(logCL, "qt.quickcl")
+/*!
+ \class QQuickCLContext
+
+ \brief QQuickCLContext encapsulates an OpenCL context.
+
+ \note In most cases there is no need to directly interact with this class
+ as QQuickCLItem takes care of creating and destroying a QQuickCLContext
+ instance as necessary.
+
+ \note This class assumes that OpenCL 1.1 and CL-GL interop are available.
+ */
+
+class QQuickCLContextPrivate
+{
+public:
+ QQuickCLContextPrivate()
+ : platform(0),
+ device(0),
+ context(0)
+ { }
+
+ cl_platform_id platform;
+ cl_device_id device;
+ cl_context context;
+};
+
+/*!
+ Constructs a new instance of QQuickCLContext.
+
+ \note No OpenCL initialization takes place before calling create().
+ */
QQuickCLContext::QQuickCLContext()
- : m_platform(0),
- m_device(0),
- m_context(0)
+ : d_ptr(new QQuickCLContextPrivate)
{
}
+/*!
+ Destroys the instance and releases all OpenCL resources by invoking
+ destroy().
+ */
QQuickCLContext::~QQuickCLContext()
{
destroy();
+ delete d_ptr;
+}
+
+/*!
+ \return \c true if the OpenCL context was successfully created.
+ */
+bool QQuickCLContext::isValid() const
+{
+ Q_D(const QQuickCLContext);
+ return d->context != 0;
}
+/*!
+ \return the OpenCL platform chosen in create().
+ */
+cl_platform_id QQuickCLContext::platform() const
+{
+ Q_D(const QQuickCLContext);
+ return d->platform;
+}
+
+/*!
+ \return the OpenCL device chosen in create().
+ */
+cl_device_id QQuickCLContext::device() const
+{
+ Q_D(const QQuickCLContext);
+ return d->device;
+}
+
+/*!
+ \return the OpenCL context or \c 0 if not yet created.
+ */
+cl_context QQuickCLContext::context() const
+{
+ Q_D(const QQuickCLContext);
+ return d->context;
+}
+
+/*!
+ Creates a new OpenCL context.
+
+ If a context was already created, it is destroyed first.
+
+ An OpenGL context must be current at the time of calling this function.
+ This ensures that the OpenCL platform matching the OpenGL implementation's
+ vendor is selected and that CL-GL interop is enabled for the context.
+
+ If something fails, warnings are logged with the \c qt.quickcl category.
+
+ \return \c true if successful.
+ */
bool QQuickCLContext::create()
{
+ Q_D(QQuickCLContext);
+
destroy();
qCDebug(logCL, "Creating new OpenCL context");
@@ -92,7 +177,7 @@ bool QQuickCLContext::create()
qWarning("Failed to get platform IDs");
return false;
}
- m_platform = platformIds[0];
+ d->platform = platformIds[0];
const char *vendor = (const char *) f->glGetString(GL_VENDOR);
qCDebug(logCL, "GL_VENDOR: %s", vendor);
const bool isNV = vendor && strstr(vendor, "NVIDIA");
@@ -105,13 +190,13 @@ bool QQuickCLContext::create()
clGetPlatformInfo(platformIds[i], CL_PLATFORM_NAME, name.size(), name.data(), 0);
qCDebug(logCL, "Platform %p: %s", platformIds[i], name.constData());
if (isNV && name.contains(QByteArrayLiteral("NVIDIA")))
- m_platform = platformIds[i];
+ d->platform = platformIds[i];
else if (isIntel && name.contains(QByteArrayLiteral("Intel")))
- m_platform = platformIds[i];
+ d->platform = platformIds[i];
else if (isAMD && name.contains(QByteArrayLiteral("AMD")))
- m_platform = platformIds[i];
+ d->platform = platformIds[i];
}
- qCDebug(logCL, "Using platform %p", m_platform);
+ qCDebug(logCL, "Using platform %p", d->platform);
#if defined (Q_OS_OSX)
cl_context_properties contextProps[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE,
@@ -123,12 +208,12 @@ bool QQuickCLContext::create()
qWarning("ANGLE is not supported");
return false;
}
- cl_context_properties contextProps[] = { CL_CONTEXT_PLATFORM, (cl_context_properties) m_platform,
+ cl_context_properties contextProps[] = { CL_CONTEXT_PLATFORM, (cl_context_properties) d->platform,
CL_GL_CONTEXT_KHR, (cl_context_properties) wglGetCurrentContext(),
CL_WGL_HDC_KHR, (cl_context_properties) wglGetCurrentDC(),
0 };
#elif defined(Q_OS_LINUX)
- cl_context_properties contextProps[] = { CL_CONTEXT_PLATFORM, (cl_context_properties) m_platform,
+ cl_context_properties contextProps[] = { CL_CONTEXT_PLATFORM, (cl_context_properties) d->platform,
CL_GL_CONTEXT_KHR, 0,
0, 0,
0 };
@@ -152,17 +237,17 @@ bool QQuickCLContext::create()
}
#endif
- m_context = clCreateContextFromType(contextProps, CL_DEVICE_TYPE_GPU, 0, 0, &err);
- if (!m_context) {
+ d->context = clCreateContextFromType(contextProps, CL_DEVICE_TYPE_GPU, 0, 0, &err);
+ if (!d->context) {
qWarning("Failed to create OpenCL context: %d", err);
return false;
}
- qCDebug(logCL, "Using context %p", m_context);
+ qCDebug(logCL, "Using context %p", d->context);
#if defined(Q_OS_OSX)
- err = clGetGLContextInfoAPPLE(m_context, CGLGetCurrentContext(),
+ err = clGetGLContextInfoAPPLE(d->context, CGLGetCurrentContext(),
CL_CGL_DEVICE_FOR_CURRENT_VIRTUAL_SCREEN_APPLE,
- sizeof(cl_device_id), &m_device, 0);
+ sizeof(cl_device_id), &d->device, 0);
if (err != CL_SUCCESS) {
qWarning("Failed to get OpenCL device for current screen: %d", err);
destroy();
@@ -171,8 +256,8 @@ bool QQuickCLContext::create()
#else
clGetGLContextInfoKHR_fn getGLContextInfo = (clGetGLContextInfoKHR_fn) clGetExtensionFunctionAddress("clGetGLContextInfoKHR");
if (!getGLContextInfo || getGLContextInfo(contextProps, CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR,
- sizeof(cl_device_id), &m_device, 0) != CL_SUCCESS) {
- err = clGetDeviceIDs(m_platform, CL_DEVICE_TYPE_GPU, 1, &m_device, 0);
+ sizeof(cl_device_id), &d->device, 0) != CL_SUCCESS) {
+ err = clGetDeviceIDs(d->platform, CL_DEVICE_TYPE_GPU, 1, &d->device, 0);
if (err != CL_SUCCESS) {
qWarning("Failed to get OpenCL device: %d", err);
destroy();
@@ -180,20 +265,24 @@ bool QQuickCLContext::create()
}
}
#endif
- qCDebug(logCL, "Using device %p", m_device);
+ qCDebug(logCL, "Using device %p", d->device);
return true;
}
+/*!
+ Releases all OpenCL resources.
+ */
void QQuickCLContext::destroy()
{
- if (m_context) {
- qCDebug(logCL, "Releasing OpenCL context %p", m_context);
- clReleaseContext(m_context);
- m_context = 0;
+ Q_D(QQuickCLContext);
+ if (d->context) {
+ qCDebug(logCL, "Releasing OpenCL context %p", d->context);
+ clReleaseContext(d->context);
+ d->context = 0;
}
- m_device = 0;
- m_platform = 0;
+ d->device = 0;
+ d->platform = 0;
}
QT_END_NAMESPACE
diff --git a/src/quickcl/qquickclcontext_p.h b/src/quickcl/qquickclcontext.h
index 10bf70d..2a7e94c 100644
--- a/src/quickcl/qquickclcontext_p.h
+++ b/src/quickcl/qquickclcontext.h
@@ -34,15 +34,19 @@
**
****************************************************************************/
-#ifndef QQUICKCLCONTEXT_P_H
-#define QQUICKCLCONTEXT_P_H
+#ifndef QQUICKCLCONTEXT_H
+#define QQUICKCLCONTEXT_H
#include <QtQuickCL/qtquickclglobal.h>
QT_BEGIN_NAMESPACE
-class QQuickCLContext
+class QQuickCLContextPrivate;
+
+class Q_QUICKCL_EXPORT QQuickCLContext
{
+ Q_DECLARE_PRIVATE(QQuickCLContext)
+
public:
QQuickCLContext();
~QQuickCLContext();
@@ -50,16 +54,14 @@ public:
bool create();
void destroy();
- bool isValid() const { return m_context != 0; }
+ bool isValid() const;
- cl_platform_id platform() const { return m_platform; }
- cl_device_id device() const { return m_device; }
- cl_context context() const { return m_context; }
+ cl_platform_id platform() const;
+ cl_device_id device() const;
+ cl_context context() const;
private:
- cl_platform_id m_platform;
- cl_device_id m_device;
- cl_context m_context;
+ QQuickCLContextPrivate *d_ptr;
};
QT_END_NAMESPACE
diff --git a/src/quickcl/qquickclitem.cpp b/src/quickcl/qquickclitem.cpp
index fa5933c..6c88b5d 100644
--- a/src/quickcl/qquickclitem.cpp
+++ b/src/quickcl/qquickclitem.cpp
@@ -35,7 +35,7 @@
****************************************************************************/
#include "qquickclitem.h"
-#include "qquickclcontext_p.h"
+#include "qquickclcontext.h"
#include <QtCore/QAtomicInt>
#include <QtCore/QHash>
#include <QtCore/QFile>
@@ -52,7 +52,8 @@ Q_DECLARE_LOGGING_CATEGORY(logCL)
\brief QQuickCLItem is a QQuickItem that automatically gets an OpenCL
context with the proper platform and device chosen for CL-GL interop.
- Each instance of QQuickCLItem is backed by a corresponding QQuickCLRunnable.
+ Each instance of QQuickCLItem is backed by a QQuickCLContext and
+ QQuickCLRunnable instance.
\note When animating properties that are used in OpenCL kernels, call the
\l{QQuickItem::update()}{update()} function (from the gui thread) to
diff --git a/src/quickcl/quickcl.pro b/src/quickcl/quickcl.pro
index 2a28924..20b81b9 100644
--- a/src/quickcl/quickcl.pro
+++ b/src/quickcl/quickcl.pro
@@ -7,7 +7,7 @@ DEFINES += QT_BUILD_QUICKCL_LIB
HEADERS = \
qtquickclglobal.h \
- qquickclcontext_p.h \
+ qquickclcontext.h \
qquickclitem.h \
qquickclrunnable.h \
qquickclimagerunnable.h