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/buffer_hub_client.h>
6
7#include <memory>
8
9namespace android {
10namespace dvr {
11
12// Manages the ACQUIRE/RELEASE ownership cycle of a BufferConsumer.
13class AcquiredBuffer {
14 public:
15  static constexpr int kEmptyFence = pdx::LocalHandle::kEmptyFileHandle;
16
17  AcquiredBuffer() : buffer_(nullptr), acquire_fence_(kEmptyFence) {}
18
19  // Constructs an AcquiredBuffer from a BufferConsumer pointer and an acquire
20  // fence. The BufferConsumer 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<BufferConsumer>& buffer,
24                 pdx::LocalHandle acquire_fence, std::size_t slot = 0);
25
26  // Constructs an AcquiredBuffer from a BufferConsumer. The BufferConsumer 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<BufferConsumer>& buffer, int* error);
32
33  // Move constructor. Behaves similarly to the move assignment operator below.
34  AcquiredBuffer(AcquiredBuffer&& other);
35
36  ~AcquiredBuffer();
37
38  // Move assignment operator. Moves the BufferConsumer and acquire fence from
39  // |other| into this instance after RELEASING the current BufferConsumer and
40  // closing the acquire fence. After the move |other| is left in the empty
41  // state.
42  AcquiredBuffer& operator=(AcquiredBuffer&& other);
43
44  // Accessors for the underlying BufferConsumer, the acquire fence, and the
45  // use-case specific sequence value from the acquisition (see
46  // private/dvr/buffer_hub_client.h).
47  std::shared_ptr<BufferConsumer> buffer() const { return buffer_; }
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
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<BufferConsumer> ClaimBuffer();
62
63  // Releases the BufferConsumer, passing the release fence in |release_fence|
64  // to the producer. On success, the BufferConsumer and acquire fence are set
65  // to empty state; if release fails, the BufferConsumer 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.
71  std::size_t slot() const { return slot_; }
72
73 private:
74  std::shared_ptr<BufferConsumer> 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