]> git.sesse.net Git - nageru/blob - pbo_frame_allocator.cpp
Initial checkin.
[nageru] / pbo_frame_allocator.cpp
1 #include "pbo_frame_allocator.h"
2 #include "util.h"
3
4 using namespace std;
5
6 PBOFrameAllocator::PBOFrameAllocator(size_t frame_size, size_t num_queued_frames, GLenum buffer, GLenum permissions, GLenum map_bits)
7         : frame_size(frame_size), buffer(buffer)
8 {
9         for (size_t i = 0; i < num_queued_frames; ++i) {
10                 GLuint pbo;
11                 glGenBuffers(1, &pbo);
12                 check_error();
13                 glBindBuffer(buffer, pbo);
14                 check_error();
15                 glBufferStorage(buffer, frame_size, NULL, permissions | GL_MAP_PERSISTENT_BIT);
16                 check_error();
17
18                 Frame frame;
19                 frame.data = (uint8_t *)glMapBufferRange(buffer, 0, frame_size, permissions | map_bits | GL_MAP_PERSISTENT_BIT);
20                 frame.data2 = frame.data + frame_size / 2;
21                 check_error();
22                 frame.size = frame_size;
23                 frame.userdata = (void *)(intptr_t)pbo;
24                 frame.owner = this;
25                 frame.interleaved = true;
26                 freelist.push(frame);
27         }
28         glBindBuffer(buffer, 0);
29         check_error();
30 }
31
32 PBOFrameAllocator::~PBOFrameAllocator()
33 {
34         while (!freelist.empty()) {
35                 Frame frame = freelist.front();
36                 freelist.pop();
37                 GLuint pbo = (intptr_t)frame.userdata;
38                 glBindBuffer(buffer, pbo);
39                 check_error();
40                 glUnmapBuffer(buffer);
41                 check_error();
42                 glBindBuffer(buffer, 0);
43                 check_error();
44                 glDeleteBuffers(1, &pbo);
45         }
46 }
47 //static int sumsum = 0;
48
49 FrameAllocator::Frame PBOFrameAllocator::alloc_frame()
50 {
51         Frame vf;
52
53         std::unique_lock<std::mutex> lock(freelist_mutex);  // Meh.
54         if (freelist.empty()) {
55                 printf("Frame overrun (no more spare PBO frames), dropping frame!\n");
56         } else {
57                 //fprintf(stderr, "freelist has %d allocated\n", ++sumsum);
58                 vf = freelist.front();
59                 freelist.pop();  // Meh.
60         }
61         vf.len = 0;
62         return vf;
63 }
64
65 void PBOFrameAllocator::release_frame(Frame frame)
66 {
67         std::unique_lock<std::mutex> lock(freelist_mutex);
68         freelist.push(frame);
69         //--sumsum;
70 }