blob: 0e925ceb3bf5c220e8387083becfd9276ed9b68d [file] [log] [blame]
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -08001/*
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
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -080017#ifndef ANDROID_GUI_BUFFERHUBPRODUCER_H_
18#define ANDROID_GUI_BUFFERHUBPRODUCER_H_
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080019
Jiwen 'Steve' Cai0f950842018-01-16 17:05:54 -080020#include <gui/BufferSlot.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080021#include <gui/IGraphicBufferProducer.h>
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -070022#include <private/dvr/buffer_hub_queue_client.h>
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -080023#include <private/dvr/buffer_hub_queue_parcelable.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080024
25namespace android {
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080026
Jiwen 'Steve' Caic90a77f2018-01-14 15:42:29 -080027class BufferHubProducer : public IGraphicBufferProducer {
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -080028public:
29 static constexpr int kNoConnectedApi = -1;
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -070030
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -080031 // 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;
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -070036
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -080037 // Creates a BufferHubProducer instance by importing an existing prodcuer
38 // queue.
39 static sp<BufferHubProducer> Create(const std::shared_ptr<dvr::ProducerQueue>& producer);
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080040
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -080041 // 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);
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -080045
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -080046 // See |IGraphicBufferProducer::requestBuffer|
47 status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) override;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080048
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -080049 // 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;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080057
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -080058 // See |IGraphicBufferProducer::setAsyncMode|
59 status_t setAsyncMode(bool async) override;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080060
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -080061 // 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;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080065
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -080066 // See |IGraphicBufferProducer::detachBuffer|
67 status_t detachBuffer(int slot) override;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080068
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -080069 // See |IGraphicBufferProducer::detachNextBuffer|
70 status_t detachNextBuffer(sp<GraphicBuffer>* out_buffer, sp<Fence>* out_fence) override;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080071
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -080072 // See |IGraphicBufferProducer::attachBuffer|
73 status_t attachBuffer(int* out_slot, const sp<GraphicBuffer>& buffer) override;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080074
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -080075 // See |IGraphicBufferProducer::queueBuffer|
76 status_t queueBuffer(int slot, const QueueBufferInput& input,
77 QueueBufferOutput* output) override;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080078
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -080079 // See |IGraphicBufferProducer::cancelBuffer|
80 status_t cancelBuffer(int slot, const sp<Fence>& fence) override;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080081
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -080082 // See |IGraphicBufferProducer::query|
83 status_t query(int what, int* out_value) override;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080084
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -080085 // See |IGraphicBufferProducer::connect|
86 status_t connect(const sp<IProducerListener>& listener, int api,
87 bool producer_controlled_by_app, QueueBufferOutput* output) override;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080088
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -080089 // See |IGraphicBufferProducer::disconnect|
90 status_t disconnect(int api, DisconnectMode mode = DisconnectMode::Api) override;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080091
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -080092 // See |IGraphicBufferProducer::setSidebandStream|
93 status_t setSidebandStream(const sp<NativeHandle>& stream) override;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080094
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -080095 // See |IGraphicBufferProducer::allocateBuffers|
96 void allocateBuffers(uint32_t width, uint32_t height, PixelFormat format,
97 uint64_t usage) override;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080098
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -080099 // See |IGraphicBufferProducer::allowAllocation|
100 status_t allowAllocation(bool allow) override;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800101
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800102 // See |IGraphicBufferProducer::setGenerationNumber|
103 status_t setGenerationNumber(uint32_t generation_number) override;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800104
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800105 // See |IGraphicBufferProducer::getConsumerName|
106 String8 getConsumerName() const override;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800107
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800108 // See |IGraphicBufferProducer::setSharedBufferMode|
109 status_t setSharedBufferMode(bool shared_buffer_mode) override;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800110
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800111 // See |IGraphicBufferProducer::setAutoRefresh|
112 status_t setAutoRefresh(bool auto_refresh) override;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800113
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800114 // See |IGraphicBufferProducer::setDequeueTimeout|
115 status_t setDequeueTimeout(nsecs_t timeout) override;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800116
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800117 // See |IGraphicBufferProducer::getLastQueuedBuffer|
118 status_t getLastQueuedBuffer(sp<GraphicBuffer>* out_buffer, sp<Fence>* out_fence,
119 float out_transform_matrix[16]) override;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800120
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800121 // See |IGraphicBufferProducer::getFrameTimestamps|
122 void getFrameTimestamps(FrameEventHistoryDelta* /*outDelta*/) override;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800123
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800124 // See |IGraphicBufferProducer::getUniqueId|
125 status_t getUniqueId(uint64_t* out_id) const override;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800126
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800127 // See |IGraphicBufferProducer::getConsumerUsage|
128 status_t getConsumerUsage(uint64_t* out_usage) const override;
Chia-I Wue2786ea2017-08-07 10:36:08 -0700129
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800130 // 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);
Jiwen 'Steve' Cai5afb7402017-11-09 18:50:32 -0800137
Jiwen 'Steve' Caic90a77f2018-01-14 15:42:29 -0800138 IBinder* onAsBinder() override;
139
140protected:
141 // See |IGraphicBufferProducer::exportToParcel|
142 status_t exportToParcel(Parcel* parcel) override;
143
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800144private:
145 using LocalHandle = pdx::LocalHandle;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800146
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800147 // Private constructor to force use of |Create|.
148 BufferHubProducer() {}
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700149
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800150 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 }
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700155
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800156 // 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);
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700160
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800161 // Remove a buffer via BufferHubRPC.
162 status_t RemoveBuffer(size_t slot);
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700163
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800164 // 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();
Jiwen 'Steve' Cai005f45d2017-08-04 17:34:37 -0700167
Jiwen 'Steve' Cai42875352018-04-30 17:55:11 -0700168 // Helper function that implements the detachBuffer() call, but assuming |mutex_| has been
169 // locked already.
170 status_t DetachBufferLocked(size_t slot);
171
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800172 // Concreate implementation backed by BufferHubBuffer.
173 std::shared_ptr<dvr::ProducerQueue> queue_;
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700174
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800175 // Mutex for thread safety.
176 std::mutex mutex_;
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700177
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800178 // Connect client API, should be one of the NATIVE_WINDOW_API_* flags.
179 int connected_api_{kNoConnectedApi};
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800180
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800181 // |max_buffer_count_| sets the capacity of the underlying buffer queue.
182 int32_t max_buffer_count_{dvr::BufferHubQueue::kMaxQueueCapacity};
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -0700183
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800184 // |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};
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700187
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800188 // 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};
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700191
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800192 // |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};
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700198
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800199 // |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 {
Jiwen 'Steve' Cai1c730242018-12-31 18:40:02 -0800206 BufferHubSlot() : mProducerBuffer(nullptr), mIsReallocating(false) {}
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800207 // BufferSlot comes from android framework, using m prefix to comply with
208 // the name convention with the reset of data fields from BufferSlot.
Jiwen 'Steve' Cai1c730242018-12-31 18:40:02 -0800209 std::shared_ptr<dvr::ProducerBuffer> mProducerBuffer;
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800210 bool mIsReallocating;
211 };
212 BufferHubSlot buffers_[dvr::BufferHubQueue::kMaxQueueCapacity];
Jiwen 'Steve' Caid6cb17f2017-05-08 16:15:35 -0700213
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800214 // A uniqueId used by IGraphicBufferProducer interface.
215 const uint64_t unique_id_{genUniqueId()};
Jiwen 'Steve' Caic90a77f2018-01-14 15:42:29 -0800216
217 // A pending parcelable object which keeps the bufferhub channel alive.
218 dvr::ProducerQueueParcelable pending_producer_parcelable_;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800219};
220
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800221} // namespace android
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800222
Jiwen 'Steve' Cai9a6ddf72018-01-18 14:37:24 -0800223#endif // ANDROID_GUI_BUFFERHUBPRODUCER_H_