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