diff options
Diffstat (limited to 'src/opengl')
-rw-r--r-- | src/opengl/qglbuffer.cpp | 92 | ||||
-rw-r--r-- | src/opengl/qglbuffer.h | 9 |
2 files changed, 90 insertions, 11 deletions
diff --git a/src/opengl/qglbuffer.cpp b/src/opengl/qglbuffer.cpp index 223243c..d6e0109 100644 --- a/src/opengl/qglbuffer.cpp +++ b/src/opengl/qglbuffer.cpp @@ -42,6 +42,7 @@ #include <QtOpenGL/qgl.h> #include <QtOpenGL/private/qgl_p.h> #include <QtOpenGL/private/qglextensions_p.h> +#include <QtCore/qatomic.h> #include "qglbuffer.h" QT_BEGIN_NAMESPACE @@ -55,6 +56,20 @@ QT_BEGIN_NAMESPACE Buffer objects are created in the GL server so that the client application can avoid uploading vertices, indices, texture image data, etc every time they are needed. + + QGLBuffer objects can be copied around as a reference to the + underlying GL buffer object: + + \code + QGLBuffer buffer1(QGLBuffer::IndexBuffer); + buffer1.create(); + + QGLBuffer buffer2 = buffer1; + \endcode + + QGLBuffer performs a shallow copy when objects are copied in this + manner, but does not implement copy-on-write semantics. The original + object will be affected whenever the copy is modified. */ /*! @@ -116,13 +131,15 @@ class QGLBufferPrivate { public: QGLBufferPrivate(QGLBuffer::Type t) - : type(t), + : ref(1), + type(t), guard(0), usagePattern(QGLBuffer::StaticDraw), actualUsagePattern(QGLBuffer::StaticDraw) { } + QAtomicInt ref; QGLBuffer::Type type; QGLSharedResourceGuard guard; QGLBuffer::UsagePattern usagePattern; @@ -130,6 +147,19 @@ public: }; /*! + Constructs a new buffer object of type QGLBuffer::VertexBuffer. + + Note: this constructor just creates the QGLBuffer instance. The actual + buffer object in the GL server is not created until create() is called. + + \sa create() +*/ +QGLBuffer::QGLBuffer() + : d_ptr(new QGLBufferPrivate(QGLBuffer::VertexBuffer)) +{ +} + +/*! Constructs a new buffer object of \a type. Note: this constructor just creates the QGLBuffer instance. The actual @@ -142,6 +172,18 @@ QGLBuffer::QGLBuffer(QGLBuffer::Type type) { } +/*! + Constructs a shallow copy of \a other. + + Note: QGLBuffer does not implement copy-on-write semantics, + so \a other will be affected whenever the copy is modified. +*/ +QGLBuffer::QGLBuffer(const QGLBuffer &other) + : d_ptr(other.d_ptr) +{ + d_ptr->ref.ref(); +} + #define ctx d->guard.context() /*! @@ -150,13 +192,27 @@ QGLBuffer::QGLBuffer(QGLBuffer::Type type) */ QGLBuffer::~QGLBuffer() { - Q_D(QGLBuffer); - GLuint bufferId = d->guard.id(); - if (bufferId) { - // Switch to the original creating context to destroy it. - QGLShareContextScope scope(d->guard.context()); - glDeleteBuffers(1, &bufferId); + if (!d_ptr->ref.deref()) { + destroy(); + delete d_ptr; + } +} + +/*! + Assigns a shallow copy of \a other to this object. + + Note: QGLBuffer does not implement copy-on-write semantics, + so \a other will be affected whenever the copy is modified. +*/ +QGLBuffer &QGLBuffer::operator=(const QGLBuffer &other) +{ + if (d_ptr != other.d_ptr) { + other.d_ptr->ref.ref(); + if (!d_ptr->ref.deref()) + destroy(); + d_ptr = other.d_ptr; } + return *this; } /*! @@ -215,7 +271,7 @@ void QGLBuffer::setUsagePattern(QGLBuffer::UsagePattern value) This function will return false if the GL implementation does not support buffers, or there is no current QGLContext. - \sa isCreated(), allocate(), write() + \sa isCreated(), allocate(), write(), destroy() */ bool QGLBuffer::create() { @@ -242,7 +298,7 @@ bool QGLBuffer::create() /*! Returns true if this buffer has been created; false otherwise. - \sa create() + \sa create(), destroy() */ bool QGLBuffer::isCreated() const { @@ -251,6 +307,24 @@ bool QGLBuffer::isCreated() const } /*! + Destroys this buffer object, including the storage being + used in the GL server. All references to the buffer will + become invalid. +*/ +void QGLBuffer::destroy() +{ + Q_D(QGLBuffer); + GLuint bufferId = d->guard.id(); + if (bufferId) { + // Switch to the original creating context to destroy it. + QGLShareContextScope scope(d->guard.context()); + glDeleteBuffers(1, &bufferId); + } + d->guard.setId(0); + d->guard.setContext(0); +} + +/*! Reads the \a count bytes in this buffer starting at \a offset into \a data. Returns true on success; false if reading from the buffer is not supported. Buffer reading is not supported diff --git a/src/opengl/qglbuffer.h b/src/opengl/qglbuffer.h index 2fe1f1f..a1b45ff 100644 --- a/src/opengl/qglbuffer.h +++ b/src/opengl/qglbuffer.h @@ -64,9 +64,13 @@ public: PixelUnpackBuffer = 0x88EC // GL_PIXEL_UNPACK_BUFFER }; + QGLBuffer(); explicit QGLBuffer(QGLBuffer::Type type); + QGLBuffer(const QGLBuffer &other); ~QGLBuffer(); + QGLBuffer &operator=(const QGLBuffer &other); + enum UsagePattern { StreamDraw = 0x88E0, // GL_STREAM_DRAW @@ -95,6 +99,8 @@ public: bool create(); bool isCreated() const; + void destroy(); + bool bind() const; void release() const; @@ -114,9 +120,8 @@ public: bool unmap(); private: - QScopedPointer<QGLBufferPrivate> d_ptr; + QGLBufferPrivate *d_ptr; - Q_DISABLE_COPY(QGLBuffer) Q_DECLARE_PRIVATE(QGLBuffer) }; |