Browse Source

Implemented CHROMIUM_map_sub for Buffer.

pull/278/head
Vladimír Vondruš 13 years ago
parent
commit
fbdbd4aa01
  1. 33
      src/Buffer.cpp
  2. 50
      src/Buffer.h
  3. 4
      src/OpenGL.h
  4. 29
      src/Test/BufferGLTest.cpp

33
src/Buffer.cpp

@ -78,6 +78,14 @@ void Buffer::initializeContextBasedFunctionality(Context* context) {
#endif #endif
} }
Buffer::Buffer(Buffer::Target targetHint): _targetHint(targetHint)
#ifdef CORRADE_TARGET_NACL
, _mappedBuffer(nullptr)
#endif
{
glGenBuffers(1, &_id);
}
Buffer::~Buffer() { Buffer::~Buffer() {
GLuint* bindings = Context::current()->state()->buffer->bindings; GLuint* bindings = Context::current()->state()->buffer->bindings;
@ -127,6 +135,31 @@ Int Buffer::size() {
return size; return size;
} }
#ifdef MAGNUM_TARGET_GLES2
void* Buffer::mapSub(const GLintptr offset, const GLsizeiptr length, const MapAccess access) {
/** @todo Enable also in Emscripten (?) when extension wrangler is available */
#ifdef CORRADE_TARGET_NACL
CORRADE_ASSERT(!_mappedBuffer, "Buffer::mapSub(): the buffer is already mapped", nullptr);
return _mappedBuffer = glMapBufferSubDataCHROMIUM(static_cast<GLenum>(bindInternal(_targetHint)), offset, length, GLenum(access));
#else
CORRADE_INTERNAL_ASSERT(false);
static_cast<void>(offset);
static_cast<void>(length);
static_cast<void>(access);
#endif
}
void Buffer::unmapSub() {
#ifdef CORRADE_TARGET_NACL
CORRADE_ASSERT(_mappedBuffer, "Buffer::unmapSub(): the buffer is not mapped", );
glUnmapBufferSubDataCHROMIUM(_mappedBuffer);
_mappedBuffer = nullptr;
#else
CORRADE_INTERNAL_ASSERT(false);
#endif
}
#endif
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
void Buffer::copyImplementationDefault(Buffer* read, Buffer* write, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) { void Buffer::copyImplementationDefault(Buffer* read, Buffer* write, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) {
glCopyBufferSubData(static_cast<GLenum>(read->bindInternal(Target::CopyRead)), static_cast<GLenum>(write->bindInternal(Target::CopyWrite)), readOffset, writeOffset, size); glCopyBufferSubData(static_cast<GLenum>(read->bindInternal(Target::CopyRead)), static_cast<GLenum>(write->bindInternal(Target::CopyWrite)), readOffset, writeOffset, size);

50
src/Buffer.h

@ -324,9 +324,10 @@ class MAGNUM_EXPORT Buffer {
* *
* @deprecated Prefer to use @ref Magnum::Buffer::map(GLintptr, GLsizeiptr, MapFlags) "map(GLintptr, GLsizeiptr, MapFlags)" * @deprecated Prefer to use @ref Magnum::Buffer::map(GLintptr, GLsizeiptr, MapFlags) "map(GLintptr, GLsizeiptr, MapFlags)"
* instead, as it has more complete set of features. * instead, as it has more complete set of features.
* @see map(MapAccess) * @see map(MapAccess), mapSub()
* @requires_es_extension %Extension @es_extension{OES,mapbuffer} in * @requires_es_extension %Extension @es_extension{OES,mapbuffer} or
* OpenGL ES 2.0, use @ref Magnum::Buffer::map(GLintptr, GLsizeiptr, MapFlags) "map(GLintptr, GLsizeiptr, MapFlags)" * @es_extension{CHROMIUM,map_sub} in OpenGL ES 2.0, use
* @ref Magnum::Buffer::map(GLintptr, GLsizeiptr, MapFlags) "map(GLintptr, GLsizeiptr, MapFlags)"
* in OpenGL ES 3.0 instead. * in OpenGL ES 3.0 instead.
*/ */
enum class MapAccess: GLenum { enum class MapAccess: GLenum {
@ -471,9 +472,7 @@ class MAGNUM_EXPORT Buffer {
* Generates new OpenGL buffer. * Generates new OpenGL buffer.
* @see @fn_gl{GenBuffers} * @see @fn_gl{GenBuffers}
*/ */
explicit Buffer(Target targetHint = Target::Array): _targetHint(targetHint) { explicit Buffer(Target targetHint = Target::Array);
glGenBuffers(1, &_id);
}
/** /**
* @brief Destructor * @brief Destructor
@ -728,6 +727,27 @@ class MAGNUM_EXPORT Buffer {
} }
#endif #endif
#if defined(MAGNUM_TARGET_GLES2) || defined(DOXYGEN_GENERATING_OUTPUT)
/**
* @brief Map portion of buffer to client memory
* @param offset Offset into the buffer
* @param length Length of the mapped memory
* @param access Access
* @return Pointer to buffer data
*
* If the buffer is not already bound somewhere, it is bound to hinted
* target before the operation.
* @deprecated Prefer to use @ref Magnum::Buffer::map(GLintptr, GLsizeiptr, MapFlags) "map(GLintptr, GLsizeiptr, MapFlags)"
* instead, as it has more complete set of features.
* @see unmapSub(), setTargetHint(), @fn_gl_extension{MapBufferSubData,CHROMIUM,map_sub}
* @requires_gles20 Not available in ES 3.0 or desktop OpenGL. Use
* @ref Magnum::Buffer::map(GLintptr, GLsizeiptr, MapFlags) "map(GLintptr, GLsizeiptr, MapFlags)"
* instead.
* @requires_es_extension %Extension @es_extension{CHROMIUM,map_sub}
*/
void* mapSub(GLintptr offset, GLsizeiptr length, MapAccess access);
#endif
/** /**
* @brief Map buffer to client memory * @brief Map buffer to client memory
* @param offset Offset into the buffer * @param offset Offset into the buffer
@ -789,6 +809,21 @@ class MAGNUM_EXPORT Buffer {
return (this->*unmapImplementation)(); return (this->*unmapImplementation)();
} }
#if defined(MAGNUM_TARGET_GLES2) || defined(DOXYGEN_GENERATING_OUTPUT)
/**
* @brief Unmap portion of buffer
*
* Unmaps portion of buffer previously mapped with mapSub(),
* invalidating the pointer returned by the function.
* @see @fn_gl_extension{UnmapBufferSubData,CHROMIUM,map_sub}
* @requires_gles20 Not available in ES 3.0 or desktop OpenGL. Use
* @ref Magnum::Buffer::map(GLintptr, GLsizeiptr, MapFlags) "map(GLintptr, GLsizeiptr, MapFlags)"
* instead.
* @requires_es_extension %Extension @es_extension{CHROMIUM,map_sub}
*/
void unmapSub();
#endif
private: private:
static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context* context); static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context* context);
@ -878,6 +913,9 @@ class MAGNUM_EXPORT Buffer {
GLuint _id; GLuint _id;
Target _targetHint; Target _targetHint;
#ifdef CORRADE_TARGET_NACL
void* _mappedBuffer;
#endif
}; };
CORRADE_ENUMSET_OPERATORS(Buffer::MapFlags) CORRADE_ENUMSET_OPERATORS(Buffer::MapFlags)

4
src/OpenGL.h

@ -40,6 +40,10 @@
to NaCl's gl2ext.h we are including our own to prevent undeclared symbol to NaCl's gl2ext.h we are including our own to prevent undeclared symbol
errors with some recent extensions. */ errors with some recent extensions. */
#elif defined(CORRADE_TARGET_NACL) #elif defined(CORRADE_TARGET_NACL)
/* Enable function prototypes (the supported ones shouldn't fail at link time) */
#define GL_GLEXT_PROTOTYPES
#include <GLES2/gl2.h> #include <GLES2/gl2.h>
#include <GLES2/gl2ext.h> #include <GLES2/gl2ext.h>
#undef __gl2ext_h_ #undef __gl2ext_h_

29
src/Test/BufferGLTest.cpp

@ -38,6 +38,9 @@ class BufferGLTest: public AbstractOpenGLTester {
void construct(); void construct();
void data(); void data();
void map(); void map();
#ifdef MAGNUM_TARGET_GLES2
void mapSub();
#endif
void mapRange(); void mapRange();
void mapRangeExplicitFlush(); void mapRangeExplicitFlush();
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
@ -52,6 +55,9 @@ BufferGLTest::BufferGLTest() {
addTests({&BufferGLTest::construct, addTests({&BufferGLTest::construct,
&BufferGLTest::data, &BufferGLTest::data,
&BufferGLTest::map, &BufferGLTest::map,
#ifdef MAGNUM_TARGET_GLES2
&BufferGLTest::mapSub,
#endif
&BufferGLTest::mapRange, &BufferGLTest::mapRange,
&BufferGLTest::mapRangeExplicitFlush, &BufferGLTest::mapRangeExplicitFlush,
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
@ -147,6 +153,29 @@ void BufferGLTest::map() {
} }
#endif #endif
#ifdef MAGNUM_TARGET_GLES2
void BufferGLTest::mapSub() {
if(!Context::current()->isExtensionSupported<Extensions::GL::CHROMIUM::map_sub>())
CORRADE_SKIP(Extensions::GL::CHROMIUM::map_sub::string() + std::string(" is not supported"));
Buffer buffer;
constexpr char data[] = {2, 7, 5, 13, 25};
buffer.setData(data, Buffer::Usage::StaticDraw);
char* contents = reinterpret_cast<char*>(buffer.mapSub(1, 4, Buffer::MapAccess::WriteOnly));
MAGNUM_VERIFY_NO_ERROR();
CORRADE_VERIFY(contents);
contents[3] = 107;
buffer.unmapSub();
MAGNUM_VERIFY_NO_ERROR();
/** @todo How to verify the contents in ES? */
}
#endif
void BufferGLTest::mapRange() { void BufferGLTest::mapRange() {
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::map_buffer_range>()) if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::map_buffer_range>())

Loading…
Cancel
Save