1 #ifndef ANDROID_DVR_SERVICES_DISPLAYD_ACQUIRED_BUFFER_H_
2 #define ANDROID_DVR_SERVICES_DISPLAYD_ACQUIRED_BUFFER_H_
3 
4 #include <pdx/file_handle.h>
5 #include <private/dvr/consumer_buffer.h>
6 
7 #include <memory>
8 
9 namespace android {
10 namespace dvr {
11 
12 // Manages the ACQUIRE/RELEASE ownership cycle of a ConsumerBuffer.
13 class AcquiredBuffer {
14  public:
15   static constexpr int kEmptyFence = pdx::LocalHandle::kEmptyFileHandle;
16 
AcquiredBuffer()17   AcquiredBuffer() : buffer_(nullptr), acquire_fence_(kEmptyFence) {}
18 
19   // Constructs an AcquiredBuffer from a ConsumerBuffer pointer and an acquire
20   // fence. The ConsumerBuffer MUST be in the ACQUIRED state prior to calling
21   // this constructor; the constructor does not attempt to ACQUIRE the buffer
22   // itself.
23   AcquiredBuffer(const std::shared_ptr<ConsumerBuffer>& buffer,
24                  pdx::LocalHandle acquire_fence, std::size_t slot = 0);
25 
26   // Constructs an AcquiredBuffer from a ConsumerBuffer. The ConsumerBuffer MUST
27   // be in the POSTED state prior to calling this constructor, as this
28   // constructor attempts to ACQUIRE the buffer. If ACQUIRING the buffer fails
29   // this instance is left in the empty state. An optional error code is
30   // returned in |error|, which may be nullptr if not needed.
31   AcquiredBuffer(const std::shared_ptr<ConsumerBuffer>& buffer, int* error);
32 
33   // Move constructor. Behaves similarly to the move assignment operator below.
34   AcquiredBuffer(AcquiredBuffer&& other) noexcept;
35 
36   ~AcquiredBuffer();
37 
38   // Move assignment operator. Moves the ConsumerBuffer and acquire fence from
39   // |other| into this instance after RELEASING the current ConsumerBuffer and
40   // closing the acquire fence. After the move |other| is left in the empty
41   // state.
42   AcquiredBuffer& operator=(AcquiredBuffer&& other) noexcept;
43 
44   // Accessors for the underlying ConsumerBuffer, the acquire fence, and the
45   // use-case specific sequence value from the acquisition (see
46   // private/dvr/consumer_buffer.h).
buffer()47   std::shared_ptr<ConsumerBuffer> buffer() const { return buffer_; }
acquire_fence()48   int acquire_fence() const { return acquire_fence_.Get(); }
49 
50   // When non-empty, returns true if the acquired fence was signaled (or if the
51   // fence is empty). Returns false when empty or if the fence is not signaled.
52   bool IsAvailable() const;
53 
IsEmpty()54   bool IsEmpty() const { return buffer_ == nullptr; }
55 
56   // Returns the acquire fence, passing ownership to the caller.
57   pdx::LocalHandle ClaimAcquireFence();
58 
59   // Returns the buffer, passing ownership to the caller. Caller is responsible
60   // for calling Release on the returned buffer.
61   std::shared_ptr<ConsumerBuffer> ClaimBuffer();
62 
63   // Releases the ConsumerBuffer, passing the release fence in |release_fence|
64   // to the producer. On success, the ConsumerBuffer and acquire fence are set
65   // to empty state; if release fails, the ConsumerBuffer and acquire fence are
66   // left in place and a negative error code is returned.
67   int Release(pdx::LocalHandle release_fence = {});
68 
69   // Returns the slot in the queue this buffer belongs to. Buffers that are not
70   // part of a queue return 0.
slot()71   std::size_t slot() const { return slot_; }
72 
73  private:
74   std::shared_ptr<ConsumerBuffer> buffer_;
75   // Mutable so that the fence can be closed when it is determined to be
76   // signaled during IsAvailable().
77   mutable pdx::LocalHandle acquire_fence_;
78   std::size_t slot_{0};
79 
80   AcquiredBuffer(const AcquiredBuffer&) = delete;
81   void operator=(const AcquiredBuffer&) = delete;
82 };
83 
84 }  // namespace dvr
85 }  // namespace android
86 
87 #endif  // ANDROID_DVR_SERVICES_DISPLAYD_ACQUIRED_BUFFER_H_
88