Improved performance of SpriteBatch:add/set in some cases when the SpriteBatch isn't bound

This commit is contained in:
Alex Szpakowski
2013-07-28 16:51:22 -03:00
parent 02d77aa9be
commit fa6eaaa3a6
+41 -2
View File
@@ -171,7 +171,7 @@ void VBO::unmap()
is_bound = true;
}
// "orphan" current buffer to avoid implicit synchronisation on the gpu:
// "orphan" current buffer to avoid implicit synchronisation on the GPU:
// http://www.seas.upenn.edu/~pcozzi/OpenGLInsights/OpenGLInsights-AsynchronousBufferTransfers.pdf
glBufferDataARB(getTarget(), getSize(), NULL, getUsage());
glBufferDataARB(getTarget(), getSize(), memory_map, getUsage());
@@ -204,7 +204,40 @@ void VBO::fill(size_t offset, size_t size, const void *data)
}
else
{
glBufferSubDataARB(getTarget(), offset, size, data);
// Not all systems have access to some faster paths...
if (GLEE_VERSION_3_0 || GLEE_ARB_map_buffer_range)
{
// Mapping a small range can have less chance of synchronization
// than glBufferSubData, so it may be faster.
GLbitfield access = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT;
void *mapdata = glMapBufferRange(getTarget(), offset, size, access);
if (mapdata)
memcpy(mapdata, data, size);
glUnmapBuffer(getTarget());
}
else if (GLEE_APPLE_flush_buffer_range)
{
void *mapdata = glMapBuffer(getTarget(), GL_WRITE_ONLY);
if (mapdata)
{
// We specified in VBO::load that we'll do manual flushing.
// Now we tell the driver it only needs to deal with the data
// we changed.
memcpy(static_cast<char *>(mapdata) + offset, data, size);
glFlushMappedBufferRangeAPPLE(getTarget(), offset, size);
}
glUnmapBuffer(getTarget());
}
else
{
// Fall back to a possibly slower SubData (more chance of syncing.)
glBufferSubDataARB(getTarget(), offset, size, data);
}
is_dirty = true;
}
}
@@ -240,6 +273,12 @@ bool VBO::load(bool restore)
glBufferDataARB(getTarget(), getSize(), src, getUsage());
GLenum err = glGetError();
// We don't want to flush the entire buffer when we just modify a small
// portion of it (VBO::fill without VBO::map), so we'll handle the flushing
// ourselves when we can.
if (GLEE_APPLE_flush_buffer_range)
glBufferParameteriAPPLE(getTarget(), GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE);
return (GL_NO_ERROR == err);
}