Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <functional>
- #include <glew.h>
- #include <memory>
- #include <SDL.h>
- static int allocCount = 0;
- void* operator new(size_t size)
- {
- ++allocCount;
- return malloc(size);
- }
- typedef unsigned long long uint;
- typedef unsigned char uchar;
- class RenderCommandQueue
- {
- public:
- using RenderCommandFn = std::function<void()>;
- RenderCommandQueue();
- ~RenderCommandQueue() = default;
- void* Allocate(RenderCommandFn func, uint size);
- void Execute();
- private:
- std::unique_ptr<uchar[]> commandBuffer = nullptr;
- uchar* commandBufferPtr = nullptr;
- uint commandCount = 0;
- };
- RenderCommandQueue::RenderCommandQueue()
- {
- commandBuffer = std::make_unique<uchar[]>(10 * 1024 * 1024);
- commandBufferPtr = commandBuffer.get();
- }
- void* RenderCommandQueue::Allocate(RenderCommandFn fn, uint size)
- {
- // TODO: alignment
- *(RenderCommandFn*)commandBufferPtr = fn;
- commandBufferPtr += sizeof(RenderCommandFn);
- *(uint*)commandBufferPtr = size;
- commandBufferPtr += sizeof(uint);
- void* memory = commandBufferPtr;
- commandBufferPtr += size;
- commandCount++;
- return memory;
- }
- void RenderCommandQueue::Execute()
- {
- uchar* buffer = commandBuffer.get();
- for (uint i = 0; i < commandCount; i++) {
- RenderCommandFn function = *(RenderCommandFn*)buffer;
- buffer += sizeof(RenderCommandFn);
- uint size = *(uint*)buffer;
- buffer += sizeof(uint);
- function();
- buffer += size;
- }
- commandBufferPtr = commandBuffer.get();
- commandCount = 0;
- }
- static RenderCommandQueue queue;
- using RenderCommandFn = std::function<void()>;
- static void* Submit(RenderCommandFn fn, unsigned int size)
- {
- return queue.Allocate(fn, size);
- }
- void PushRenderCmd(RenderCommandFn fn)
- {
- auto mem = Submit(fn, sizeof(RenderCommandFn));
- }
- struct Vertex
- {
- float x, y;
- float u, v;
- };
- int main(int argc, char* args[])
- {
- //RenderCommandQueue does first allocation -> count = 1
- SDL_Window* window = SDL_CreateWindow("window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_OPENGL);
- SDL_GLContext glContext = SDL_GL_CreateContext(window);
- glewExperimental = true;
- glewInit();
- //Second allocation -> count = 2
- std::vector<Vertex> vertices;
- //Third allocation -> count = 3
- vertices.resize(60000);
- float r = 0.2f;
- float g = 0.2f;
- //No allocation -> count = 3
- PushRenderCmd([=](){
- glClearColor(r, g, 0.2f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
- });
- //No allocation -> count = 3
- GLuint vao;
- PushRenderCmd([&vao]() {
- glCreateVertexArrays(1, &vao);
- glBindVertexArray(vao);
- });
- GLuint vbo;
- //Fourth allocation -> count = 4
- void* ptr = new void* [512];
- //No allocation -> count = 4
- PushRenderCmd([&]() {
- glCreateBuffers(1, &vbo);
- glBindBuffer(GL_ARRAY_BUFFER, vbo);
- //No allocation -> count = 4
- glNamedBufferData(vbo, 512, ptr, GL_DYNAMIC_DRAW);
- delete[] ptr;
- });
- //Fifth allocation -> count = 5
- void* ptr2 = new void* [vertices.size()];
- std::memcpy(ptr2, vertices.data(), vertices.size());
- GLuint vbo2;
- //No allocation -> count = 5
- PushRenderCmd([&]() {
- glCreateBuffers(1, &vbo2);
- glBindBuffer(GL_ARRAY_BUFFER, vbo2);
- //No allocation -> count = 5
- glNamedBufferData(vbo2, vertices.size(), ptr2, GL_DYNAMIC_DRAW);
- delete[] ptr2;
- });
- queue.Execute();
- std::cout << allocCount << std::endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement