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