Browse Source

Slightly improved the performance of SpriteBatch:setBufferSize.

Alex Szpakowski 11 years ago
parent
commit
5dda0c08eb

+ 11 - 23
src/modules/graphics/opengl/SpriteBatch.cpp

@@ -47,7 +47,7 @@ SpriteBatch::SpriteBatch(Texture *texture, int size, int usage)
 	, next(0)
 	, color(0)
 	, array_buf(nullptr)
-	, element_buf(nullptr)
+	, element_buf(size)
 	, buffer_used_offset(0)
 	, buffer_used_size(0)
 {
@@ -74,18 +74,15 @@ SpriteBatch::SpriteBatch(Texture *texture, int size, int usage)
 	try
 	{
 		array_buf = VertexBuffer::Create(vertex_size, GL_ARRAY_BUFFER, gl_usage);
-		element_buf = new VertexIndex(size);
 	}
 	catch (love::Exception &)
 	{
 		delete array_buf;
-		delete element_buf;
 		throw;
 	}
 	catch (std::bad_alloc &)
 	{
 		delete array_buf;
-		delete element_buf;
 		throw love::Exception("Out of memory.");
 	}
 }
@@ -94,7 +91,6 @@ SpriteBatch::~SpriteBatch()
 {
 	delete color;
 	delete array_buf;
-	delete element_buf;
 }
 
 int SpriteBatch::add(float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index /*= -1*/)
@@ -171,7 +167,7 @@ void SpriteBatch::setTexture(Texture *newtexture)
 	texture.set(newtexture);
 }
 
-Texture *SpriteBatch::getTexture()
+Texture *SpriteBatch::getTexture() const
 {
 	return texture.get();
 }
@@ -216,40 +212,32 @@ void SpriteBatch::setBufferSize(int newsize)
 	}
 
 	size_t vertex_size = sizeof(Vertex) * 4 * newsize;
-
 	VertexBuffer *new_array_buf = nullptr;
-	VertexIndex *new_element_buf = nullptr;
 
 	try
 	{
 		new_array_buf = VertexBuffer::Create(vertex_size, array_buf->getTarget(), array_buf->getUsage());
-		new_element_buf = new VertexIndex(newsize);
+
+		// Copy as much of the old data into the new VertexBuffer as can fit.
+		VertexBuffer::Bind bind(*new_array_buf);
+		void *new_data = new_array_buf->map();
+		memcpy(new_data, old_data, sizeof(Vertex) * 4 * std::min(newsize, size));
+
+		element_buf = VertexIndex(newsize);
 	}
 	catch (love::Exception &)
 	{
 		delete new_array_buf;
-		delete new_element_buf;
 		throw;
 	}
 
-	// Copy as much of the old data into the new VertexBuffer as can fit.
-	{
-		VertexBuffer::Bind bind(*new_array_buf);
-		new_array_buf->fill(0, sizeof(Vertex) * 4 * std::min(newsize, size), old_data);
-	}
-
 	// We don't need to unmap the old VertexBuffer since we're deleting it.
 	delete array_buf;
-	delete element_buf;
 
 	array_buf = new_array_buf;
-	element_buf = new_element_buf;
 	size = newsize;
 
 	next = std::min(next, newsize);
-
-	// The new VertexBuffer isn't mapped, so we should reset these variables.
-	buffer_used_offset = buffer_used_size = 0;
 }
 
 int SpriteBatch::getBufferSize() const
@@ -275,7 +263,7 @@ void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float
 	texture->predraw();
 
 	VertexBuffer::Bind array_bind(*array_buf);
-	VertexBuffer::Bind element_bind(*element_buf->getVertexBuffer());
+	VertexBuffer::Bind element_bind(*element_buf.getVertexBuffer());
 
 	// Make sure the VBO isn't mapped when we draw (sends data to GPU if needed.)
 	array_buf->unmap(buffer_used_offset, buffer_used_size);
@@ -297,7 +285,7 @@ void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float
 	glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), array_buf->getPointer(texel_offset));
 
 	gl.prepareDraw();
-	gl.drawElements(GL_TRIANGLES, element_buf->getIndexCount(next), element_buf->getType(), element_buf->getPointer(0));
+	gl.drawElements(GL_TRIANGLES, element_buf.getIndexCount(next), element_buf.getType(), element_buf.getPointer(0));
 
 	glDisableClientState(GL_VERTEX_ARRAY);
 	glDisableClientState(GL_TEXTURE_COORD_ARRAY);

+ 3 - 5
src/modules/graphics/opengl/SpriteBatch.h

@@ -26,13 +26,13 @@
 
 // LOVE
 #include "common/math.h"
-#include "common/Object.h"
 #include "common/Matrix.h"
 #include "common/StringMap.h"
 #include "graphics/Drawable.h"
 #include "graphics/Volatile.h"
 #include "graphics/Color.h"
 #include "graphics/Quad.h"
+#include "VertexBuffer.h"
 
 namespace love
 {
@@ -43,8 +43,6 @@ namespace opengl
 
 // Forward declarations.
 class Texture;
-class VertexBuffer;
-class VertexIndex;
 
 class SpriteBatch : public Drawable
 {
@@ -68,7 +66,7 @@ public:
 	void flush();
 
 	void setTexture(Texture *newtexture);
-	Texture *getTexture();
+	Texture *getTexture() const;
 
 	/**
 	 * Set the current color for this SpriteBatch. The sprites added
@@ -139,7 +137,7 @@ private:
 	Color *color;
 
 	VertexBuffer *array_buf;
-	VertexIndex *element_buf;
+	VertexIndex element_buf;
 
 	// The portion of the vertex buffer that's been modified while mapped.
 	size_t buffer_used_offset;

+ 15 - 1
src/modules/graphics/opengl/VertexBuffer.cpp

@@ -119,7 +119,7 @@ VBO::VBO(size_t size, GLenum target, GLenum usage, MemoryBacking backing)
 	: VertexBuffer(size, target, usage, backing)
 	, vbo(0)
 	, memory_map(nullptr)
-	, is_dirty(true)
+	, is_dirty(false)
 {
 	if (!(GLEE_ARB_vertex_buffer_object || GLEE_VERSION_1_5))
 		throw love::Exception("Not supported");
@@ -321,6 +321,20 @@ VertexIndex::VertexIndex(size_t size)
 	addSize(size);
 }
 
+VertexIndex::VertexIndex(const VertexIndex &other)
+	: size(other.size)
+{
+	addSize(size);
+}
+
+VertexIndex &VertexIndex::operator = (const VertexIndex &other)
+{
+	addSize(other.size);
+	removeSize(size);
+	size = other.size;
+	return *this;
+}
+
 VertexIndex::~VertexIndex()
 {
 	removeSize(size);

+ 3 - 0
src/modules/graphics/opengl/VertexBuffer.h

@@ -412,6 +412,9 @@ public:
 	 */
 	VertexIndex(size_t size);
 
+	VertexIndex(const VertexIndex &other);
+	VertexIndex &operator = (const VertexIndex &other);
+
 	/**
 	 * Removes an entry from the list of sizes and resizes the VertexBuffer
 	 * if needed.