mirror of
https://github.com/love2d/love.git
synced 2026-08-20 12:40:20 +02:00
Slightly improved the performance of SpriteBatch:setBufferSize.
This commit is contained in:
@@ -47,7 +47,7 @@ SpriteBatch::SpriteBatch(Texture *texture, int size, int usage)
|
|||||||
, next(0)
|
, next(0)
|
||||||
, color(0)
|
, color(0)
|
||||||
, array_buf(nullptr)
|
, array_buf(nullptr)
|
||||||
, element_buf(nullptr)
|
, element_buf(size)
|
||||||
, buffer_used_offset(0)
|
, buffer_used_offset(0)
|
||||||
, buffer_used_size(0)
|
, buffer_used_size(0)
|
||||||
{
|
{
|
||||||
@@ -74,18 +74,15 @@ SpriteBatch::SpriteBatch(Texture *texture, int size, int usage)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
array_buf = VertexBuffer::Create(vertex_size, GL_ARRAY_BUFFER, gl_usage);
|
array_buf = VertexBuffer::Create(vertex_size, GL_ARRAY_BUFFER, gl_usage);
|
||||||
element_buf = new VertexIndex(size);
|
|
||||||
}
|
}
|
||||||
catch (love::Exception &)
|
catch (love::Exception &)
|
||||||
{
|
{
|
||||||
delete array_buf;
|
delete array_buf;
|
||||||
delete element_buf;
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
catch (std::bad_alloc &)
|
catch (std::bad_alloc &)
|
||||||
{
|
{
|
||||||
delete array_buf;
|
delete array_buf;
|
||||||
delete element_buf;
|
|
||||||
throw love::Exception("Out of memory.");
|
throw love::Exception("Out of memory.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -94,7 +91,6 @@ SpriteBatch::~SpriteBatch()
|
|||||||
{
|
{
|
||||||
delete color;
|
delete color;
|
||||||
delete array_buf;
|
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*/)
|
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.set(newtexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture *SpriteBatch::getTexture()
|
Texture *SpriteBatch::getTexture() const
|
||||||
{
|
{
|
||||||
return texture.get();
|
return texture.get();
|
||||||
}
|
}
|
||||||
@@ -216,40 +212,32 @@ void SpriteBatch::setBufferSize(int newsize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t vertex_size = sizeof(Vertex) * 4 * newsize;
|
size_t vertex_size = sizeof(Vertex) * 4 * newsize;
|
||||||
|
|
||||||
VertexBuffer *new_array_buf = nullptr;
|
VertexBuffer *new_array_buf = nullptr;
|
||||||
VertexIndex *new_element_buf = nullptr;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
new_array_buf = VertexBuffer::Create(vertex_size, array_buf->getTarget(), array_buf->getUsage());
|
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 &)
|
catch (love::Exception &)
|
||||||
{
|
{
|
||||||
delete new_array_buf;
|
delete new_array_buf;
|
||||||
delete new_element_buf;
|
|
||||||
throw;
|
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.
|
// We don't need to unmap the old VertexBuffer since we're deleting it.
|
||||||
delete array_buf;
|
delete array_buf;
|
||||||
delete element_buf;
|
|
||||||
|
|
||||||
array_buf = new_array_buf;
|
array_buf = new_array_buf;
|
||||||
element_buf = new_element_buf;
|
|
||||||
size = newsize;
|
size = newsize;
|
||||||
|
|
||||||
next = std::min(next, 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
|
int SpriteBatch::getBufferSize() const
|
||||||
@@ -275,7 +263,7 @@ void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float
|
|||||||
texture->predraw();
|
texture->predraw();
|
||||||
|
|
||||||
VertexBuffer::Bind array_bind(*array_buf);
|
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.)
|
// 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);
|
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));
|
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), array_buf->getPointer(texel_offset));
|
||||||
|
|
||||||
gl.prepareDraw();
|
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_VERTEX_ARRAY);
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
|||||||
@@ -26,13 +26,13 @@
|
|||||||
|
|
||||||
// LOVE
|
// LOVE
|
||||||
#include "common/math.h"
|
#include "common/math.h"
|
||||||
#include "common/Object.h"
|
|
||||||
#include "common/Matrix.h"
|
#include "common/Matrix.h"
|
||||||
#include "common/StringMap.h"
|
#include "common/StringMap.h"
|
||||||
#include "graphics/Drawable.h"
|
#include "graphics/Drawable.h"
|
||||||
#include "graphics/Volatile.h"
|
#include "graphics/Volatile.h"
|
||||||
#include "graphics/Color.h"
|
#include "graphics/Color.h"
|
||||||
#include "graphics/Quad.h"
|
#include "graphics/Quad.h"
|
||||||
|
#include "VertexBuffer.h"
|
||||||
|
|
||||||
namespace love
|
namespace love
|
||||||
{
|
{
|
||||||
@@ -43,8 +43,6 @@ namespace opengl
|
|||||||
|
|
||||||
// Forward declarations.
|
// Forward declarations.
|
||||||
class Texture;
|
class Texture;
|
||||||
class VertexBuffer;
|
|
||||||
class VertexIndex;
|
|
||||||
|
|
||||||
class SpriteBatch : public Drawable
|
class SpriteBatch : public Drawable
|
||||||
{
|
{
|
||||||
@@ -68,7 +66,7 @@ public:
|
|||||||
void flush();
|
void flush();
|
||||||
|
|
||||||
void setTexture(Texture *newtexture);
|
void setTexture(Texture *newtexture);
|
||||||
Texture *getTexture();
|
Texture *getTexture() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the current color for this SpriteBatch. The sprites added
|
* Set the current color for this SpriteBatch. The sprites added
|
||||||
@@ -139,7 +137,7 @@ private:
|
|||||||
Color *color;
|
Color *color;
|
||||||
|
|
||||||
VertexBuffer *array_buf;
|
VertexBuffer *array_buf;
|
||||||
VertexIndex *element_buf;
|
VertexIndex element_buf;
|
||||||
|
|
||||||
// The portion of the vertex buffer that's been modified while mapped.
|
// The portion of the vertex buffer that's been modified while mapped.
|
||||||
size_t buffer_used_offset;
|
size_t buffer_used_offset;
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ VBO::VBO(size_t size, GLenum target, GLenum usage, MemoryBacking backing)
|
|||||||
: VertexBuffer(size, target, usage, backing)
|
: VertexBuffer(size, target, usage, backing)
|
||||||
, vbo(0)
|
, vbo(0)
|
||||||
, memory_map(nullptr)
|
, memory_map(nullptr)
|
||||||
, is_dirty(true)
|
, is_dirty(false)
|
||||||
{
|
{
|
||||||
if (!(GLEE_ARB_vertex_buffer_object || GLEE_VERSION_1_5))
|
if (!(GLEE_ARB_vertex_buffer_object || GLEE_VERSION_1_5))
|
||||||
throw love::Exception("Not supported");
|
throw love::Exception("Not supported");
|
||||||
@@ -321,6 +321,20 @@ VertexIndex::VertexIndex(size_t size)
|
|||||||
addSize(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()
|
VertexIndex::~VertexIndex()
|
||||||
{
|
{
|
||||||
removeSize(size);
|
removeSize(size);
|
||||||
|
|||||||
@@ -412,6 +412,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
VertexIndex(size_t size);
|
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
|
* Removes an entry from the list of sizes and resizes the VertexBuffer
|
||||||
* if needed.
|
* if needed.
|
||||||
|
|||||||
Reference in New Issue
Block a user