]> git.sesse.net Git - nageru/blob - futatabi/pbo_pool.cpp
Set CEF autoplay policy to be more lenient.
[nageru] / futatabi / pbo_pool.cpp
1 #include "pbo_pool.h"
2
3 #include <chrono>
4 #include <mutex>
5
6 #include <movit/util.h>
7
8 using namespace std;
9 using namespace std::chrono;
10
11 once_flag global_pbo_pool_inited;
12 PBOPool *global_pbo_pool = nullptr;
13
14 void init_pbo_pool()
15 {
16         call_once(global_pbo_pool_inited, []{
17                 global_pbo_pool = new PBOPool;
18         });
19 }
20
21 PBOPool::PBOPool(size_t pbo_size, size_t num_pbos, GLenum buffer, GLenum permissions, GLenum map_bits)
22         : pbo_size(pbo_size), buffer(buffer), permissions(permissions), map_bits(map_bits)
23 {
24         for (size_t i = 0; i < num_pbos; ++i) {
25                 freelist.push(create_pbo());
26         }
27 }
28
29 PBO PBOPool::alloc_pbo()
30 {
31         PBO pbo;
32         bool found_pbo = false;
33         {
34                 lock_guard<mutex> lock(freelist_mutex);
35                 if (!freelist.empty()) {
36                         pbo = move(freelist.front());
37                         freelist.pop();
38                         found_pbo = true;
39                 }
40         }
41
42         if (!found_pbo) {
43                 fprintf(stderr, "WARNING: Out of PBOs for texture upload, creating a new one\n");
44                 pbo = create_pbo();
45         }
46         if (pbo.upload_done != nullptr) {
47                 if (glClientWaitSync(pbo.upload_done.get(), 0, 0) == GL_TIMEOUT_EXPIRED) {
48                         steady_clock::time_point start = steady_clock::now();
49                         glClientWaitSync(pbo.upload_done.get(), /*flags=*/0, GL_TIMEOUT_IGNORED);
50                         steady_clock::time_point stop = steady_clock::now();
51
52                         fprintf(stderr, "WARNING: PBO was not ready after previous upload, had to wait %.1f ms before reusing\n",
53                                 1e3 * duration<double>(stop - start).count());
54                 }
55                 pbo.upload_done.reset();
56         }
57
58         return pbo;
59 }
60
61 void PBOPool::release_pbo(PBO pbo)
62 {
63         lock_guard<mutex> lock(freelist_mutex);
64         freelist.push(move(pbo));
65 }
66
67 PBO PBOPool::create_pbo()
68 {
69         PBO pbo;
70         
71         glCreateBuffers(1, &pbo.pbo);
72         check_error();
73         glNamedBufferStorage(pbo.pbo, pbo_size, nullptr, permissions | GL_MAP_PERSISTENT_BIT);
74         check_error();
75         pbo.ptr = (uint8_t *)glMapNamedBufferRange(pbo.pbo, 0, pbo_size, permissions | map_bits | GL_MAP_PERSISTENT_BIT);
76         check_error();
77
78         return pbo;
79 }