blob: c76d771262548a3a18b116252794ac1cb869a0d7 [file] [log] [blame]
Pawin Vongmasae672cd02019-02-14 16:01:29 -08001/*
2 * Copyright 2019 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//#define LOG_NDEBUG 0
Pawin Vongmasa23399ac2019-04-25 03:44:52 -070018#define LOG_TAG "B2HGraphicBufferProducer@2.0"
Pawin Vongmasae672cd02019-02-14 16:01:29 -080019
20#include <android-base/logging.h>
21
22#include <android/hardware/graphics/bufferqueue/2.0/types.h>
23#include <android/hardware/graphics/common/1.2/types.h>
24#include <gui/bufferqueue/2.0/H2BProducerListener.h>
25#include <gui/bufferqueue/2.0/B2HGraphicBufferProducer.h>
26#include <gui/bufferqueue/2.0/types.h>
27#include <ui/GraphicBuffer.h>
28#include <ui/Rect.h>
29#include <ui/Region.h>
30#include <vndk/hardware_buffer.h>
31
32namespace android {
Pawin Vongmasae672cd02019-02-14 16:01:29 -080033namespace hardware {
34namespace graphics {
35namespace bufferqueue {
36namespace V2_0 {
37namespace utils {
38
Pawin Vongmasa23399ac2019-04-25 03:44:52 -070039namespace /* unnamed */ {
40
41using BQueueBufferInput = ::android::
42 IGraphicBufferProducer::QueueBufferInput;
43using HQueueBufferInput = ::android::hardware::graphics::bufferqueue::V2_0::
44 IGraphicBufferProducer::QueueBufferInput;
45using BQueueBufferOutput = ::android::
46 IGraphicBufferProducer::QueueBufferOutput;
47using HQueueBufferOutput = ::android::hardware::graphics::bufferqueue::V2_0::
48 IGraphicBufferProducer::QueueBufferOutput;
49
50using ::android::hardware::graphics::bufferqueue::V2_0::utils::b2h;
51using ::android::hardware::graphics::bufferqueue::V2_0::utils::h2b;
52
53bool b2h(BQueueBufferOutput const& from, HQueueBufferOutput* to) {
54 to->width = from.width;
55 to->height = from.height;
56 to->transformHint = static_cast<int32_t>(from.transformHint);
57 to->numPendingBuffers = from.numPendingBuffers;
58 to->nextFrameNumber = from.nextFrameNumber;
59 to->bufferReplaced = from.bufferReplaced;
60 return true;
61}
62
63} // unnamed namespace
64
Pawin Vongmasae672cd02019-02-14 16:01:29 -080065// B2HGraphicBufferProducer
66// ========================
67
68B2HGraphicBufferProducer::B2HGraphicBufferProducer(
69 sp<BGraphicBufferProducer> const& base)
70 : mBase{base} {
71}
72
73Return<HStatus> B2HGraphicBufferProducer::setMaxDequeuedBufferCount(
74 int32_t maxDequeuedBuffers) {
75 HStatus hStatus{};
76 bool converted = b2h(
77 mBase->setMaxDequeuedBufferCount(
78 static_cast<int>(maxDequeuedBuffers)),
79 &hStatus);
80 return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
81}
82
83Return<void> B2HGraphicBufferProducer::requestBuffer(
84 int32_t slot,
85 requestBuffer_cb _hidl_cb) {
86 sp<GraphicBuffer> bBuffer;
87 HStatus hStatus{};
88 HardwareBuffer hBuffer{};
89 uint32_t hGenerationNumber{};
90 bool converted =
91 b2h(mBase->requestBuffer(
92 static_cast<int>(slot), &bBuffer),
93 &hStatus) &&
94 b2h(bBuffer, &hBuffer, &hGenerationNumber);
95 _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR,
96 hBuffer, hGenerationNumber);
97 return {};
98}
99
100Return<HStatus> B2HGraphicBufferProducer::setAsyncMode(bool async) {
101 HStatus hStatus{};
102 bool converted = b2h(mBase->setAsyncMode(async), &hStatus);
103 return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
104}
105
106Return<void> B2HGraphicBufferProducer::dequeueBuffer(
107 DequeueBufferInput const& input,
108 dequeueBuffer_cb _hidl_cb) {
109 int bSlot{};
110 sp<BFence> bFence;
111 HStatus hStatus{};
112 DequeueBufferOutput hOutput{};
113 HFenceWrapper hFenceWrapper;
114 bool converted =
115 b2h(mBase->dequeueBuffer(
116 &bSlot,
117 &bFence,
118 input.width,
119 input.height,
120 static_cast<PixelFormat>(input.format),
121 input.usage,
122 &hOutput.bufferAge,
123 nullptr /* outTimestamps */),
124 &hStatus,
125 &hOutput.bufferNeedsReallocation,
126 &hOutput.releaseAllBuffers) &&
127 b2h(bFence, &hFenceWrapper);
128 hOutput.fence = hFenceWrapper.getHandle();
129 _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR,
130 static_cast<int32_t>(bSlot),
131 hOutput);
132 return {};
133}
134
135Return<HStatus> B2HGraphicBufferProducer::detachBuffer(int32_t slot) {
136 HStatus hStatus{};
137 bool converted = b2h(
138 mBase->detachBuffer(static_cast<int>(slot)), &hStatus);
139 return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
140}
141
142Return<void> B2HGraphicBufferProducer::detachNextBuffer(
143 detachNextBuffer_cb _hidl_cb) {
144 sp<GraphicBuffer> bBuffer;
145 sp<BFence> bFence;
146 HStatus hStatus{};
147 HardwareBuffer hBuffer{};
148 HFenceWrapper hFenceWrapper;
149 bool converted =
150 b2h(mBase->detachNextBuffer(&bBuffer, &bFence), &hStatus) &&
151 b2h(bBuffer, &hBuffer) &&
152 b2h(bFence, &hFenceWrapper);
153 _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR,
154 hBuffer,
155 hFenceWrapper.getHandle());
156 return {};
157}
158
159Return<void> B2HGraphicBufferProducer::attachBuffer(
160 HardwareBuffer const& hBuffer,
161 uint32_t generationNumber,
162 attachBuffer_cb _hidl_cb) {
163 sp<GraphicBuffer> bBuffer;
164 if (!h2b(hBuffer, &bBuffer) || !bBuffer) {
165 _hidl_cb(HStatus::UNKNOWN_ERROR,
166 static_cast<int32_t>(SlotIndex::INVALID),
167 false);
168 return {};
169 }
170 bBuffer->setGenerationNumber(generationNumber);
171
172 int bSlot{};
173 HStatus hStatus{};
174 bool releaseAllBuffers{};
175 bool converted = b2h(
176 mBase->attachBuffer(&bSlot, bBuffer), &hStatus,
177 nullptr /* bufferNeedsReallocation */,
178 &releaseAllBuffers);
179 _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR,
180 static_cast<int32_t>(bSlot),
181 releaseAllBuffers);
182 return {};
183}
184
185Return<void> B2HGraphicBufferProducer::queueBuffer(
186 int32_t slot,
187 QueueBufferInput const& hInput,
188 queueBuffer_cb _hidl_cb) {
Pawin Vongmasa23399ac2019-04-25 03:44:52 -0700189 BQueueBufferInput bInput{
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800190 hInput.timestamp,
191 hInput.isAutoTimestamp,
192 static_cast<android_dataspace>(hInput.dataSpace),
193 {}, /* crop */
194 0 /* scalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE */,
195 static_cast<uint32_t>(hInput.transform),
196 {}, /* fence */
197 static_cast<uint32_t>(hInput.stickyTransform),
198 false /* getFrameTimestamps */};
199
200 // Convert crop.
201 if (!h2b(hInput.crop, &bInput.crop)) {
Pawin Vongmasa23399ac2019-04-25 03:44:52 -0700202 _hidl_cb(HStatus::UNKNOWN_ERROR, QueueBufferOutput{});
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800203 return {};
204 }
205
206 // Convert surfaceDamage.
207 if (!h2b(hInput.surfaceDamage, &bInput.surfaceDamage)) {
Pawin Vongmasa23399ac2019-04-25 03:44:52 -0700208 _hidl_cb(HStatus::UNKNOWN_ERROR, QueueBufferOutput{});
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800209 return {};
210 }
211
212 // Convert fence.
213 if (!h2b(hInput.fence, &bInput.fence)) {
Pawin Vongmasa23399ac2019-04-25 03:44:52 -0700214 _hidl_cb(HStatus::UNKNOWN_ERROR, QueueBufferOutput{});
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800215 return {};
216 }
217
Pawin Vongmasa23399ac2019-04-25 03:44:52 -0700218 BQueueBufferOutput bOutput{};
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800219 HStatus hStatus{};
Pawin Vongmasa23399ac2019-04-25 03:44:52 -0700220 QueueBufferOutput hOutput{};
221 bool converted =
222 b2h(
223 mBase->queueBuffer(static_cast<int>(slot), bInput, &bOutput),
224 &hStatus) &&
225 b2h(bOutput, &hOutput);
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800226
Pawin Vongmasa23399ac2019-04-25 03:44:52 -0700227 _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR, hOutput);
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800228 return {};
229}
230
231Return<HStatus> B2HGraphicBufferProducer::cancelBuffer(
232 int32_t slot,
233 hidl_handle const& fence) {
234 sp<BFence> bFence;
235 if (!h2b(fence.getNativeHandle(), &bFence)) {
236 return {HStatus::UNKNOWN_ERROR};
237 }
238 HStatus hStatus{};
239 bool converted = b2h(
240 mBase->cancelBuffer(static_cast<int>(slot), bFence),
241 &hStatus);
242 return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
243}
244
245Return<void> B2HGraphicBufferProducer::query(int32_t what, query_cb _hidl_cb) {
246 int value{};
247 int result = mBase->query(static_cast<int>(what), &value);
248 _hidl_cb(static_cast<int32_t>(result), static_cast<int32_t>(value));
249 return {};
250}
251
Chong Zhang62493092020-01-15 16:04:47 -0800252struct Obituary : public hardware::hidl_death_recipient {
253 wp<B2HGraphicBufferProducer> producer;
254 sp<HProducerListener> listener;
255 HConnectionType apiType;
256 Obituary(const wp<B2HGraphicBufferProducer>& p,
257 const sp<HProducerListener>& l,
258 HConnectionType t)
259 : producer(p), listener(l), apiType(t) {}
260
261 void serviceDied(uint64_t /* cookie */,
262 const wp<::android::hidl::base::V1_0::IBase>& /* who */) override {
263 sp<B2HGraphicBufferProducer> dr = producer.promote();
264 if (dr != nullptr) {
265 (void)dr->disconnect(apiType);
266 }
267 }
268};
269
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800270Return<void> B2HGraphicBufferProducer::connect(
271 sp<HProducerListener> const& hListener,
272 HConnectionType hConnectionType,
273 bool producerControlledByApp,
274 connect_cb _hidl_cb) {
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800275 sp<BProducerListener> bListener = new H2BProducerListener(hListener);
Pawin Vongmasa23399ac2019-04-25 03:44:52 -0700276 int bConnectionType{};
277 if (!bListener || !h2b(hConnectionType, &bConnectionType)) {
278 _hidl_cb(HStatus::UNKNOWN_ERROR, QueueBufferOutput{});
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800279 return {};
280 }
Pawin Vongmasa23399ac2019-04-25 03:44:52 -0700281 BQueueBufferOutput bOutput{};
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800282 HStatus hStatus{};
Pawin Vongmasa23399ac2019-04-25 03:44:52 -0700283 QueueBufferOutput hOutput{};
284 bool converted =
285 b2h(mBase->connect(bListener,
286 bConnectionType,
287 producerControlledByApp,
288 &bOutput),
289 &hStatus) &&
290 b2h(bOutput, &hOutput);
Chong Zhang3248ea02020-02-11 17:27:38 -0800291#ifdef NO_BINDER
292 if (converted && hListener != nullptr) {
Chong Zhang62493092020-01-15 16:04:47 -0800293 mObituary = new Obituary(this, hListener, hConnectionType);
294 hListener->linkToDeath(mObituary, 0);
295 }
Chong Zhang3248ea02020-02-11 17:27:38 -0800296#endif // NO_BINDER
Pawin Vongmasa23399ac2019-04-25 03:44:52 -0700297 _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR, hOutput);
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800298 return {};
299}
300
301Return<HStatus> B2HGraphicBufferProducer::disconnect(
302 HConnectionType hConnectionType) {
303 int bConnectionType;
304 if (!h2b(hConnectionType, &bConnectionType)) {
305 return {HStatus::UNKNOWN_ERROR};
306 }
307 HStatus hStatus{};
308 bool converted = b2h(mBase->disconnect(bConnectionType), &hStatus);
Chong Zhang3248ea02020-02-11 17:27:38 -0800309#ifdef NO_BINDER
Chong Zhang62493092020-01-15 16:04:47 -0800310 if (mObituary != nullptr) {
311 mObituary->listener->unlinkToDeath(mObituary);
312 mObituary.clear();
313 }
Chong Zhang3248ea02020-02-11 17:27:38 -0800314#endif // NO_BINDER
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800315 return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
316}
317
318Return<HStatus> B2HGraphicBufferProducer::allocateBuffers(
319 uint32_t width, uint32_t height,
320 uint32_t format, uint64_t usage) {
321 mBase->allocateBuffers(
322 width, height, static_cast<PixelFormat>(format), usage);
323 return {HStatus::OK};
324}
325
326Return<HStatus> B2HGraphicBufferProducer::allowAllocation(bool allow) {
327 HStatus hStatus{};
328 bool converted = b2h(mBase->allowAllocation(allow), &hStatus);
329 return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
330}
331
332Return<HStatus> B2HGraphicBufferProducer::setGenerationNumber(
333 uint32_t generationNumber) {
334 HStatus hStatus{};
335 bool converted = b2h(
336 mBase->setGenerationNumber(generationNumber),
337 &hStatus);
338 return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
339}
340
341Return<HStatus> B2HGraphicBufferProducer::setDequeueTimeout(
342 int64_t timeoutNs) {
343 HStatus hStatus{};
344 bool converted = b2h(
345 mBase->setDequeueTimeout(static_cast<nsecs_t>(timeoutNs)),
346 &hStatus);
347 return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
348}
349
350Return<uint64_t> B2HGraphicBufferProducer::getUniqueId() {
351 uint64_t outId{};
352 HStatus hStatus{};
353 bool converted = b2h(mBase->getUniqueId(&outId), &hStatus);
354 return {converted ? outId : 0};
355}
356
357Return<void> B2HGraphicBufferProducer::getConsumerName(
358 getConsumerName_cb _hidl_cb) {
359 _hidl_cb(hidl_string{mBase->getConsumerName().c_str()});
360 return {};
361}
362
363} // namespace utils
364} // namespace V2_0
365} // namespace bufferqueue
366} // namespace graphics
367} // namespace hardware
368} // namespace android
369