[update] Improved memory efficiency of ShapeElementProgram.

This commit is contained in:
falsycat 2019-10-15 00:00:00 +00:00
parent f5500b0b98
commit 3d992ee73b

View File

@ -9,13 +9,14 @@ import gl4d;
import sjplayer.AbstractShapeElement, import sjplayer.AbstractShapeElement,
sjplayer.ElementDrawerInterface, sjplayer.ElementDrawerInterface,
sjplayer.ScriptRuntimeException,
sjplayer.ShapeElementProgram; sjplayer.ShapeElementProgram;
/// ///
class ShapeElementDrawer(Program, vec2[] vertices) : ElementDrawerInterface { class ShapeElementDrawer(Program, vec2[] vertices) : ElementDrawerInterface {
public: public:
/// ///
enum MaxInstanceCount = 512; enum DefaultInstanceCount = 128;
/// ///
this(Program program, in AbstractShapeElement[] shapes) this(Program program, in AbstractShapeElement[] shapes)
@ -42,22 +43,18 @@ class ShapeElementDrawer(Program, vec2[] vertices) : ElementDrawerInterface {
} }
instances_.Bind(); instances_.Bind();
with (ArrayBufferAllocator()) { AllocateInstanceBufferIfNeeded(DefaultInstanceCount);
size = ShapeElementProgramInstance.sizeof * MaxInstanceCount;
usage = GL_DYNAMIC_DRAW;
Allocate(instances_);
}
} }
override void Draw() { override void Draw() {
size_t alive_count; const alive_count = shapes_.filter!"a.alive".count!"true";
instances_.Bind(); instances_.Bind();
AllocateInstanceBufferIfNeeded(alive_count);
{ {
auto ptr = instances_.MapToWrite!ShapeElementProgramInstance(); auto data = instances_.MapToWrite!ShapeElementProgramInstance();
auto ptr = data.entity;
foreach (const shape; shapes_.filter!"a.alive") { foreach (const shape; shapes_.filter!"a.alive") {
enforce(alive_count <= MaxInstanceCount); *ptr++ = shape.instance;
ptr[alive_count++] = shape.instance;
} }
} }
@ -70,6 +67,17 @@ class ShapeElementDrawer(Program, vec2[] vertices) : ElementDrawerInterface {
} }
private: private:
void AllocateInstanceBufferIfNeeded(size_t count) {
if (instances_count_ >= count) return;
with (ArrayBufferAllocator()) {
size = ShapeElementProgramInstance.sizeof * count;
usage = GL_DYNAMIC_DRAW;
Allocate(instances_);
}
instances_count_ = count;
}
Program program_; Program program_;
const AbstractShapeElement[] shapes_; const AbstractShapeElement[] shapes_;
@ -77,4 +85,6 @@ class ShapeElementDrawer(Program, vec2[] vertices) : ElementDrawerInterface {
ArrayBufferRef verts_; ArrayBufferRef verts_;
ArrayBufferRef instances_; ArrayBufferRef instances_;
VertexArrayRef vao_; VertexArrayRef vao_;
size_t instances_count_;
} }