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 
25 namespace android {
26 
27 class BufferHubProducer : public IGraphicBufferProducer {
28 public:
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 
140 protected:
141     // See |IGraphicBufferProducer::exportToParcel|
142     status_t exportToParcel(Parcel* parcel) override;
143 
144 private:
145     using LocalHandle = pdx::LocalHandle;
146 
147     // Private constructor to force use of |Create|.
BufferHubProducer()148     BufferHubProducer() {}
149 
genUniqueId()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     // Helper function that implements the detachBuffer() call, but assuming |mutex_| has been
169     // locked already.
170     status_t DetachBufferLocked(size_t slot);
171 
172     // Concreate implementation backed by BufferHubBuffer.
173     std::shared_ptr<dvr::ProducerQueue> queue_;
174 
175     // Mutex for thread safety.
176     std::mutex mutex_;
177 
178     // Connect client API, should be one of the NATIVE_WINDOW_API_* flags.
179     int connected_api_{kNoConnectedApi};
180 
181     // |max_buffer_count_| sets the capacity of the underlying buffer queue.
182     int32_t max_buffer_count_{dvr::BufferHubQueue::kMaxQueueCapacity};
183 
184     // |max_dequeued_buffer_count_| set the maximum number of buffers that can
185     // be dequeued at the same momment.
186     int32_t max_dequeued_buffer_count_{1};
187 
188     // Sets how long dequeueBuffer or attachBuffer will block if a buffer or
189     // slot is not yet available. The timeout is stored in milliseconds.
190     int dequeue_timeout_ms_{dvr::BufferHubQueue::kNoTimeOut};
191 
192     // |generation_number_| stores the current generation number of the attached
193     // producer. Any attempt to attach a buffer with a different generation
194     // number will fail.
195     // TOOD(b/38137191) Currently not used as we don't support
196     // IGraphicBufferProducer::detachBuffer.
197     uint32_t generation_number_{0};
198 
199     // |buffers_| stores the buffers that have been dequeued from
200     // |dvr::BufferHubQueue|, It is initialized to invalid buffers, and gets
201     // filled in with the result of |Dequeue|.
202     // TODO(jwcai) The buffer allocated to a slot will also be replaced if the
203     // requested buffer usage or geometry differs from that of the buffer
204     // allocated to a slot.
205     struct BufferHubSlot : public BufferSlot {
BufferHubSlotBufferHubSlot206         BufferHubSlot() : mProducerBuffer(nullptr), mIsReallocating(false) {}
207         // BufferSlot comes from android framework, using m prefix to comply with
208         // the name convention with the reset of data fields from BufferSlot.
209         std::shared_ptr<dvr::ProducerBuffer> mProducerBuffer;
210         bool mIsReallocating;
211     };
212     BufferHubSlot buffers_[dvr::BufferHubQueue::kMaxQueueCapacity];
213 
214     // A uniqueId used by IGraphicBufferProducer interface.
215     const uint64_t unique_id_{genUniqueId()};
216 
217     // A pending parcelable object which keeps the bufferhub channel alive.
218     dvr::ProducerQueueParcelable pending_producer_parcelable_;
219 };
220 
221 } // namespace android
222 
223 #endif // ANDROID_GUI_BUFFERHUBPRODUCER_H_
224