]> git.sesse.net Git - nageru/blob - ref_counted_frame.h
Release Nageru 1.7.2.
[nageru] / ref_counted_frame.h
1 #ifndef _REF_COUNTED_FRAME_H
2 #define _REF_COUNTED_FRAME_H 1
3
4 // A wrapper around FrameAllocator::Frame that is automatically refcounted;
5 // when the refcount goes to zero, the frame is given back to the allocator.
6 //
7 // Note that the important point isn't really the pointer to the Frame itself,
8 // it's the resources it's representing that need to go back to the allocator.
9 //
10 // FIXME: There's an issue here in that we could be releasing a frame while
11 // we're still uploading textures from it, causing it to be written to in
12 // another thread. (Thankfully, it goes to the back of the queue, and there's
13 // usually a render in-between, meaning it's fairly unlikely that someone
14 // actually managed to get to that race.) We should probably have some mechanism
15 // for registering fences.
16
17 #include <memory>
18
19 #include "bmusb/bmusb.h"
20
21 void release_refcounted_frame(bmusb::FrameAllocator::Frame *frame);
22
23 typedef std::shared_ptr<bmusb::FrameAllocator::Frame> RefCountedFrameBase;
24
25 class RefCountedFrame : public RefCountedFrameBase {
26 public:
27         RefCountedFrame() {}
28
29         RefCountedFrame(const bmusb::FrameAllocator::Frame &frame)
30                 : RefCountedFrameBase(new bmusb::FrameAllocator::Frame(frame), release_refcounted_frame) {}
31 };
32
33 // Similar to RefCountedFrame, but as unique_ptr instead of shared_ptr.
34
35 struct Unique_frame_deleter {
36         void operator() (bmusb::FrameAllocator::Frame *frame) const {
37                 release_refcounted_frame(frame);
38         }
39 };
40
41 typedef std::unique_ptr<bmusb::FrameAllocator::Frame, Unique_frame_deleter>
42         UniqueFrameBase;
43
44 class UniqueFrame : public UniqueFrameBase {
45 public:
46         UniqueFrame() {}
47
48         UniqueFrame(const bmusb::FrameAllocator::Frame &frame)
49                 : UniqueFrameBase(new bmusb::FrameAllocator::Frame(frame)) {}
50
51         bmusb::FrameAllocator::Frame get_and_release()
52         {
53                 bmusb::FrameAllocator::Frame *ptr = release();
54                 bmusb::FrameAllocator::Frame frame = *ptr;
55                 delete ptr;
56                 return frame;
57         }
58 };
59
60 #endif  // !defined(_REF_COUNTED_FRAME_H)