X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=ref_counted_frame.h;h=59a16869c38fa923a639a56eca679b22b3eb871f;hb=327534a3031a332423411c9599c741f2f81657df;hp=6d66a769f59044079055cf5c7d0484e200ef2e2c;hpb=5bc2d4de98e960f40a11cd2991a25ea7d1d5a143;p=nageru diff --git a/ref_counted_frame.h b/ref_counted_frame.h index 6d66a76..59a1686 100644 --- a/ref_counted_frame.h +++ b/ref_counted_frame.h @@ -6,19 +6,55 @@ // // Note that the important point isn't really the pointer to the Frame itself, // it's the resources it's representing that need to go back to the allocator. +// +// FIXME: There's an issue here in that we could be releasing a frame while +// we're still uploading textures from it, causing it to be written to in +// another thread. (Thankfully, it goes to the back of the queue, and there's +// usually a render in-between, meaning it's fairly unlikely that someone +// actually managed to get to that race.) We should probably have some mechanism +// for registering fences. + +#include #include "bmusb/bmusb.h" -void release_refcounted_frame(FrameAllocator::Frame *frame); +void release_refcounted_frame(bmusb::FrameAllocator::Frame *frame); -typedef std::shared_ptr RefCountedFrameBase; +typedef std::shared_ptr RefCountedFrameBase; class RefCountedFrame : public RefCountedFrameBase { public: RefCountedFrame() {} - RefCountedFrame(const FrameAllocator::Frame &frame) - : RefCountedFrameBase(new FrameAllocator::Frame(frame), release_refcounted_frame) {} + RefCountedFrame(const bmusb::FrameAllocator::Frame &frame) + : RefCountedFrameBase(new bmusb::FrameAllocator::Frame(frame), release_refcounted_frame) {} +}; + +// Similar to RefCountedFrame, but as unique_ptr instead of shared_ptr. + +struct Unique_frame_deleter { + void operator() (bmusb::FrameAllocator::Frame *frame) const { + release_refcounted_frame(frame); + } +}; + +typedef std::unique_ptr + UniqueFrameBase; + +class UniqueFrame : public UniqueFrameBase { +public: + UniqueFrame() {} + + UniqueFrame(const bmusb::FrameAllocator::Frame &frame) + : UniqueFrameBase(new bmusb::FrameAllocator::Frame(frame)) {} + + bmusb::FrameAllocator::Frame get_and_release() + { + bmusb::FrameAllocator::Frame *ptr = release(); + bmusb::FrameAllocator::Frame frame = *ptr; + delete ptr; + return frame; + } }; #endif // !defined(_REF_COUNTED_FRAME_H)