From: David Gow Date: Tue, 22 Apr 2014 08:35:52 +0000 (+0800) Subject: Hideously useless buffer perf optimization. X-Git-Url: https://git.ucc.asn.au/?p=ipdf%2Fcode.git;a=commitdiff_plain;h=eff96d65bd1101083e04cb3ff2468b3feea3ff9e;hp=2c938c2219bb9d27830bb7412690887f6963d4af Hideously useless buffer perf optimization. --- diff --git a/bin/ipdf b/bin/ipdf index ce60299..bc85e7c 100755 Binary files a/bin/ipdf and b/bin/ipdf differ diff --git a/src/graphicsbuffer.cpp b/src/graphicsbuffer.cpp index 6f9ea9a..fe5ae1c 100644 --- a/src/graphicsbuffer.cpp +++ b/src/graphicsbuffer.cpp @@ -69,7 +69,9 @@ static GLenum BufferTypeToGLType(GraphicsBuffer::BufferType buffer_type) GraphicsBuffer::GraphicsBuffer() { m_invalidated = true; + m_map_pointer = nullptr; m_buffer_size = 0; + m_buffer_shape_dirty = true; SetUsage(BufferUsageStaticDraw); } @@ -84,13 +86,41 @@ GraphicsBuffer::~GraphicsBuffer() void GraphicsBuffer::SetType(GraphicsBuffer::BufferType bufType) { - glGenBuffers(1, &m_buffer_handle); m_buffer_type = bufType; } void GraphicsBuffer::SetUsage(GraphicsBuffer::BufferUsage bufUsage) { - m_buffer_usage = bufUsage; + if (bufUsage != m_buffer_usage) + { + m_buffer_usage = bufUsage; + m_buffer_shape_dirty = true; + } +} + +void GraphicsBuffer::Invalidate() +{ + m_invalidated = true; + // Apparently not supported. + //glInvalidateBufferData(m_buffer_handle); +} + +void GraphicsBuffer::RecreateBuffer() +{ + // If the buffer is not dirty, don't recreate it. + if (!m_buffer_shape_dirty) return; + // If the buffer is mapped, don't recreate it. + if (m_map_pointer) return; + // If the buffer has data in it we need, don't recreate it. + if (!m_invalidated) return; + if (m_buffer_handle) + { + glDeleteBuffers(1, &m_buffer_handle); + } + glGenBuffers(1, &m_buffer_handle); + m_buffer_shape_dirty = false; + if (m_buffer_size) + Upload(m_buffer_size, nullptr); } void* GraphicsBuffer::Map(bool read, bool write, bool invalidate) @@ -98,12 +128,19 @@ void* GraphicsBuffer::Map(bool read, bool write, bool invalidate) GLbitfield access = ((read)?GL_MAP_READ_BIT:0) | ((write)?GL_MAP_WRITE_BIT:0) | ((invalidate)?GL_MAP_INVALIDATE_BUFFER_BIT:0); GLenum target = BufferTypeToGLType(m_buffer_type); + if (invalidate) + m_invalidated = true; + + if (m_map_pointer) + Warn("Tried to map already mapped buffer!"); + + RecreateBuffer(); + Bind(); - return glMapBufferRange(target, 0, m_buffer_size, access); + m_map_pointer = glMapBufferRange(target, 0, m_buffer_size, access); - //TODO: Emulate DSA - //return glMapNamedBufferEXT(m_bufferHandle, access); + return m_map_pointer; } void* GraphicsBuffer::MapRange(int offset, int length, bool read, bool write, bool invalidate) @@ -111,12 +148,15 @@ void* GraphicsBuffer::MapRange(int offset, int length, bool read, bool write, bo GLbitfield access = ((read)?GL_MAP_READ_BIT:0) | ((write)?GL_MAP_WRITE_BIT:0) | ((invalidate)?GL_MAP_INVALIDATE_RANGE_BIT:0); GLenum target = BufferTypeToGLType(m_buffer_type); + if (m_map_pointer) + Warn("Tried to map already mapped buffer!"); + + RecreateBuffer(); + Bind(); - return glMapBufferRange(target, offset, length, access); - - //TODO: Emulate DSA - //return glMapNamedBufferRangeEXT(m_bufferHandle, offset, length, access); + m_map_pointer = glMapBufferRange(target, offset, length, access); + return m_map_pointer; } void GraphicsBuffer::UnMap() @@ -125,7 +165,7 @@ void GraphicsBuffer::UnMap() Bind(); glUnmapBuffer(target); - //glUnmapNamedBufferEXT(m_bufferHandle); + m_map_pointer = nullptr; } void GraphicsBuffer::Upload(size_t length, const void* data) @@ -133,27 +173,31 @@ void GraphicsBuffer::Upload(size_t length, const void* data) GLenum target = BufferTypeToGLType(m_buffer_type); GLenum usage = BufferUsageToGLUsage(m_buffer_usage); + + m_invalidated = true; + RecreateBuffer(); Bind(); glBufferData(target, length, data, usage); m_buffer_size = length; - //glNamedBufferDataEXT(m_bufferHandle, length, data, usage); } void GraphicsBuffer::UploadRange(size_t length, intptr_t offset, const void* data) { GLenum target = BufferTypeToGLType(m_buffer_type); + + RecreateBuffer(); Bind(); glBufferSubData(target, offset, length, data); - //glNamedBufferSubDataEXT(m_bufferHandle, offset, length, data); } void GraphicsBuffer::Resize(size_t length) { if (m_invalidated) { - Upload(length, nullptr); + m_buffer_size = length; + RecreateBuffer(); } else { @@ -166,9 +210,8 @@ void GraphicsBuffer::Resize(size_t length) glBindBuffer(GL_COPY_WRITE_BUFFER, m_buffer_handle); glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, m_buffer_size); glDeleteBuffers(1, &old_buffer); + m_buffer_size = length; } - m_buffer_size = length; - } void GraphicsBuffer::Bind() diff --git a/src/graphicsbuffer.h b/src/graphicsbuffer.h index d74d344..47534c9 100644 --- a/src/graphicsbuffer.h +++ b/src/graphicsbuffer.h @@ -9,7 +9,7 @@ namespace IPDF { /* - * The "Screen" class handles managing the OS window (using SDL2). + * Implementation of an OpenGL buffer, with some extra cleverness. */ class GraphicsBuffer { @@ -53,15 +53,19 @@ namespace IPDF void Resize(size_t length); const size_t GetSize() const { return m_buffer_size; } + + void Invalidate(); void Bind(); private: + void RecreateBuffer(); GLuint m_buffer_handle; BufferType m_buffer_type; BufferUsage m_buffer_usage; void *m_map_pointer; size_t m_buffer_size; bool m_invalidated; + bool m_buffer_shape_dirty; }; } diff --git a/src/log.h b/src/log.h index 0dfedfd..a98a8cc 100644 --- a/src/log.h +++ b/src/log.h @@ -35,7 +35,7 @@ inline std::string methodName(const std::string& prettyFunction) #define Debug(...) LogEx(LOG_DEBUG, __func__, __FILE__, __LINE__, __VA_ARGS__) #define Error(...) LogEx(LOG_ERR, __func__, __FILE__, __LINE__, __VA_ARGS__) -#define Warn(...) LogEx(LOG_WARN, __func__, __FILE__, __LINE__, __VA_ARGS__) +#define Warn(...) LogEx(LOG_WARNING, __func__, __FILE__, __LINE__, __VA_ARGS__) extern void LogEx(int level, const char * funct, const char * file, int line, ...); // General function for printing log messages to stderr diff --git a/src/screen.cpp b/src/screen.cpp index 8adb195..ecc8c20 100644 --- a/src/screen.cpp +++ b/src/screen.cpp @@ -255,7 +255,7 @@ void Screen::DebugFontInit(const char *name, float font_size) m_debug_font_vertices.SetUsage(GraphicsBuffer::BufferUsageStreamDraw); m_debug_font_vertices.SetType(GraphicsBuffer::BufferTypeVertex); - m_debug_font_vertices.Upload(512, nullptr); + m_debug_font_vertices.Upload(8192, nullptr); m_debug_font_vertex_head = 0; } @@ -290,7 +290,6 @@ void Screen::DebugFontFlush() glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(2, GL_FLOAT, 4*sizeof(float), (void*)(2*sizeof(float))); glTexCoordPointer(2, GL_FLOAT, 4*sizeof(float), 0); - Debug("Flushing Debug Font arrays, %d verts (%d floats)", m_debug_font_vertex_head/4, m_debug_font_vertex_head); glDrawArrays(GL_QUADS, 0, m_debug_font_vertex_head/4); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY);