From 872af6811b2af366965f49280918d315a1f640ff Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing Date: Wed, 22 Jan 2020 16:33:23 +0100 Subject: Move QOpenGLBuffer from QtGui to QtOpenGL Task-number: QTBUG-74409 Change-Id: I72c839e54f24810b2bde2385c568921c4e4a2869 Reviewed-by: Laszlo Agocs --- src/opengl/CMakeLists.txt | 1 + src/opengl/opengl.pro | 2 + src/opengl/qopenglbuffer.cpp | 618 +++++++++++++++++++++++++++++++++++ src/opengl/qopenglbuffer.h | 145 ++++++++ src/opengl/qopengltextureblitter.cpp | 2 +- 5 files changed, 767 insertions(+), 1 deletion(-) create mode 100644 src/opengl/qopenglbuffer.cpp create mode 100644 src/opengl/qopenglbuffer.h (limited to 'src/opengl') diff --git a/src/opengl/CMakeLists.txt b/src/opengl/CMakeLists.txt index 6063ca58be..18378a7564 100644 --- a/src/opengl/CMakeLists.txt +++ b/src/opengl/CMakeLists.txt @@ -7,6 +7,7 @@ qt_add_module(OpenGL SOURCES qopengl2pexvertexarray.cpp qopengl2pexvertexarray_p.h + qopenglbuffer.cpp qopenglbuffer.h qopenglcustomshaderstage.cpp qopenglcustomshaderstage_p.h qopengldebug.cpp qopengldebug.h qopenglengineshadermanager.cpp qopenglengineshadermanager_p.h diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro index e2b27984c7..bf4ba63053 100644 --- a/src/opengl/opengl.pro +++ b/src/opengl/opengl.pro @@ -10,6 +10,7 @@ qtConfig(opengles2): CONFIG += opengles2 HEADERS += \ qopengl2pexvertexarray_p.h \ + qopenglbuffer.h \ qopenglcustomshaderstage_p.h \ qopengldebug.h \ qopenglengineshadermanager_p.h \ @@ -36,6 +37,7 @@ HEADERS += \ SOURCES += \ qopengl2pexvertexarray.cpp \ + qopenglbuffer.cpp \ qopenglcustomshaderstage.cpp \ qopenglengineshadermanager.cpp \ qopenglframebufferobject.cpp \ diff --git a/src/opengl/qopenglbuffer.cpp b/src/opengl/qopenglbuffer.cpp new file mode 100644 index 0000000000..3f049e5e89 --- /dev/null +++ b/src/opengl/qopenglbuffer.cpp @@ -0,0 +1,618 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtOpenGL module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include "qopenglbuffer.h" +#include + +#ifndef GL_CONTEXT_LOST +#define GL_CONTEXT_LOST 0x0507 +#endif + +QT_BEGIN_NAMESPACE + +/*! + \class QOpenGLBuffer + \brief The QOpenGLBuffer class provides functions for creating and managing OpenGL buffer objects. + \since 5.0 + \ingroup painting-3D + \inmodule QtOpenGL + + Buffer objects are created in the OpenGL server so that the + client application can avoid uploading vertices, indices, + texture image data, etc every time they are needed. + + QOpenGLBuffer objects can be copied around as a reference to the + underlying OpenGL buffer object: + + \snippet code/src_gui_opengl_qopenglbuffer.cpp 0 + + QOpenGLBuffer 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. +*/ + +/*! + \enum QOpenGLBuffer::Type + This enum defines the type of OpenGL buffer object to create with QOpenGLBuffer. + + \value VertexBuffer Vertex buffer object for use when specifying + vertex arrays. + \value IndexBuffer Index buffer object for use with \c{glDrawElements()}. + \value PixelPackBuffer Pixel pack buffer object for reading pixel + data from the OpenGL server (for example, with \c{glReadPixels()}). + Not supported under OpenGL/ES. + \value PixelUnpackBuffer Pixel unpack buffer object for writing pixel + data to the OpenGL server (for example, with \c{glTexImage2D()}). + Not supported under OpenGL/ES. +*/ + +/*! + \enum QOpenGLBuffer::UsagePattern + This enum defines the usage pattern of a QOpenGLBuffer object. + + \value StreamDraw The data will be set once and used a few times + for drawing operations. Under OpenGL/ES 1.1 this is identical + to StaticDraw. + \value StreamRead The data will be set once and used a few times + for reading data back from the OpenGL server. Not supported + under OpenGL/ES. + \value StreamCopy The data will be set once and used a few times + for reading data back from the OpenGL server for use in further + drawing operations. Not supported under OpenGL/ES. + \value StaticDraw The data will be set once and used many times + for drawing operations. + \value StaticRead The data will be set once and used many times + for reading data back from the OpenGL server. Not supported + under OpenGL/ES. + \value StaticCopy The data will be set once and used many times + for reading data back from the OpenGL server for use in further + drawing operations. Not supported under OpenGL/ES. + \value DynamicDraw The data will be modified repeatedly and used + many times for drawing operations. + \value DynamicRead The data will be modified repeatedly and used + many times for reading data back from the OpenGL server. + Not supported under OpenGL/ES. + \value DynamicCopy The data will be modified repeatedly and used + many times for reading data back from the OpenGL server for + use in further drawing operations. Not supported under OpenGL/ES. +*/ + +/*! + \enum QOpenGLBuffer::Access + This enum defines the access mode for QOpenGLBuffer::map(). + + \value ReadOnly The buffer will be mapped for reading only. + \value WriteOnly The buffer will be mapped for writing only. + \value ReadWrite The buffer will be mapped for reading and writing. +*/ + +/*! + \enum QOpenGLBuffer::RangeAccessFlag + This enum defines the access mode bits for QOpenGLBuffer::mapRange(). + + \value RangeRead The buffer will be mapped for reading. + \value RangeWrite The buffer will be mapped for writing. + \value RangeInvalidate Discard the previous contents of the specified range. + \value RangeInvalidateBuffer Discard the previous contents of the entire buffer. + \value RangeFlushExplicit Indicates that modifications are to be flushed explicitly via \c glFlushMappedBufferRange. + \value RangeUnsynchronized Indicates that pending operations should not be synchronized before returning from mapRange(). +*/ + +class QOpenGLBufferPrivate +{ +public: + QOpenGLBufferPrivate(QOpenGLBuffer::Type t) + : ref(1), + type(t), + guard(nullptr), + usagePattern(QOpenGLBuffer::StaticDraw), + actualUsagePattern(QOpenGLBuffer::StaticDraw), + funcs(nullptr) + { + } + + QAtomicInt ref; + QOpenGLBuffer::Type type; + QOpenGLSharedResourceGuard *guard; + QOpenGLBuffer::UsagePattern usagePattern; + QOpenGLBuffer::UsagePattern actualUsagePattern; + QOpenGLExtensions *funcs; +}; + +/*! + Constructs a new buffer object of type QOpenGLBuffer::VertexBuffer. + + Note: this constructor just creates the QOpenGLBuffer instance. The actual + buffer object in the OpenGL server is not created until create() is called. + + \sa create() +*/ +QOpenGLBuffer::QOpenGLBuffer() + : d_ptr(new QOpenGLBufferPrivate(QOpenGLBuffer::VertexBuffer)) +{ +} + +/*! + Constructs a new buffer object of \a type. + + Note: this constructor just creates the QOpenGLBuffer instance. The actual + buffer object in the OpenGL server is not created until create() is called. + + \sa create() +*/ +QOpenGLBuffer::QOpenGLBuffer(QOpenGLBuffer::Type type) + : d_ptr(new QOpenGLBufferPrivate(type)) +{ +} + +/*! + Constructs a shallow copy of \a other. + + Note: QOpenGLBuffer does not implement copy-on-write semantics, + so \a other will be affected whenever the copy is modified. +*/ +QOpenGLBuffer::QOpenGLBuffer(const QOpenGLBuffer &other) + : d_ptr(other.d_ptr) +{ + d_ptr->ref.ref(); +} + +/*! + Destroys this buffer object, including the storage being + used in the OpenGL server. +*/ +QOpenGLBuffer::~QOpenGLBuffer() +{ + if (!d_ptr->ref.deref()) { + destroy(); + delete d_ptr; + } +} + +/*! + Assigns a shallow copy of \a other to this object. + + Note: QOpenGLBuffer does not implement copy-on-write semantics, + so \a other will be affected whenever the copy is modified. +*/ +QOpenGLBuffer &QOpenGLBuffer::operator=(const QOpenGLBuffer &other) +{ + if (d_ptr != other.d_ptr) { + other.d_ptr->ref.ref(); + if (!d_ptr->ref.deref()) { + destroy(); + delete d_ptr; + } + d_ptr = other.d_ptr; + } + return *this; +} + +/*! + Returns the type of buffer represented by this object. +*/ +QOpenGLBuffer::Type QOpenGLBuffer::type() const +{ + Q_D(const QOpenGLBuffer); + return d->type; +} + +/*! + Returns the usage pattern for this buffer object. + The default value is StaticDraw. + + \sa setUsagePattern() +*/ +QOpenGLBuffer::UsagePattern QOpenGLBuffer::usagePattern() const +{ + Q_D(const QOpenGLBuffer); + return d->usagePattern; +} + +/*! + Sets the usage pattern for this buffer object to \a value. + This function must be called before allocate() or write(). + + \sa usagePattern(), allocate(), write() +*/ +void QOpenGLBuffer::setUsagePattern(QOpenGLBuffer::UsagePattern value) +{ + Q_D(QOpenGLBuffer); + d->usagePattern = d->actualUsagePattern = value; +} + +namespace { + void freeBufferFunc(QOpenGLFunctions *funcs, GLuint id) + { + funcs->glDeleteBuffers(1, &id); + } +} + +/*! + Creates the buffer object in the OpenGL server. Returns \c true if + the object was created; false otherwise. + + This function must be called with a current QOpenGLContext. + The buffer will be bound to and can only be used in + that context (or any other context that is shared with it). + + This function will return false if the OpenGL implementation + does not support buffers, or there is no current QOpenGLContext. + + \sa isCreated(), allocate(), write(), destroy() +*/ +bool QOpenGLBuffer::create() +{ + Q_D(QOpenGLBuffer); + if (d->guard && d->guard->id()) + return true; + QOpenGLContext *ctx = QOpenGLContext::currentContext(); + if (ctx) { + delete d->funcs; + d->funcs = new QOpenGLExtensions(ctx); + GLuint bufferId = 0; + d->funcs->glGenBuffers(1, &bufferId); + if (bufferId) { + if (d->guard) + d->guard->free(); + + d->guard = new QOpenGLSharedResourceGuard(ctx, bufferId, freeBufferFunc); + return true; + } + } + return false; +} + +/*! + Returns \c true if this buffer has been created; false otherwise. + + \sa create(), destroy() +*/ +bool QOpenGLBuffer::isCreated() const +{ + Q_D(const QOpenGLBuffer); + return d->guard && d->guard->id(); +} + +/*! + Destroys this buffer object, including the storage being + used in the OpenGL server. All references to the buffer will + become invalid. +*/ +void QOpenGLBuffer::destroy() +{ + Q_D(QOpenGLBuffer); + if (d->guard) { + d->guard->free(); + d->guard = nullptr; + } + delete d->funcs; + d->funcs = nullptr; +} + +/*! + Reads the \a count bytes in this buffer starting at \a offset + into \a data. Returns \c true on success; false if reading from + the buffer is not supported. Buffer reading is not supported + under OpenGL/ES. + + It is assumed that this buffer has been bound to the current context. + + \sa write(), bind() +*/ +bool QOpenGLBuffer::read(int offset, void *data, int count) +{ +#if !defined(QT_OPENGL_ES) + Q_D(QOpenGLBuffer); + if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers) || !d->guard->id()) + return false; + + while (true) { // Clear error state. + GLenum error = d->funcs->glGetError(); + if (error == GL_NO_ERROR) + break; + if (error == GL_CONTEXT_LOST) + return false; + }; + d->funcs->glGetBufferSubData(d->type, offset, count, data); + return d->funcs->glGetError() == GL_NO_ERROR; +#else + Q_UNUSED(offset); + Q_UNUSED(data); + Q_UNUSED(count); + return false; +#endif +} + +/*! + Replaces the \a count bytes of this buffer starting at \a offset + with the contents of \a data. Any other bytes in the buffer + will be left unmodified. + + It is assumed that create() has been called on this buffer and that + it has been bound to the current context. + + \sa create(), read(), allocate() +*/ +void QOpenGLBuffer::write(int offset, const void *data, int count) +{ +#ifndef QT_NO_DEBUG + if (!isCreated()) + qWarning("QOpenGLBuffer::write(): buffer not created"); +#endif + Q_D(QOpenGLBuffer); + if (d->guard && d->guard->id()) + d->funcs->glBufferSubData(d->type, offset, count, data); +} + +/*! + Allocates \a count bytes of space to the buffer, initialized to + the contents of \a data. Any previous contents will be removed. + + It is assumed that create() has been called on this buffer and that + it has been bound to the current context. + + \sa create(), read(), write() +*/ +void QOpenGLBuffer::allocate(const void *data, int count) +{ +#ifndef QT_NO_DEBUG + if (!isCreated()) + qWarning("QOpenGLBuffer::allocate(): buffer not created"); +#endif + Q_D(QOpenGLBuffer); + if (d->guard && d->guard->id()) + d->funcs->glBufferData(d->type, count, data, d->actualUsagePattern); +} + +/*! + \fn void QOpenGLBuffer::allocate(int count) + \overload + + Allocates \a count bytes of space to the buffer. Any previous + contents will be removed. + + It is assumed that create() has been called on this buffer and that + it has been bound to the current context. + + \sa create(), write() +*/ + +/*! + Binds the buffer associated with this object to the current + OpenGL context. Returns \c false if binding was not possible, usually because + type() is not supported on this OpenGL implementation. + + The buffer must be bound to the same QOpenGLContext current when create() + was called, or to another QOpenGLContext that is sharing with it. + Otherwise, false will be returned from this function. + + \sa release(), create() +*/ +bool QOpenGLBuffer::bind() +{ +#ifndef QT_NO_DEBUG + if (!isCreated()) + qWarning("QOpenGLBuffer::bind(): buffer not created"); +#endif + Q_D(const QOpenGLBuffer); + GLuint bufferId = d->guard ? d->guard->id() : 0; + if (bufferId) { + if (d->guard->group() != QOpenGLContextGroup::currentContextGroup()) { +#ifndef QT_NO_DEBUG + qWarning("QOpenGLBuffer::bind: buffer is not valid in the current context"); +#endif + return false; + } + d->funcs->glBindBuffer(d->type, bufferId); + return true; + } else { + return false; + } +} + +/*! + Releases the buffer associated with this object from the + current OpenGL context. + + This function must be called with the same QOpenGLContext current + as when bind() was called on the buffer. + + \sa bind() +*/ +void QOpenGLBuffer::release() +{ +#ifndef QT_NO_DEBUG + if (!isCreated()) + qWarning("QOpenGLBuffer::release(): buffer not created"); +#endif + Q_D(const QOpenGLBuffer); + if (d->guard && d->guard->id()) + d->funcs->glBindBuffer(d->type, 0); +} + +/*! + Releases the buffer associated with \a type in the current + QOpenGLContext. + + This function is a direct call to \c{glBindBuffer(type, 0)} + for use when the caller does not know which QOpenGLBuffer has + been bound to the context but wants to make sure that it + is released. + + \snippet code/src_gui_opengl_qopenglbuffer.cpp 1 +*/ +void QOpenGLBuffer::release(QOpenGLBuffer::Type type) +{ + QOpenGLContext *ctx = QOpenGLContext::currentContext(); + if (ctx) + ctx->functions()->glBindBuffer(GLenum(type), 0); +} + +/*! + Returns the OpenGL identifier associated with this buffer; zero if + the buffer has not been created. + + \sa isCreated() +*/ +GLuint QOpenGLBuffer::bufferId() const +{ + Q_D(const QOpenGLBuffer); + return d->guard ? d->guard->id() : 0; +} + +/*! + Returns the size of the data in this buffer, for reading operations. + Returns -1 if fetching the buffer size is not supported, or the + buffer has not been created. + + It is assumed that this buffer has been bound to the current context. + + \sa isCreated(), bind() +*/ +int QOpenGLBuffer::size() const +{ + Q_D(const QOpenGLBuffer); + if (!d->guard || !d->guard->id()) + return -1; + GLint value = -1; + d->funcs->glGetBufferParameteriv(d->type, GL_BUFFER_SIZE, &value); + return value; +} + +/*! + Maps the contents of this buffer into the application's memory + space and returns a pointer to it. Returns null if memory + mapping is not possible. The \a access parameter indicates the + type of access to be performed. + + It is assumed that create() has been called on this buffer and that + it has been bound to the current context. + + \note This function is only supported under OpenGL ES 2.0 or + earlier if the \c GL_OES_mapbuffer extension is present. + + \note On OpenGL ES 3.0 and newer, or, in case if desktop OpenGL, + if \c GL_ARB_map_buffer_range is supported, this function uses + \c glMapBufferRange instead of \c glMapBuffer. + + \sa unmap(), create(), bind(), mapRange() +*/ +void *QOpenGLBuffer::map(QOpenGLBuffer::Access access) +{ + Q_D(QOpenGLBuffer); +#ifndef QT_NO_DEBUG + if (!isCreated()) + qWarning("QOpenGLBuffer::map(): buffer not created"); +#endif + if (!d->guard || !d->guard->id()) + return nullptr; + if (d->funcs->hasOpenGLExtension(QOpenGLExtensions::MapBufferRange)) { + QOpenGLBuffer::RangeAccessFlags rangeAccess; + switch (access) { + case QOpenGLBuffer::ReadOnly: + rangeAccess = QOpenGLBuffer::RangeRead; + break; + case QOpenGLBuffer::WriteOnly: + rangeAccess = QOpenGLBuffer::RangeWrite; + break; + case QOpenGLBuffer::ReadWrite: + rangeAccess = QOpenGLBuffer::RangeRead | QOpenGLBuffer::RangeWrite; + break; + } + return d->funcs->glMapBufferRange(d->type, 0, size(), rangeAccess); + } else { + return d->funcs->glMapBuffer(d->type, access); + } +} + +/*! + Maps the range specified by \a offset and \a count of the contents + of this buffer into the application's memory space and returns a + pointer to it. Returns null if memory mapping is not possible. + The \a access parameter specifies a combination of access flags. + + It is assumed that create() has been called on this buffer and that + it has been bound to the current context. + + \note This function is not available on OpenGL ES 2.0 and earlier. + + \sa unmap(), create(), bind() + */ +void *QOpenGLBuffer::mapRange(int offset, int count, QOpenGLBuffer::RangeAccessFlags access) +{ + Q_D(QOpenGLBuffer); +#ifndef QT_NO_DEBUG + if (!isCreated()) + qWarning("QOpenGLBuffer::mapRange(): buffer not created"); +#endif + if (!d->guard || !d->guard->id()) + return nullptr; + return d->funcs->glMapBufferRange(d->type, offset, count, access); +} + +/*! + Unmaps the buffer after it was mapped into the application's + memory space with a previous call to map(). Returns \c true if + the unmap succeeded; false otherwise. + + It is assumed that this buffer has been bound to the current context, + and that it was previously mapped with map(). + + \note This function is only supported under OpenGL ES 2.0 and + earlier if the \c{GL_OES_mapbuffer} extension is present. + + \sa map() +*/ +bool QOpenGLBuffer::unmap() +{ + Q_D(QOpenGLBuffer); +#ifndef QT_NO_DEBUG + if (!isCreated()) + qWarning("QOpenGLBuffer::unmap(): buffer not created"); +#endif + if (!d->guard || !d->guard->id()) + return false; + return d->funcs->glUnmapBuffer(d->type) == GL_TRUE; +} + +QT_END_NAMESPACE diff --git a/src/opengl/qopenglbuffer.h b/src/opengl/qopenglbuffer.h new file mode 100644 index 0000000000..8a099a0320 --- /dev/null +++ b/src/opengl/qopenglbuffer.h @@ -0,0 +1,145 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtOpenGL module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QOPENGLBUFFER_H +#define QOPENGLBUFFER_H + +#include + +#ifndef QT_NO_OPENGL + +#include +#include + +QT_BEGIN_NAMESPACE + + +class QOpenGLBufferPrivate; + +class Q_OPENGL_EXPORT QOpenGLBuffer +{ +public: + enum Type + { + VertexBuffer = 0x8892, // GL_ARRAY_BUFFER + IndexBuffer = 0x8893, // GL_ELEMENT_ARRAY_BUFFER + PixelPackBuffer = 0x88EB, // GL_PIXEL_PACK_BUFFER + PixelUnpackBuffer = 0x88EC // GL_PIXEL_UNPACK_BUFFER + }; + + QOpenGLBuffer(); + explicit QOpenGLBuffer(QOpenGLBuffer::Type type); + QOpenGLBuffer(const QOpenGLBuffer &other); + ~QOpenGLBuffer(); + + QOpenGLBuffer &operator=(const QOpenGLBuffer &other); + + enum UsagePattern + { + StreamDraw = 0x88E0, // GL_STREAM_DRAW + StreamRead = 0x88E1, // GL_STREAM_READ + StreamCopy = 0x88E2, // GL_STREAM_COPY + StaticDraw = 0x88E4, // GL_STATIC_DRAW + StaticRead = 0x88E5, // GL_STATIC_READ + StaticCopy = 0x88E6, // GL_STATIC_COPY + DynamicDraw = 0x88E8, // GL_DYNAMIC_DRAW + DynamicRead = 0x88E9, // GL_DYNAMIC_READ + DynamicCopy = 0x88EA // GL_DYNAMIC_COPY + }; + + enum Access + { + ReadOnly = 0x88B8, // GL_READ_ONLY + WriteOnly = 0x88B9, // GL_WRITE_ONLY + ReadWrite = 0x88BA // GL_READ_WRITE + }; + + enum RangeAccessFlag + { + RangeRead = 0x0001, // GL_MAP_READ_BIT + RangeWrite = 0x0002, // GL_MAP_WRITE_BIT + RangeInvalidate = 0x0004, // GL_MAP_INVALIDATE_RANGE_BIT + RangeInvalidateBuffer = 0x0008, // GL_MAP_INVALIDATE_BUFFER_BIT + RangeFlushExplicit = 0x0010, // GL_MAP_FLUSH_EXPLICIT_BIT + RangeUnsynchronized = 0x0020 // GL_MAP_UNSYNCHRONIZED_BIT + }; + Q_DECLARE_FLAGS(RangeAccessFlags, RangeAccessFlag) + + QOpenGLBuffer::Type type() const; + + QOpenGLBuffer::UsagePattern usagePattern() const; + void setUsagePattern(QOpenGLBuffer::UsagePattern value); + + bool create(); + bool isCreated() const; + + void destroy(); + + bool bind(); + void release(); + + static void release(QOpenGLBuffer::Type type); + + GLuint bufferId() const; + + int size() const; + + bool read(int offset, void *data, int count); + void write(int offset, const void *data, int count); + + void allocate(const void *data, int count); + inline void allocate(int count) { allocate(nullptr, count); } + + void *map(QOpenGLBuffer::Access access); + void *mapRange(int offset, int count, QOpenGLBuffer::RangeAccessFlags access); + bool unmap(); + +private: + QOpenGLBufferPrivate *d_ptr; + + Q_DECLARE_PRIVATE(QOpenGLBuffer) +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(QOpenGLBuffer::RangeAccessFlags) + +QT_END_NAMESPACE + +#endif // QT_NO_OPENGL + +#endif diff --git a/src/opengl/qopengltextureblitter.cpp b/src/opengl/qopengltextureblitter.cpp index c695ae626d..b350e8e0e3 100644 --- a/src/opengl/qopengltextureblitter.cpp +++ b/src/opengl/qopengltextureblitter.cpp @@ -41,7 +41,7 @@ #include #include -#include +#include #include #include -- cgit v1.2.3