From 93e3f45142e2ba85746bc3a8e0f2f67a7890cb0a Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Thu, 24 Jun 2010 13:40:54 +1000 Subject: Lazy creation of QCLImage2DPrivate to improve performance. --- src/opencl/qclimage.cpp | 54 +++++++++++++++++++++++++++---------------------- src/opencl/qclimage.h | 7 ++++--- 2 files changed, 34 insertions(+), 27 deletions(-) diff --git a/src/opencl/qclimage.cpp b/src/opencl/qclimage.cpp index a44990f..27b3293 100644 --- a/src/opencl/qclimage.cpp +++ b/src/opencl/qclimage.cpp @@ -79,32 +79,19 @@ public: }; /*! + \fn QCLImage2D::QCLImage2D() + Constructs a null 2D OpenCL image object. */ -QCLImage2D::QCLImage2D() - : d_ptr(new QCLImage2DPrivate()) -{ -} /*! + \fn QCLImage2D::QCLImage2D(QCLContext *context, cl_mem id) + Constructs a 2D OpenCL image object that is initialized with the native OpenCL identifier \a id, and associates it with \a context. This class will take over ownership of \a id and will release it in the destructor. */ -QCLImage2D::QCLImage2D(QCLContext *context, cl_mem id) - : QCLMemoryObject(context, id), d_ptr(new QCLImage2DPrivate()) -{ - if (id) { - cl_image_format iformat; - if (clGetImageInfo(id, CL_IMAGE_FORMAT, sizeof(iformat), &iformat, 0) - == CL_SUCCESS) { - d_ptr->format = QCLImageFormat - (QCLImageFormat::ChannelOrder(iformat.image_channel_order), - QCLImageFormat::ChannelType(iformat.image_channel_data_type)); - } - } -} /*! \internal @@ -120,7 +107,8 @@ QCLImage2D::QCLImage2D(QCLContext *context, cl_mem id, Constructs a copy of \a other. */ QCLImage2D::QCLImage2D(const QCLImage2D &other) - : QCLMemoryObject(), d_ptr(new QCLImage2DPrivate(other.d_ptr.data())) + : QCLMemoryObject() + , d_ptr(other.d_ptr ? new QCLImage2DPrivate(other.d_ptr) : 0) { setId(other.context(), other.memoryId()); } @@ -130,6 +118,7 @@ QCLImage2D::QCLImage2D(const QCLImage2D &other) */ QCLImage2D::~QCLImage2D() { + delete d_ptr; } /*! @@ -139,7 +128,14 @@ QCLImage2D &QCLImage2D::operator=(const QCLImage2D &other) { if (this != &other) { setId(other.context(), other.memoryId()); - d_ptr->assign(other.d_ptr.data()); + if (!d_ptr && other.d_ptr) { + d_ptr = new QCLImage2DPrivate(other.d_ptr); + } else if (other.d_ptr) { + d_ptr->assign(other.d_ptr); + } else { + delete d_ptr; + d_ptr = 0; + } } return *this; } @@ -149,6 +145,17 @@ QCLImage2D &QCLImage2D::operator=(const QCLImage2D &other) */ QCLImageFormat QCLImage2D::format() const { + if (!d_ptr) { + d_ptr = new QCLImage2DPrivate(); + cl_image_format iformat; + if (clGetImageInfo + (memoryId(), CL_IMAGE_FORMAT, sizeof(iformat), &iformat, 0) + == CL_SUCCESS) { + d_ptr->format = QCLImageFormat + (QCLImageFormat::ChannelOrder(iformat.image_channel_order), + QCLImageFormat::ChannelType(iformat.image_channel_data_type)); + } + } return d_ptr->format; } @@ -615,10 +622,10 @@ QImage QCLImage2D::toQImage(bool cached) { if (!memoryId()) return QImage(); - Q_D(QCLImage2D); - QImage::Format qformat = d->format.toQImageFormat(); + QImage::Format qformat = format().toQImageFormat(); if (qformat == QImage::Format_Invalid) return QImage(); + Q_D(QCLImage2D); if (cached) { if (d->cachedImage.isNull()) d->cachedImage = QImage(width(), height(), qformat); @@ -740,18 +747,17 @@ void QCLImage2D::drawImage (QPainter *painter, const QRect &targetRect, const QRect &subRect, Qt::ImageConversionFlags flags) { - Q_D(QCLImage2D); - // Bail out if the OpenCL image doesn't have a drawable format. if (isNull()) return; - QImage::Format qformat = d->format.toQImageFormat(); + QImage::Format qformat = format().toQImageFormat(); if (qformat == QImage::Format_Invalid) return; int wid = width(); int ht = height(); // Can we draw directly into the painter's surface as a QImage? + Q_D(QCLImage2D); QPoint offset; QImage *surfaceImage = qt_cl_surface_image(painter, &offset); if (surfaceImage && qformat == surfaceImage->format() && diff --git a/src/opencl/qclimage.h b/src/opencl/qclimage.h index 5b5f962..ab27dd3 100644 --- a/src/opencl/qclimage.h +++ b/src/opencl/qclimage.h @@ -61,8 +61,9 @@ class QPainter; class Q_CL_EXPORT QCLImage2D : public QCLMemoryObject { public: - QCLImage2D(); - QCLImage2D(QCLContext *context, cl_mem id); + QCLImage2D() : d_ptr(0) {} + QCLImage2D(QCLContext *context, cl_mem id) + : QCLMemoryObject(context, id), d_ptr(0) {} QCLImage2D(const QCLImage2D &other); ~QCLImage2D(); @@ -122,7 +123,7 @@ public: Qt::ImageConversionFlags flags = Qt::AutoColor); private: - QScopedPointer d_ptr; + mutable QCLImage2DPrivate *d_ptr; Q_DECLARE_PRIVATE(QCLImage2D) -- cgit v1.2.3