blob: 2f5b73ccbb13c912549c90646c675abf4d51707d [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
18#define LOG_TAG "H2BGraphicBufferProducer@2.0"
19
20#include <android-base/logging.h>
21
22#include <android/hardware/graphics/common/1.2/types.h>
23#include <gui/bufferqueue/2.0/B2HProducerListener.h>
24#include <gui/bufferqueue/2.0/H2BGraphicBufferProducer.h>
25#include <gui/bufferqueue/2.0/types.h>
26#include <ui/GraphicBuffer.h>
27#include <ui/Rect.h>
28#include <ui/Region.h>
29#include <vndk/hardware_buffer.h>
30
31namespace android {
Pawin Vongmasae672cd02019-02-14 16:01:29 -080032namespace hardware {
33namespace graphics {
34namespace bufferqueue {
35namespace V2_0 {
36namespace utils {
37
Pawin Vongmasa23399ac2019-04-25 03:44:52 -070038namespace /* unnamed */ {
39
40using BQueueBufferInput = ::android::
41 IGraphicBufferProducer::QueueBufferInput;
42using HQueueBufferInput = ::android::hardware::graphics::bufferqueue::V2_0::
43 IGraphicBufferProducer::QueueBufferInput;
44using BQueueBufferOutput = ::android::
45 IGraphicBufferProducer::QueueBufferOutput;
46using HQueueBufferOutput = ::android::hardware::graphics::bufferqueue::V2_0::
47 IGraphicBufferProducer::QueueBufferOutput;
48
49using ::android::hardware::graphics::bufferqueue::V2_0::utils::b2h;
50using ::android::hardware::graphics::bufferqueue::V2_0::utils::h2b;
51
52bool b2h(BQueueBufferInput const& from, HQueueBufferInput* to,
53 HFenceWrapper* hFenceWrapper) {
54 to->timestamp = from.timestamp;
55 to->isAutoTimestamp = static_cast<bool>(from.isAutoTimestamp);
56 to->dataSpace = static_cast<int32_t>(from.dataSpace);
57 to->transform = static_cast<int32_t>(from.transform);
58 to->stickyTransform = static_cast<int32_t>(from.stickyTransform);
59 if (!b2h(from.crop, &to->crop) ||
60 !b2h(from.surfaceDamage, &to->surfaceDamage) ||
61 !b2h(from.fence, hFenceWrapper)) {
62 return false;
63 }
64 to->fence = hFenceWrapper->getHandle();
65 return true;
66}
67
68bool h2b(HQueueBufferOutput const& from, BQueueBufferOutput* to) {
69 to->width = from.width;
70 to->height = from.height;
71 to->transformHint = static_cast<uint32_t>(from.transformHint);
72 to->numPendingBuffers = from.numPendingBuffers;
73 to->nextFrameNumber = from.nextFrameNumber;
74 to->bufferReplaced = from.bufferReplaced;
75 return true;
76}
77
78} // unnamed namespace
79
Pawin Vongmasae672cd02019-02-14 16:01:29 -080080// H2BGraphicBufferProducer
81// ========================
82
83status_t H2BGraphicBufferProducer::requestBuffer(int slot,
84 sp<GraphicBuffer>* bBuffer) {
85 bool converted{};
86 status_t bStatus{};
87 Return<void> transResult = mBase->requestBuffer(slot,
88 [&converted, &bStatus, bBuffer](
89 HStatus hStatus,
90 HardwareBuffer const& hBuffer,
91 uint32_t generationNumber) {
92 converted =
93 h2b(hStatus, &bStatus) &&
94 h2b(hBuffer, bBuffer);
95 if (*bBuffer) {
96 (*bBuffer)->setGenerationNumber(generationNumber);
97 }
98 });
99 if (!transResult.isOk()) {
100 LOG(ERROR) << "requestBuffer: transaction failed.";
101 return FAILED_TRANSACTION;
102 }
103 if (!converted) {
104 LOG(ERROR) << "requestBuffer: corrupted transaction.";
105 return FAILED_TRANSACTION;
106 }
107 return bStatus;
108}
109
110status_t H2BGraphicBufferProducer::setMaxDequeuedBufferCount(
111 int maxDequeuedBuffers) {
112 status_t bStatus{};
113 Return<HStatus> transResult = mBase->setMaxDequeuedBufferCount(
114 static_cast<int32_t>(maxDequeuedBuffers));
115 if (!transResult.isOk()) {
116 LOG(ERROR) << "setMaxDequeuedBufferCount: transaction failed.";
117 return FAILED_TRANSACTION;
118 }
119 if (!h2b(static_cast<HStatus>(transResult), &bStatus)) {
120 LOG(ERROR) << "setMaxDequeuedBufferCount: corrupted transaction.";
121 return FAILED_TRANSACTION;
122 }
123 return bStatus;
124}
125
126status_t H2BGraphicBufferProducer::setAsyncMode(bool async) {
127 status_t bStatus{};
128 Return<HStatus> transResult = mBase->setAsyncMode(async);
129 if (!transResult.isOk()) {
130 LOG(ERROR) << "setAsyncMode: transaction failed.";
131 return FAILED_TRANSACTION;
132 }
133 if (!h2b(static_cast<HStatus>(transResult), &bStatus)) {
134 LOG(ERROR) << "setAsyncMode: corrupted transaction.";
135 return FAILED_TRANSACTION;
136 }
137 return bStatus;
138}
139
140status_t H2BGraphicBufferProducer::dequeueBuffer(
141 int* slot, sp<BFence>* fence,
142 uint32_t w, uint32_t h,
143 PixelFormat format, uint64_t usage,
144 uint64_t* outBufferAge, FrameEventHistoryDelta* /* outTimestamps */) {
145
146 using HInput = HGraphicBufferProducer::DequeueBufferInput;
147 HInput input{w, h, static_cast<uint32_t>(format), usage};
148
149 using HOutput = HGraphicBufferProducer::DequeueBufferOutput;
150 bool converted{};
151 status_t bStatus{};
152 Return<void> transResult = mBase->dequeueBuffer(input,
153 [&converted, &bStatus, slot, fence, outBufferAge] (
154 HStatus hStatus, int32_t hSlot, HOutput const& hOutput) {
155 converted = h2b(hStatus, &bStatus);
156 if (!converted || bStatus != OK) {
157 return;
158 }
159 *slot = hSlot;
160 *outBufferAge = hOutput.bufferAge;
161 bStatus =
162 (hOutput.bufferNeedsReallocation ?
163 BUFFER_NEEDS_REALLOCATION : 0) |
164 (hOutput.releaseAllBuffers ?
165 RELEASE_ALL_BUFFERS : 0);
166 converted = h2b(hOutput.fence, fence);
167 });
168 if (!transResult.isOk()) {
169 LOG(ERROR) << "dequeueBuffer: transaction failed.";
170 return FAILED_TRANSACTION;
171 }
172 if (!converted) {
173 LOG(ERROR) << "dequeueBuffer: corrupted transaction.";
174 return FAILED_TRANSACTION;
175 }
176 return bStatus;
177}
178
179status_t H2BGraphicBufferProducer::detachBuffer(int slot) {
180 status_t bStatus{};
181 Return<HStatus> transResult = mBase->detachBuffer(
182 static_cast<int32_t>(slot));
183 if (!transResult.isOk()) {
184 LOG(ERROR) << "detachBuffer: transaction failed.";
185 return FAILED_TRANSACTION;
186 }
187 if (!h2b(static_cast<HStatus>(transResult), &bStatus)) {
188 LOG(ERROR) << "detachBuffer: corrupted transaction.";
189 return FAILED_TRANSACTION;
190 }
191 return bStatus;
192}
193
194status_t H2BGraphicBufferProducer::detachNextBuffer(
195 sp<GraphicBuffer>* outBuffer, sp<BFence>* outFence) {
196 bool converted{};
197 status_t bStatus{};
198 Return<void> transResult = mBase->detachNextBuffer(
199 [&converted, &bStatus, outBuffer, outFence] (
200 HStatus hStatus,
201 HardwareBuffer const& hBuffer,
202 hidl_handle const& hFence) {
203 converted = h2b(hStatus, &bStatus) &&
204 h2b(hBuffer, outBuffer) &&
205 h2b(hFence, outFence);
206 });
207 if (!transResult.isOk()) {
208 LOG(ERROR) << "detachNextBuffer: transaction failed.";
209 return FAILED_TRANSACTION;
210 }
211 if (!converted) {
212 LOG(ERROR) << "detachNextBuffer: corrupted transaction.";
213 return FAILED_TRANSACTION;
214 }
215 return bStatus;
216}
217
218status_t H2BGraphicBufferProducer::attachBuffer(
219 int* outSlot, sp<GraphicBuffer> const& buffer) {
220 HardwareBuffer hBuffer{};
221 uint32_t hGenerationNumber{};
222 if (!b2h(buffer, &hBuffer, &hGenerationNumber)) {
223 LOG(ERROR) << "attachBuffer: invalid input buffer.";
224 return BAD_VALUE;
225 }
226
227 bool converted{};
228 status_t bStatus{};
229 Return<void> transResult = mBase->attachBuffer(hBuffer, hGenerationNumber,
230 [&converted, &bStatus, outSlot](
231 HStatus hStatus, int32_t hSlot, bool releaseAllBuffers) {
232 converted = h2b(hStatus, &bStatus);
233 *outSlot = static_cast<int>(hSlot);
234 if (converted && releaseAllBuffers && bStatus == OK) {
235 bStatus = IGraphicBufferProducer::RELEASE_ALL_BUFFERS;
236 }
237 });
238 if (!transResult.isOk()) {
239 LOG(ERROR) << "attachBuffer: transaction failed.";
240 return FAILED_TRANSACTION;
241 }
242 if (!converted) {
243 LOG(ERROR) << "attachBuffer: corrupted transaction.";
244 return FAILED_TRANSACTION;
245 }
246 return bStatus;
247}
248
249status_t H2BGraphicBufferProducer::queueBuffer(
250 int slot,
251 QueueBufferInput const& input,
252 QueueBufferOutput* output) {
Pawin Vongmasa23399ac2019-04-25 03:44:52 -0700253 HQueueBufferInput hInput{};
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800254 HFenceWrapper hFenceWrapper;
Pawin Vongmasa23399ac2019-04-25 03:44:52 -0700255 if (!b2h(input, &hInput, &hFenceWrapper)) {
256 LOG(ERROR) << "queueBuffer: corrupted input.";
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800257 return UNKNOWN_ERROR;
258 }
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800259
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800260 bool converted{};
261 status_t bStatus{};
262 Return<void> transResult = mBase->queueBuffer(
263 static_cast<int32_t>(slot),
264 hInput,
265 [&converted, &bStatus, output](
266 HStatus hStatus,
Pawin Vongmasa23399ac2019-04-25 03:44:52 -0700267 HQueueBufferOutput const& hOutput) {
268 converted = h2b(hStatus, &bStatus) && h2b(hOutput, output);
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800269 });
270
271 if (!transResult.isOk()) {
272 LOG(ERROR) << "queueBuffer: transaction failed.";
273 return FAILED_TRANSACTION;
274 }
275 if (!converted) {
276 LOG(ERROR) << "queueBuffer: corrupted transaction.";
277 return FAILED_TRANSACTION;
278 }
279 return bStatus;
280}
281
282status_t H2BGraphicBufferProducer::cancelBuffer(int slot, sp<BFence> const& fence) {
283 HFenceWrapper hFenceWrapper;
284 if (!b2h(fence, &hFenceWrapper)) {
285 LOG(ERROR) << "cancelBuffer: corrupted input fence.";
286 return UNKNOWN_ERROR;
287 }
288 status_t bStatus{};
289 Return<HStatus> transResult = mBase->cancelBuffer(
290 static_cast<int32_t>(slot),
291 hFenceWrapper.getHandle());
292 if (!transResult.isOk()) {
293 LOG(ERROR) << "cancelBuffer: transaction failed.";
294 return FAILED_TRANSACTION;
295 }
296 if (!h2b(static_cast<HStatus>(transResult), &bStatus)) {
297 LOG(ERROR) << "cancelBuffer: corrupted transaction.";
298 return FAILED_TRANSACTION;
299 }
300 return bStatus;
301}
302
303int H2BGraphicBufferProducer::query(int what, int* value) {
304 int result{};
305 Return<void> transResult = mBase->query(
306 static_cast<int32_t>(what),
307 [&result, value](int32_t r, int32_t v) {
308 result = static_cast<int>(r);
309 *value = static_cast<int>(v);
310 });
311 if (!transResult.isOk()) {
312 LOG(ERROR) << "query: transaction failed.";
313 return FAILED_TRANSACTION;
314 }
315 return result;
316}
317
318status_t H2BGraphicBufferProducer::connect(
319 sp<IProducerListener> const& listener, int api,
320 bool producerControlledByApp, QueueBufferOutput* output) {
321 HConnectionType hConnectionType;
322 if (!b2h(api, &hConnectionType)) {
323 LOG(ERROR) << "connect: corrupted input connection type.";
324 return UNKNOWN_ERROR;
325 }
326 sp<HProducerListener> hListener = nullptr;
327 if (listener && listener->needsReleaseNotify()) {
328 hListener = new B2HProducerListener(listener);
329 if (!hListener) {
330 LOG(ERROR) << "connect: failed to wrap listener.";
331 return UNKNOWN_ERROR;
332 }
333 }
334
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800335 bool converted{};
336 status_t bStatus{};
337 Return<void> transResult = mBase->connect(
338 hListener,
339 hConnectionType,
340 producerControlledByApp,
341 [&converted, &bStatus, output](
342 HStatus hStatus,
Pawin Vongmasa23399ac2019-04-25 03:44:52 -0700343 HQueueBufferOutput const& hOutput) {
344 converted = h2b(hStatus, &bStatus) && h2b(hOutput, output);
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800345 });
346 if (!transResult.isOk()) {
347 LOG(ERROR) << "connect: transaction failed.";
348 return FAILED_TRANSACTION;
349 }
350 if (!converted) {
351 LOG(ERROR) << "connect: corrupted transaction.";
352 return FAILED_TRANSACTION;
353 }
354 return bStatus;
355
356}
357
358status_t H2BGraphicBufferProducer::disconnect(int api, DisconnectMode mode) {
359 HConnectionType hConnectionType;
360 if (mode == DisconnectMode::AllLocal) {
361 hConnectionType = HConnectionType::CURRENTLY_CONNECTED;
362 } else if (!b2h(api, &hConnectionType)) {
363 LOG(ERROR) << "connect: corrupted input connection type.";
364 return UNKNOWN_ERROR;
365 }
366
367 status_t bStatus{};
368 Return<HStatus> transResult = mBase->disconnect(hConnectionType);
369 if (!transResult.isOk()) {
370 LOG(ERROR) << "disconnect: transaction failed.";
371 return FAILED_TRANSACTION;
372 }
373 if (!h2b(static_cast<HStatus>(transResult), &bStatus)) {
374 LOG(ERROR) << "disconnect: corrupted transaction.";
375 return FAILED_TRANSACTION;
376 }
377 return bStatus;
378}
379
380status_t H2BGraphicBufferProducer::setSidebandStream(
381 sp<NativeHandle> const& stream) {
382 if (stream) {
383 LOG(INFO) << "setSidebandStream: not supported.";
384 return INVALID_OPERATION;
385 }
386 return OK;
387}
388
389void H2BGraphicBufferProducer::allocateBuffers(
390 uint32_t width, uint32_t height,
391 PixelFormat format, uint64_t usage) {
392 status_t bStatus{};
393 Return<HStatus> transResult = mBase->allocateBuffers(
394 width, height, static_cast<uint32_t>(format), usage);
395 if (!transResult.isOk()) {
396 LOG(ERROR) << "allocateBuffer: transaction failed.";
397 return;
398 }
399 if (!h2b(static_cast<HStatus>(transResult), &bStatus)) {
400 LOG(ERROR) << "allocateBuffer: corrupted transaction.";
401 return;
402 }
403}
404
405status_t H2BGraphicBufferProducer::allowAllocation(bool allow) {
406 status_t bStatus{};
407 Return<HStatus> transResult = mBase->allowAllocation(allow);
408 if (!transResult.isOk()) {
409 LOG(ERROR) << "allowAllocation: transaction failed.";
410 return FAILED_TRANSACTION;
411 }
412 if (!h2b(static_cast<HStatus>(transResult), &bStatus)) {
413 LOG(ERROR) << "allowAllocation: corrupted transaction.";
414 return FAILED_TRANSACTION;
415 }
416 return bStatus;
417}
418
419status_t H2BGraphicBufferProducer::setGenerationNumber(
420 uint32_t generationNumber) {
421 status_t bStatus{};
422 Return<HStatus> transResult = mBase->setGenerationNumber(generationNumber);
423 if (!transResult.isOk()) {
424 LOG(ERROR) << "setGenerationNumber: transaction failed.";
425 return FAILED_TRANSACTION;
426 }
427 if (!h2b(static_cast<HStatus>(transResult), &bStatus)) {
428 LOG(ERROR) << "setGenerationNumber: corrupted transaction.";
429 return FAILED_TRANSACTION;
430 }
431 return bStatus;
432}
433
434String8 H2BGraphicBufferProducer::getConsumerName() const {
435 String8 bName;
436 Return<void> transResult = mBase->getConsumerName(
437 [&bName](hidl_string const& name) {
438 bName = name.c_str();
439 });
440 return bName;
441}
442
443status_t H2BGraphicBufferProducer::setSharedBufferMode(bool sharedBufferMode) {
444 if (sharedBufferMode) {
445 LOG(INFO) << "setSharedBufferMode: not supported.";
446 return INVALID_OPERATION;
447 }
448 return OK;
449}
450
451status_t H2BGraphicBufferProducer::setAutoRefresh(bool autoRefresh) {
452 if (autoRefresh) {
453 LOG(INFO) << "setAutoRefresh: not supported.";
454 return INVALID_OPERATION;
455 }
456 return OK;
457}
458
459status_t H2BGraphicBufferProducer::setDequeueTimeout(nsecs_t timeout) {
460 status_t bStatus{};
461 Return<HStatus> transResult = mBase->setDequeueTimeout(
462 static_cast<int64_t>(timeout));
463 if (!transResult.isOk()) {
464 LOG(ERROR) << "setDequeueTimeout: transaction failed.";
465 return FAILED_TRANSACTION;
466 }
467 if (!h2b(static_cast<HStatus>(transResult), &bStatus)) {
468 LOG(ERROR) << "setDequeueTimeout: corrupted transaction.";
469 return FAILED_TRANSACTION;
470 }
471 return bStatus;
472}
473
474status_t H2BGraphicBufferProducer::getLastQueuedBuffer(
475 sp<GraphicBuffer>*,
476 sp<BFence>*,
477 float[16]) {
478 LOG(INFO) << "getLastQueuedBuffer: not supported.";
479 return INVALID_OPERATION;
480}
481
482void H2BGraphicBufferProducer::getFrameTimestamps(FrameEventHistoryDelta*) {
483 LOG(INFO) << "getFrameTimestamps: not supported.";
484}
485
486status_t H2BGraphicBufferProducer::getUniqueId(uint64_t* outId) const {
487 Return<uint64_t> transResult = mBase->getUniqueId();
488 if (!transResult.isOk()) {
489 LOG(ERROR) << "getUniqueId: transaction failed.";
490 return FAILED_TRANSACTION;
491 }
492 *outId = static_cast<uint64_t>(transResult);
493 return OK;
494}
495
496status_t H2BGraphicBufferProducer::getConsumerUsage(uint64_t*) const {
497 LOG(INFO) << "getConsumerUsage: not supported.";
498 return INVALID_OPERATION;
499}
500
501} // namespace utils
502} // namespace V2_0
503} // namespace bufferqueue
504} // namespace graphics
505} // namespace hardware
506} // namespace android