From ccb2e4dbb18fafb92d1c06a9f2c2ffa862de3abd Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 12 Jul 2022 17:55:21 +0200 Subject: [PATCH] QOpenGLBuffer: add move-SMFs and swap()s - add move special member functions (docs copied from QHostInfo) - add member swap - use move-and-swap, not pure-swap, because these objects hold resources (handles) other than just memory - Q_DECLARE_SHARED (it's not implicitly shared, but explicitly) - adds ADL swap and Q_DECLARE_TYPEINFO [ChangeLog][QtOpenGL][QOpenGLBuffer] Added member-swap(), move constructor, move assignment operator. Change-Id: I22dc92108bdd393fff4361db23e94eaf3d7ea9cc Reviewed-by: Fabian Kosmale --- src/opengl/qopenglbuffer.cpp | 34 ++++++++++++++++++++++++-- src/opengl/qopenglbuffer.h | 7 ++++++ tests/auto/gui/qopengl/tst_qopengl.cpp | 7 ++++++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/opengl/qopenglbuffer.cpp b/src/opengl/qopenglbuffer.cpp index 62d2d5edd24..64e79750430 100644 --- a/src/opengl/qopenglbuffer.cpp +++ b/src/opengl/qopenglbuffer.cpp @@ -166,7 +166,7 @@ QOpenGLBuffer::QOpenGLBuffer(const QOpenGLBuffer &other) */ QOpenGLBuffer::~QOpenGLBuffer() { - if (!d_ptr->ref.deref()) { + if (d_ptr && !d_ptr->ref.deref()) { destroy(); delete d_ptr; } @@ -182,7 +182,7 @@ QOpenGLBuffer &QOpenGLBuffer::operator=(const QOpenGLBuffer &other) { if (d_ptr != other.d_ptr) { other.d_ptr->ref.ref(); - if (!d_ptr->ref.deref()) { + if (d_ptr && !d_ptr->ref.deref()) { destroy(); delete d_ptr; } @@ -191,6 +191,36 @@ QOpenGLBuffer &QOpenGLBuffer::operator=(const QOpenGLBuffer &other) return *this; } +/*! + \fn QOpenGLBuffer::QOpenGLBuffer(QOpenGLBuffer &&other) + \since 6.5 + + Move-constructs a new QOpenGLBuffer from \a other. + + \note The moved-from object \a other is placed in a partially-formed state, + in which the only valid operations are destruction and assignment of a new + value. +*/ + +/*! + \fn QOpenGLBuffer &QOpenGLBuffer::operator=(QOpenGLBuffer &&other) + \since 6.5 + + Move-assigns \a other to this QOpenGLBuffer instance. + + \note The moved-from object \a other is placed in a partially-formed state, + in which the only valid operations are destruction and assignment of a new + value. +*/ + +/*! + \fn QOpenGLBuffer::swap(QOpenGLBuffer &other) + \since 6.5 + + Swaps buffer \a other with this buffer. This operation is very fast and + never fails. +*/ + /*! Returns the type of buffer represented by this object. */ diff --git a/src/opengl/qopenglbuffer.h b/src/opengl/qopenglbuffer.h index 77390736816..b9f2265ca07 100644 --- a/src/opengl/qopenglbuffer.h +++ b/src/opengl/qopenglbuffer.h @@ -29,9 +29,15 @@ public: QOpenGLBuffer(); explicit QOpenGLBuffer(QOpenGLBuffer::Type type); QOpenGLBuffer(const QOpenGLBuffer &other); + QOpenGLBuffer(QOpenGLBuffer &&other) noexcept + : d_ptr{std::exchange(other.d_ptr, nullptr)} {} ~QOpenGLBuffer(); QOpenGLBuffer &operator=(const QOpenGLBuffer &other); + QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QOpenGLBuffer) + + void swap(QOpenGLBuffer &other) noexcept + { return qt_ptr_swap(d_ptr, other.d_ptr); } enum UsagePattern { @@ -98,6 +104,7 @@ private: Q_DECLARE_PRIVATE(QOpenGLBuffer) }; +Q_DECLARE_SHARED(QOpenGLBuffer) Q_DECLARE_OPERATORS_FOR_FLAGS(QOpenGLBuffer::RangeAccessFlags) diff --git a/tests/auto/gui/qopengl/tst_qopengl.cpp b/tests/auto/gui/qopengl/tst_qopengl.cpp index 58e09f7d1b3..ace4d3e9ef7 100644 --- a/tests/auto/gui/qopengl/tst_qopengl.cpp +++ b/tests/auto/gui/qopengl/tst_qopengl.cpp @@ -1588,6 +1588,13 @@ void tst_QOpenGL::bufferCreate() buf.allocate(128); QCOMPARE(buf.size(), 128); + { + QOpenGLBuffer moved = std::move(buf); + QCOMPARE_EQ(moved.isCreated(), true); + QCOMPARE_EQ(moved.size(), 128); + buf = std::move(moved); + } + buf.release(); buf.destroy();