1/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_GUI_BUFFERHUBPRODUCER_H_
18#define ANDROID_GUI_BUFFERHUBPRODUCER_H_
19
20#include <gui/BufferSlot.h>
21#include <gui/IGraphicBufferProducer.h>
22#include <private/dvr/buffer_hub_queue_client.h>
23#include <private/dvr/buffer_hub_queue_parcelable.h>
24
25namespace android {
26
27class BufferHubProducer : public IGraphicBufferProducer {
28public:
29    static constexpr int kNoConnectedApi = -1;
30
31    // TODO(b/36187402) The actual implementation of BufferHubQueue's consumer
32    // side logic doesn't limit the number of buffer it can acquire
33    // simultaneously. We need a way for consumer logic to configure and enforce
34    // that.
35    static constexpr int kDefaultUndequeuedBuffers = 1;
36
37    // Creates a BufferHubProducer instance by importing an existing prodcuer
38    // queue.
39    static sp<BufferHubProducer> Create(const std::shared_ptr<dvr::ProducerQueue>& producer);
40
41    // Creates a BufferHubProducer instance by importing an existing prodcuer
42    // parcelable. Note that this call takes the ownership of the parcelable
43    // object and is guaranteed to succeed if parcelable object is valid.
44    static sp<BufferHubProducer> Create(dvr::ProducerQueueParcelable parcelable);
45
46    // See |IGraphicBufferProducer::requestBuffer|
47    status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) override;
48
49    // For the BufferHub based implementation. All buffers in the queue are
50    // allowed to be dequeued from the consumer side. It call always returns
51    // 0 for |NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS| query. Thus setting
52    // |max_dequeued_buffers| here can be considered the same as setting queue
53    // capacity.
54    //
55    // See |IGraphicBufferProducer::setMaxDequeuedBufferCount| for more info
56    status_t setMaxDequeuedBufferCount(int max_dequeued_buffers) override;
57
58    // See |IGraphicBufferProducer::setAsyncMode|
59    status_t setAsyncMode(bool async) override;
60
61    // See |IGraphicBufferProducer::dequeueBuffer|
62    status_t dequeueBuffer(int* out_slot, sp<Fence>* out_fence, uint32_t width, uint32_t height,
63                           PixelFormat format, uint64_t usage, uint64_t* outBufferAge,
64                           FrameEventHistoryDelta* outTimestamps) override;
65
66    // See |IGraphicBufferProducer::detachBuffer|
67    status_t detachBuffer(int slot) override;
68
69    // See |IGraphicBufferProducer::detachNextBuffer|
70    status_t detachNextBuffer(sp<GraphicBuffer>* out_buffer, sp<Fence>* out_fence) override;
71
72    // See |IGraphicBufferProducer::attachBuffer|
73    status_t attachBuffer(int* out_slot, const sp<GraphicBuffer>& buffer) override;
74
75    // See |IGraphicBufferProducer::queueBuffer|
76    status_t queueBuffer(int slot, const QueueBufferInput& input,
77                         QueueBufferOutput* output) override;
78
79    // See |IGraphicBufferProducer::cancelBuffer|
80    status_t cancelBuffer(int slot, const sp<Fence>& fence) override;
81
82    // See |IGraphicBufferProducer::query|
83    status_t query(int what, int* out_value) override;
84
85    // See |IGraphicBufferProducer::connect|
86    status_t connect(const sp<IProducerListener>& listener, int api,
87                     bool producer_controlled_by_app, QueueBufferOutput* output) override;
88
89    // See |IGraphicBufferProducer::disconnect|
90    status_t disconnect(int api, DisconnectMode mode = DisconnectMode::Api) override;
91
92    // See |IGraphicBufferProducer::setSidebandStream|
93    status_t setSidebandStream(const sp<NativeHandle>& stream) override;
94
95    // See |IGraphicBufferProducer::allocateBuffers|
96    void allocateBuffers(uint32_t width, uint32_t height, PixelFormat format,
97                         uint64_t usage) override;
98
99    // See |IGraphicBufferProducer::allowAllocation|
100    status_t allowAllocation(bool allow) override;
101
102    // See |IGraphicBufferProducer::setGenerationNumber|
103    status_t setGenerationNumber(uint32_t generation_number) override;
104
105    // See |IGraphicBufferProducer::getConsumerName|
106    String8 getConsumerName() const override;
107
108    // See |IGraphicBufferProducer::setSharedBufferMode|
109    status_t setSharedBufferMode(bool shared_buffer_mode) override;
110
111    // See |IGraphicBufferProducer::setAutoRefresh|
112    status_t setAutoRefresh(bool auto_refresh) override;
113
114    // See |IGraphicBufferProducer::setDequeueTimeout|
115    status_t setDequeueTimeout(nsecs_t timeout) override;
116
117    // See |IGraphicBufferProducer::getLastQueuedBuffer|
118    status_t getLastQueuedBuffer(sp<GraphicBuffer>* out_buffer, sp<Fence>* out_fence,
119                                 float out_transform_matrix[16]) override;
120
121    // See |IGraphicBufferProducer::getFrameTimestamps|
122    void getFrameTimestamps(FrameEventHistoryDelta* /*outDelta*/) override;
123
124    // See |IGraphicBufferProducer::getUniqueId|
125    status_t getUniqueId(uint64_t* out_id) const override;
126
127    // See |IGraphicBufferProducer::getConsumerUsage|
128    status_t getConsumerUsage(uint64_t* out_usage) const override;
129
130    // Takes out the current producer as a binder parcelable object. Note that the
131    // producer must be disconnected to be exportable. After successful export,
132    // the producer queue can no longer be connected again. Returns NO_ERROR when
133    // takeout is successful and out_parcelable will hold the new parcelable
134    // object. Also note that out_parcelable cannot be NULL and must points to an
135    // invalid parcelable.
136    status_t TakeAsParcelable(dvr::ProducerQueueParcelable* out_parcelable);
137
138    IBinder* onAsBinder() override;
139
140protected:
141    // See |IGraphicBufferProducer::exportToParcel|
142    status_t exportToParcel(Parcel* parcel) override;
143
144private:
145    using LocalHandle = pdx::LocalHandle;
146
147    // Private constructor to force use of |Create|.
148    BufferHubProducer() {}
149
150    static uint64_t genUniqueId() {
151        static std::atomic<uint32_t> counter{0};
152        static uint64_t id = static_cast<uint64_t>(getpid()) << 32;
153        return id | counter++;
154    }
155
156    // Allocate new buffer through BufferHub and add it into |queue_| for
157    // bookkeeping.
158    status_t AllocateBuffer(uint32_t width, uint32_t height, uint32_t layer_count,
159                            PixelFormat format, uint64_t usage);
160
161    // Remove a buffer via BufferHubRPC.
162    status_t RemoveBuffer(size_t slot);
163
164    // Free all buffers which are owned by the prodcuer. Note that if graphic
165    // buffers are acquired by the consumer, we can't .
166    status_t FreeAllBuffers();
167
168    // Concreate implementation backed by BufferHubBuffer.
169    std::shared_ptr<dvr::ProducerQueue> queue_;
170
171    // Mutex for thread safety.
172    std::mutex mutex_;
173
174    // Connect client API, should be one of the NATIVE_WINDOW_API_* flags.
175    int connected_api_{kNoConnectedApi};
176
177    // |max_buffer_count_| sets the capacity of the underlying buffer queue.
178    int32_t max_buffer_count_{dvr::BufferHubQueue::kMaxQueueCapacity};
179
180    // |max_dequeued_buffer_count_| set the maximum number of buffers that can
181    // be dequeued at the same momment.
182    int32_t max_dequeued_buffer_count_{1};
183
184    // Sets how long dequeueBuffer or attachBuffer will block if a buffer or
185    // slot is not yet available. The timeout is stored in milliseconds.
186    int dequeue_timeout_ms_{dvr::BufferHubQueue::kNoTimeOut};
187
188    // |generation_number_| stores the current generation number of the attached
189    // producer. Any attempt to attach a buffer with a different generation
190    // number will fail.
191    // TOOD(b/38137191) Currently not used as we don't support
192    // IGraphicBufferProducer::detachBuffer.
193    uint32_t generation_number_{0};
194
195    // |buffers_| stores the buffers that have been dequeued from
196    // |dvr::BufferHubQueue|, It is initialized to invalid buffers, and gets
197    // filled in with the result of |Dequeue|.
198    // TODO(jwcai) The buffer allocated to a slot will also be replaced if the
199    // requested buffer usage or geometry differs from that of the buffer
200    // allocated to a slot.
201    struct BufferHubSlot : public BufferSlot {
202        BufferHubSlot() : mBufferProducer(nullptr), mIsReallocating(false) {}
203        // BufferSlot comes from android framework, using m prefix to comply with
204        // the name convention with the reset of data fields from BufferSlot.
205        std::shared_ptr<dvr::BufferProducer> mBufferProducer;
206        bool mIsReallocating;
207    };
208    BufferHubSlot buffers_[dvr::BufferHubQueue::kMaxQueueCapacity];
209
210    // A uniqueId used by IGraphicBufferProducer interface.
211    const uint64_t unique_id_{genUniqueId()};
212
213    // A pending parcelable object which keeps the bufferhub channel alive.
214    dvr::ProducerQueueParcelable pending_producer_parcelable_;
215};
216
217} // namespace android
218
219#endif // ANDROID_GUI_BUFFERHUBPRODUCER_H_
220