src/opengl/qglbuffer.cpp
changeset 33 3e2da88830cd
parent 30 5dc02b23752f
child 37 758a864f9613
equal deleted inserted replaced
30:5dc02b23752f 33:3e2da88830cd
    40 ****************************************************************************/
    40 ****************************************************************************/
    41 
    41 
    42 #include <QtOpenGL/qgl.h>
    42 #include <QtOpenGL/qgl.h>
    43 #include <QtOpenGL/private/qgl_p.h>
    43 #include <QtOpenGL/private/qgl_p.h>
    44 #include <QtOpenGL/private/qglextensions_p.h>
    44 #include <QtOpenGL/private/qglextensions_p.h>
       
    45 #include <QtCore/qatomic.h>
    45 #include "qglbuffer.h"
    46 #include "qglbuffer.h"
    46 
    47 
    47 QT_BEGIN_NAMESPACE
    48 QT_BEGIN_NAMESPACE
    48 
    49 
    49 /*!
    50 /*!
    53     \ingroup painting-3D
    54     \ingroup painting-3D
    54 
    55 
    55     Buffer objects are created in the GL server so that the
    56     Buffer objects are created in the GL server so that the
    56     client application can avoid uploading vertices, indices,
    57     client application can avoid uploading vertices, indices,
    57     texture image data, etc every time they are needed.
    58     texture image data, etc every time they are needed.
       
    59 
       
    60     QGLBuffer objects can be copied around as a reference to the
       
    61     underlying GL buffer object:
       
    62 
       
    63     \code
       
    64     QGLBuffer buffer1(QGLBuffer::IndexBuffer);
       
    65     buffer1.create();
       
    66 
       
    67     QGLBuffer buffer2 = buffer1;
       
    68     \endcode
       
    69 
       
    70     QGLBuffer performs a shallow copy when objects are copied in this
       
    71     manner, but does not implement copy-on-write semantics.  The original
       
    72     object will be affected whenever the copy is modified.
    58 */
    73 */
    59 
    74 
    60 /*!
    75 /*!
    61     \enum QGLBuffer::Type
    76     \enum QGLBuffer::Type
    62     This enum defines the type of GL buffer object to create with QGLBuffer.
    77     This enum defines the type of GL buffer object to create with QGLBuffer.
   114 
   129 
   115 class QGLBufferPrivate
   130 class QGLBufferPrivate
   116 {
   131 {
   117 public:
   132 public:
   118     QGLBufferPrivate(QGLBuffer::Type t)
   133     QGLBufferPrivate(QGLBuffer::Type t)
   119         : type(t),
   134         : ref(1),
       
   135           type(t),
   120           guard(0),
   136           guard(0),
   121           usagePattern(QGLBuffer::StaticDraw),
   137           usagePattern(QGLBuffer::StaticDraw),
   122           actualUsagePattern(QGLBuffer::StaticDraw)
   138           actualUsagePattern(QGLBuffer::StaticDraw)
   123     {
   139     {
   124     }
   140     }
   125 
   141 
       
   142     QAtomicInt ref;
   126     QGLBuffer::Type type;
   143     QGLBuffer::Type type;
   127     QGLSharedResourceGuard guard;
   144     QGLSharedResourceGuard guard;
   128     QGLBuffer::UsagePattern usagePattern;
   145     QGLBuffer::UsagePattern usagePattern;
   129     QGLBuffer::UsagePattern actualUsagePattern;
   146     QGLBuffer::UsagePattern actualUsagePattern;
   130 };
   147 };
   131 
   148 
   132 /*!
   149 /*!
   133     Constructs a new buffer object of \a type.
   150     Constructs a new buffer object of type QGLBuffer::VertexBuffer.
   134 
   151 
   135     Note: this constructor just creates the QGLBuffer instance.  The actual
   152     Note: this constructor just creates the QGLBuffer instance.  The actual
   136     buffer object in the GL server is not created until create() is called.
   153     buffer object in the GL server is not created until create() is called.
   137 
   154 
   138     \sa create()
   155     \sa create()
   139 */
   156 */
       
   157 QGLBuffer::QGLBuffer()
       
   158     : d_ptr(new QGLBufferPrivate(QGLBuffer::VertexBuffer))
       
   159 {
       
   160 }
       
   161 
       
   162 /*!
       
   163     Constructs a new buffer object of \a type.
       
   164 
       
   165     Note: this constructor just creates the QGLBuffer instance.  The actual
       
   166     buffer object in the GL server is not created until create() is called.
       
   167 
       
   168     \sa create()
       
   169 */
   140 QGLBuffer::QGLBuffer(QGLBuffer::Type type)
   170 QGLBuffer::QGLBuffer(QGLBuffer::Type type)
   141     : d_ptr(new QGLBufferPrivate(type))
   171     : d_ptr(new QGLBufferPrivate(type))
   142 {
   172 {
   143 }
   173 }
   144 
   174 
       
   175 /*!
       
   176     Constructs a shallow copy of \a other.
       
   177 
       
   178     Note: QGLBuffer does not implement copy-on-write semantics,
       
   179     so \a other will be affected whenever the copy is modified.
       
   180 */
       
   181 QGLBuffer::QGLBuffer(const QGLBuffer &other)
       
   182     : d_ptr(other.d_ptr)
       
   183 {
       
   184     d_ptr->ref.ref();
       
   185 }
       
   186 
   145 #define ctx d->guard.context()
   187 #define ctx d->guard.context()
   146 
   188 
   147 /*!
   189 /*!
   148     Destroys this buffer object, including the storage being
   190     Destroys this buffer object, including the storage being
   149     used in the GL server.
   191     used in the GL server.
   150 */
   192 */
   151 QGLBuffer::~QGLBuffer()
   193 QGLBuffer::~QGLBuffer()
   152 {
   194 {
   153     Q_D(QGLBuffer);
   195     if (!d_ptr->ref.deref()) {
   154     GLuint bufferId = d->guard.id();
   196         destroy();
   155     if (bufferId) {
   197         delete d_ptr;
   156         // Switch to the original creating context to destroy it.
       
   157         QGLShareContextScope scope(d->guard.context());
       
   158         glDeleteBuffers(1, &bufferId);
       
   159     }
   198     }
       
   199 }
       
   200 
       
   201 /*!
       
   202     Assigns a shallow copy of \a other to this object.
       
   203 
       
   204     Note: QGLBuffer does not implement copy-on-write semantics,
       
   205     so \a other will be affected whenever the copy is modified.
       
   206 */
       
   207 QGLBuffer &QGLBuffer::operator=(const QGLBuffer &other)
       
   208 {
       
   209     if (d_ptr != other.d_ptr) {
       
   210         other.d_ptr->ref.ref();
       
   211         if (!d_ptr->ref.deref())
       
   212             destroy();
       
   213         d_ptr = other.d_ptr;
       
   214     }
       
   215     return *this;
   160 }
   216 }
   161 
   217 
   162 /*!
   218 /*!
   163     Returns the type of buffer represented by this object.
   219     Returns the type of buffer represented by this object.
   164 */
   220 */
   213     that context (or any other context that is shared with it).
   269     that context (or any other context that is shared with it).
   214 
   270 
   215     This function will return false if the GL implementation
   271     This function will return false if the GL implementation
   216     does not support buffers, or there is no current QGLContext.
   272     does not support buffers, or there is no current QGLContext.
   217 
   273 
   218     \sa isCreated(), allocate(), write()
   274     \sa isCreated(), allocate(), write(), destroy()
   219 */
   275 */
   220 bool QGLBuffer::create()
   276 bool QGLBuffer::create()
   221 {
   277 {
   222     Q_D(QGLBuffer);
   278     Q_D(QGLBuffer);
   223     if (d->guard.id())
   279     if (d->guard.id())
   240 #define ctx d->guard.context()
   296 #define ctx d->guard.context()
   241 
   297 
   242 /*!
   298 /*!
   243     Returns true if this buffer has been created; false otherwise.
   299     Returns true if this buffer has been created; false otherwise.
   244 
   300 
   245     \sa create()
   301     \sa create(), destroy()
   246 */
   302 */
   247 bool QGLBuffer::isCreated() const
   303 bool QGLBuffer::isCreated() const
   248 {
   304 {
   249     Q_D(const QGLBuffer);
   305     Q_D(const QGLBuffer);
   250     return d->guard.id() != 0;
   306     return d->guard.id() != 0;
       
   307 }
       
   308 
       
   309 /*!
       
   310     Destroys this buffer object, including the storage being
       
   311     used in the GL server.  All references to the buffer will
       
   312     become invalid.
       
   313 */
       
   314 void QGLBuffer::destroy()
       
   315 {
       
   316     Q_D(QGLBuffer);
       
   317     GLuint bufferId = d->guard.id();
       
   318     if (bufferId) {
       
   319         // Switch to the original creating context to destroy it.
       
   320         QGLShareContextScope scope(d->guard.context());
       
   321         glDeleteBuffers(1, &bufferId);
       
   322     }
       
   323     d->guard.setId(0);
       
   324     d->guard.setContext(0);
   251 }
   325 }
   252 
   326 
   253 /*!
   327 /*!
   254     Reads the \a count bytes in this buffer starting at \a offset
   328     Reads the \a count bytes in this buffer starting at \a offset
   255     into \a data.  Returns true on success; false if reading from
   329     into \a data.  Returns true on success; false if reading from