Browse Source

Text: ported TextRenderer to not require buffer mapping in Emscripten.

The mapping is faked with client-side array, which is then uploaded on
"unmapping".
pull/23/head
Vladimír Vondruš 13 years ago
parent
commit
0f9b0e8130
  1. 23
      src/Text/TextRenderer.cpp
  2. 23
      src/Text/TextRenderer.h

23
src/Text/TextRenderer.cpp

@ -205,7 +205,7 @@ template<UnsignedInt dimensions> std::tuple<Mesh, Rectangle> TextRenderer<dimens
return std::move(r);
}
#ifdef MAGNUM_TARGET_GLES2
#if defined(MAGNUM_TARGET_GLES2) && !defined(CORRADE_TARGET_EMSCRIPTEN)
AbstractTextRenderer::BufferMapImplementation AbstractTextRenderer::bufferMapImplementation = &AbstractTextRenderer::bufferMapImplementationFull;
AbstractTextRenderer::BufferUnmapImplementation AbstractTextRenderer::bufferUnmapImplementation = &AbstractTextRenderer::bufferUnmapImplementationDefault;
@ -222,28 +222,37 @@ void AbstractTextRenderer::bufferUnmapImplementationSub(Buffer& buffer) {
}
#endif
#ifndef MAGNUM_TARGET_GLES2
#if !defined(MAGNUM_TARGET_GLES2) || defined(CORRADE_TARGET_EMSCRIPTEN)
inline void* AbstractTextRenderer::bufferMapImplementation(Buffer& buffer, GLsizeiptr length)
#else
void* AbstractTextRenderer::bufferMapImplementationRange(Buffer& buffer, GLsizeiptr length)
#endif
{
#ifndef CORRADE_TARGET_EMSCRIPTEN
return buffer.map(0, length, Buffer::MapFlag::InvalidateBuffer|Buffer::MapFlag::Write);
#else
static_cast<void>(length);
return &buffer == &_indexBuffer ? _indexBufferData : _vertexBufferData;
#endif
}
#ifndef MAGNUM_TARGET_GLES2
#if !defined(MAGNUM_TARGET_GLES2) || defined(CORRADE_TARGET_EMSCRIPTEN)
inline void AbstractTextRenderer::bufferUnmapImplementation(Buffer& buffer)
#else
void AbstractTextRenderer::bufferUnmapImplementationDefault(Buffer& buffer)
#endif
{
#ifndef CORRADE_TARGET_EMSCRIPTEN
buffer.unmap();
#else
buffer.setSubData(0, &buffer == &_indexBuffer ? _indexBufferData : _vertexBufferData);
#endif
}
AbstractTextRenderer::AbstractTextRenderer(AbstractFont& font, const GlyphCache& cache, Float size): _vertexBuffer(Buffer::Target::Array), _indexBuffer(Buffer::Target::ElementArray), font(font), cache(cache), size(size), _capacity(0) {
#ifndef MAGNUM_TARGET_GLES
MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::ARB::map_buffer_range);
#elif defined(MAGNUM_TARGET_GLES2)
#elif defined(MAGNUM_TARGET_GLES2) && !defined(CORRADE_TARGET_EMSCRIPTEN)
if(Context::current()->isExtensionSupported<Extensions::GL::EXT::map_buffer_range>()) {
bufferMapImplementation = &AbstractTextRenderer::bufferMapImplementationRange;
} else if(Context::current()->isExtensionSupported<Extensions::GL::CHROMIUM::map_sub>()) {
@ -279,6 +288,9 @@ void AbstractTextRenderer::reserve(const uint32_t glyphCount, const Buffer::Usag
/* Allocate vertex buffer, reset vertex count */
_vertexBuffer.setData(vertexCount*sizeof(Vertex), nullptr, vertexBufferUsage);
#ifdef CORRADE_TARGET_EMSCRIPTEN
_vertexBufferData = Containers::Array<UnsignedByte>(vertexCount*sizeof(Vertex));
#endif
_mesh.setVertexCount(0);
/* Allocate index buffer, reset index count and reconfigure buffer binding */
@ -295,6 +307,9 @@ void AbstractTextRenderer::reserve(const uint32_t glyphCount, const Buffer::Usag
indicesSize = indexCount*sizeof(UnsignedInt);
}
_indexBuffer.setData(indicesSize, nullptr, indexBufferUsage);
#ifdef CORRADE_TARGET_EMSCRIPTEN
_indexBufferData = Containers::Array<UnsignedByte>(indicesSize);
#endif
_mesh.setIndexCount(0)
.setIndexBuffer(_indexBuffer, 0, indexType, 0, vertexCount);

23
src/Text/TextRenderer.h

@ -129,6 +129,9 @@ class MAGNUM_TEXT_EXPORT AbstractTextRenderer {
Mesh _mesh;
Buffer _vertexBuffer, _indexBuffer;
#ifdef CORRADE_TARGET_EMSCRIPTEN
Containers::Array<UnsignedByte> _vertexBufferData, _indexBufferData;
#endif
private:
AbstractFont& font;
@ -137,23 +140,33 @@ class MAGNUM_TEXT_EXPORT AbstractTextRenderer {
UnsignedInt _capacity;
Rectangle _rectangle;
#ifdef MAGNUM_TARGET_GLES2
#if defined(MAGNUM_TARGET_GLES2) && !defined(CORRADE_TARGET_EMSCRIPTEN)
typedef void*(*BufferMapImplementation)(Buffer&, GLsizeiptr);
static MAGNUM_TEXT_LOCAL void* bufferMapImplementationFull(Buffer& buffer, GLsizeiptr length);
static MAGNUM_TEXT_LOCAL void* bufferMapImplementationSub(Buffer& buffer, GLsizeiptr length);
static MAGNUM_TEXT_LOCAL void* bufferMapImplementationRange(Buffer& buffer, GLsizeiptr length);
static BufferMapImplementation bufferMapImplementation;
#else
static void* bufferMapImplementation(Buffer& buffer, GLsizeiptr length);
#ifndef CORRADE_TARGET_EMSCRIPTEN
static
#else
MAGNUM_TEXT_LOCAL
#endif
void* bufferMapImplementation(Buffer& buffer, GLsizeiptr length);
#endif
#ifdef MAGNUM_TARGET_GLES2
#if defined(MAGNUM_TARGET_GLES2) && !defined(CORRADE_TARGET_EMSCRIPTEN)
typedef void(*BufferUnmapImplementation)(Buffer&);
static MAGNUM_TEXT_LOCAL void bufferUnmapImplementationDefault(Buffer& buffer);
static MAGNUM_TEXT_LOCAL void bufferUnmapImplementationSub(Buffer& buffer);
static MAGNUM_TEXT_LOCAL BufferUnmapImplementation bufferUnmapImplementation;
#else
static void bufferUnmapImplementation(Buffer& buffer);
#ifndef CORRADE_TARGET_EMSCRIPTEN
static
#else
MAGNUM_TEXT_LOCAL
#endif
void bufferUnmapImplementation(Buffer& buffer);
#endif
};
@ -222,6 +235,8 @@ Mutable text rendering requires @extension{ARB,map_buffer_range} on desktop
OpenGL (also part of OpenGL ES 3.0). If neither @es_extension{EXT,map_buffer_range}
nor @es_extension{CHROMIUM,map_sub} is not available in ES 2.0, at least
@es_extension{OES,mapbuffer} must be supported for asynchronous buffer updates.
There is no similar extension in WebGL, thus plain (and slow) buffer updates
are used there.
@see TextRenderer2D, TextRenderer3D, Font, Shaders::AbstractVectorShader
*/

Loading…
Cancel
Save