blob: 1023ef108abd059564cf264ae0fcdbcc2c9772e3 [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 {
32
33namespace hardware {
34namespace graphics {
35namespace bufferqueue {
36namespace V2_0 {
37namespace utils {
38
39// H2BGraphicBufferProducer
40// ========================
41
42status_t H2BGraphicBufferProducer::requestBuffer(int slot,
43 sp<GraphicBuffer>* bBuffer) {
44 bool converted{};
45 status_t bStatus{};
46 Return<void> transResult = mBase->requestBuffer(slot,
47 [&converted, &bStatus, bBuffer](
48 HStatus hStatus,
49 HardwareBuffer const& hBuffer,
50 uint32_t generationNumber) {
51 converted =
52 h2b(hStatus, &bStatus) &&
53 h2b(hBuffer, bBuffer);
54 if (*bBuffer) {
55 (*bBuffer)->setGenerationNumber(generationNumber);
56 }
57 });
58 if (!transResult.isOk()) {
59 LOG(ERROR) << "requestBuffer: transaction failed.";
60 return FAILED_TRANSACTION;
61 }
62 if (!converted) {
63 LOG(ERROR) << "requestBuffer: corrupted transaction.";
64 return FAILED_TRANSACTION;
65 }
66 return bStatus;
67}
68
69status_t H2BGraphicBufferProducer::setMaxDequeuedBufferCount(
70 int maxDequeuedBuffers) {
71 status_t bStatus{};
72 Return<HStatus> transResult = mBase->setMaxDequeuedBufferCount(
73 static_cast<int32_t>(maxDequeuedBuffers));
74 if (!transResult.isOk()) {
75 LOG(ERROR) << "setMaxDequeuedBufferCount: transaction failed.";
76 return FAILED_TRANSACTION;
77 }
78 if (!h2b(static_cast<HStatus>(transResult), &bStatus)) {
79 LOG(ERROR) << "setMaxDequeuedBufferCount: corrupted transaction.";
80 return FAILED_TRANSACTION;
81 }
82 return bStatus;
83}
84
85status_t H2BGraphicBufferProducer::setAsyncMode(bool async) {
86 status_t bStatus{};
87 Return<HStatus> transResult = mBase->setAsyncMode(async);
88 if (!transResult.isOk()) {
89 LOG(ERROR) << "setAsyncMode: transaction failed.";
90 return FAILED_TRANSACTION;
91 }
92 if (!h2b(static_cast<HStatus>(transResult), &bStatus)) {
93 LOG(ERROR) << "setAsyncMode: corrupted transaction.";
94 return FAILED_TRANSACTION;
95 }
96 return bStatus;
97}
98
99status_t H2BGraphicBufferProducer::dequeueBuffer(
100 int* slot, sp<BFence>* fence,
101 uint32_t w, uint32_t h,
102 PixelFormat format, uint64_t usage,
103 uint64_t* outBufferAge, FrameEventHistoryDelta* /* outTimestamps */) {
104
105 using HInput = HGraphicBufferProducer::DequeueBufferInput;
106 HInput input{w, h, static_cast<uint32_t>(format), usage};
107
108 using HOutput = HGraphicBufferProducer::DequeueBufferOutput;
109 bool converted{};
110 status_t bStatus{};
111 Return<void> transResult = mBase->dequeueBuffer(input,
112 [&converted, &bStatus, slot, fence, outBufferAge] (
113 HStatus hStatus, int32_t hSlot, HOutput const& hOutput) {
114 converted = h2b(hStatus, &bStatus);
115 if (!converted || bStatus != OK) {
116 return;
117 }
118 *slot = hSlot;
119 *outBufferAge = hOutput.bufferAge;
120 bStatus =
121 (hOutput.bufferNeedsReallocation ?
122 BUFFER_NEEDS_REALLOCATION : 0) |
123 (hOutput.releaseAllBuffers ?
124 RELEASE_ALL_BUFFERS : 0);
125 converted = h2b(hOutput.fence, fence);
126 });
127 if (!transResult.isOk()) {
128 LOG(ERROR) << "dequeueBuffer: transaction failed.";
129 return FAILED_TRANSACTION;
130 }
131 if (!converted) {
132 LOG(ERROR) << "dequeueBuffer: corrupted transaction.";
133 return FAILED_TRANSACTION;
134 }
135 return bStatus;
136}
137
138status_t H2BGraphicBufferProducer::detachBuffer(int slot) {
139 status_t bStatus{};
140 Return<HStatus> transResult = mBase->detachBuffer(
141 static_cast<int32_t>(slot));
142 if (!transResult.isOk()) {
143 LOG(ERROR) << "detachBuffer: transaction failed.";
144 return FAILED_TRANSACTION;
145 }
146 if (!h2b(static_cast<HStatus>(transResult), &bStatus)) {
147 LOG(ERROR) << "detachBuffer: corrupted transaction.";
148 return FAILED_TRANSACTION;
149 }
150 return bStatus;
151}
152
153status_t H2BGraphicBufferProducer::detachNextBuffer(
154 sp<GraphicBuffer>* outBuffer, sp<BFence>* outFence) {
155 bool converted{};
156 status_t bStatus{};
157 Return<void> transResult = mBase->detachNextBuffer(
158 [&converted, &bStatus, outBuffer, outFence] (
159 HStatus hStatus,
160 HardwareBuffer const& hBuffer,
161 hidl_handle const& hFence) {
162 converted = h2b(hStatus, &bStatus) &&
163 h2b(hBuffer, outBuffer) &&
164 h2b(hFence, outFence);
165 });
166 if (!transResult.isOk()) {
167 LOG(ERROR) << "detachNextBuffer: transaction failed.";
168 return FAILED_TRANSACTION;
169 }
170 if (!converted) {
171 LOG(ERROR) << "detachNextBuffer: corrupted transaction.";
172 return FAILED_TRANSACTION;
173 }
174 return bStatus;
175}
176
177status_t H2BGraphicBufferProducer::attachBuffer(
178 int* outSlot, sp<GraphicBuffer> const& buffer) {
179 HardwareBuffer hBuffer{};
180 uint32_t hGenerationNumber{};
181 if (!b2h(buffer, &hBuffer, &hGenerationNumber)) {
182 LOG(ERROR) << "attachBuffer: invalid input buffer.";
183 return BAD_VALUE;
184 }
185
186 bool converted{};
187 status_t bStatus{};
188 Return<void> transResult = mBase->attachBuffer(hBuffer, hGenerationNumber,
189 [&converted, &bStatus, outSlot](
190 HStatus hStatus, int32_t hSlot, bool releaseAllBuffers) {
191 converted = h2b(hStatus, &bStatus);
192 *outSlot = static_cast<int>(hSlot);
193 if (converted && releaseAllBuffers && bStatus == OK) {
194 bStatus = IGraphicBufferProducer::RELEASE_ALL_BUFFERS;
195 }
196 });
197 if (!transResult.isOk()) {
198 LOG(ERROR) << "attachBuffer: transaction failed.";
199 return FAILED_TRANSACTION;
200 }
201 if (!converted) {
202 LOG(ERROR) << "attachBuffer: corrupted transaction.";
203 return FAILED_TRANSACTION;
204 }
205 return bStatus;
206}
207
208status_t H2BGraphicBufferProducer::queueBuffer(
209 int slot,
210 QueueBufferInput const& input,
211 QueueBufferOutput* output) {
212 HRect hCrop{};
213 (void)b2h(input.crop, &hCrop);
214
215 using HInput = HGraphicBufferProducer::QueueBufferInput;
216 HInput hInput{
217 input.timestamp,
218 static_cast<bool>(input.isAutoTimestamp),
219 static_cast<int32_t>(input.dataSpace),
220 {}, // crop
221 static_cast<int32_t>(input.transform),
222 static_cast<int32_t>(input.stickyTransform),
223 {}, // fence
224 {} // surfaceDamage
225 };
226
227 // Convert crop.
228 if (!b2h(input.crop, &hInput.crop)) {
229 LOG(ERROR) << "queueBuffer: corrupted input crop rectangle.";
230 return UNKNOWN_ERROR;
231 }
232
233 // Convert surfaceDamage.
234 size_t numRects;
235 Rect const* rectArray = input.surfaceDamage.getArray(&numRects);
236 hInput.surfaceDamage.resize(numRects);
237 for (size_t i = 0; i < numRects; ++i) {
238 if (!b2h(rectArray[i], &hInput.surfaceDamage[i])) {
239 LOG(ERROR) << "queueBuffer: corrupted input surface damage.";
240 return UNKNOWN_ERROR;
241 }
242 }
243
244 // Convert fence.
245 HFenceWrapper hFenceWrapper;
246 if (!b2h(input.fence, &hFenceWrapper)) {
247 LOG(ERROR) << "queueBuffer: corrupted input fence.";
248 return UNKNOWN_ERROR;
249 }
250 hInput.fence = hFenceWrapper.getHandle();
251
252 using HOutput = HGraphicBufferProducer::QueueBufferOutput;
253 bool converted{};
254 status_t bStatus{};
255 Return<void> transResult = mBase->queueBuffer(
256 static_cast<int32_t>(slot),
257 hInput,
258 [&converted, &bStatus, output](
259 HStatus hStatus,
260 HOutput const& hOutput) {
261 converted = h2b(hStatus, &bStatus);
262 output->width = hOutput.width;
263 output->height = hOutput.height;
264 output->transformHint =
265 static_cast<uint32_t>(hOutput.transformHint);
266 output->numPendingBuffers = hOutput.numPendingBuffers;
267 output->nextFrameNumber = hOutput.nextFrameNumber;
268 output->bufferReplaced = hOutput.bufferReplaced;
269 });
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
335 using HOutput = HGraphicBufferProducer::QueueBufferOutput;
336 bool converted{};
337 status_t bStatus{};
338 Return<void> transResult = mBase->connect(
339 hListener,
340 hConnectionType,
341 producerControlledByApp,
342 [&converted, &bStatus, output](
343 HStatus hStatus,
344 HOutput hOutput) {
345 converted = h2b(hStatus, &bStatus);
346 output->width = hOutput.width;
347 output->height = hOutput.height;
348 output->transformHint =
349 static_cast<uint32_t>(hOutput.transformHint);
350 output->numPendingBuffers = hOutput.numPendingBuffers;
351 output->nextFrameNumber = hOutput.nextFrameNumber;
352 output->bufferReplaced = hOutput.bufferReplaced;
353 });
354 if (!transResult.isOk()) {
355 LOG(ERROR) << "connect: transaction failed.";
356 return FAILED_TRANSACTION;
357 }
358 if (!converted) {
359 LOG(ERROR) << "connect: corrupted transaction.";
360 return FAILED_TRANSACTION;
361 }
362 return bStatus;
363
364}
365
366status_t H2BGraphicBufferProducer::disconnect(int api, DisconnectMode mode) {
367 HConnectionType hConnectionType;
368 if (mode == DisconnectMode::AllLocal) {
369 hConnectionType = HConnectionType::CURRENTLY_CONNECTED;
370 } else if (!b2h(api, &hConnectionType)) {
371 LOG(ERROR) << "connect: corrupted input connection type.";
372 return UNKNOWN_ERROR;
373 }
374
375 status_t bStatus{};
376 Return<HStatus> transResult = mBase->disconnect(hConnectionType);
377 if (!transResult.isOk()) {
378 LOG(ERROR) << "disconnect: transaction failed.";
379 return FAILED_TRANSACTION;
380 }
381 if (!h2b(static_cast<HStatus>(transResult), &bStatus)) {
382 LOG(ERROR) << "disconnect: corrupted transaction.";
383 return FAILED_TRANSACTION;
384 }
385 return bStatus;
386}
387
388status_t H2BGraphicBufferProducer::setSidebandStream(
389 sp<NativeHandle> const& stream) {
390 if (stream) {
391 LOG(INFO) << "setSidebandStream: not supported.";
392 return INVALID_OPERATION;
393 }
394 return OK;
395}
396
397void H2BGraphicBufferProducer::allocateBuffers(
398 uint32_t width, uint32_t height,
399 PixelFormat format, uint64_t usage) {
400 status_t bStatus{};
401 Return<HStatus> transResult = mBase->allocateBuffers(
402 width, height, static_cast<uint32_t>(format), usage);
403 if (!transResult.isOk()) {
404 LOG(ERROR) << "allocateBuffer: transaction failed.";
405 return;
406 }
407 if (!h2b(static_cast<HStatus>(transResult), &bStatus)) {
408 LOG(ERROR) << "allocateBuffer: corrupted transaction.";
409 return;
410 }
411}
412
413status_t H2BGraphicBufferProducer::allowAllocation(bool allow) {
414 status_t bStatus{};
415 Return<HStatus> transResult = mBase->allowAllocation(allow);
416 if (!transResult.isOk()) {
417 LOG(ERROR) << "allowAllocation: transaction failed.";
418 return FAILED_TRANSACTION;
419 }
420 if (!h2b(static_cast<HStatus>(transResult), &bStatus)) {
421 LOG(ERROR) << "allowAllocation: corrupted transaction.";
422 return FAILED_TRANSACTION;
423 }
424 return bStatus;
425}
426
427status_t H2BGraphicBufferProducer::setGenerationNumber(
428 uint32_t generationNumber) {
429 status_t bStatus{};
430 Return<HStatus> transResult = mBase->setGenerationNumber(generationNumber);
431 if (!transResult.isOk()) {
432 LOG(ERROR) << "setGenerationNumber: transaction failed.";
433 return FAILED_TRANSACTION;
434 }
435 if (!h2b(static_cast<HStatus>(transResult), &bStatus)) {
436 LOG(ERROR) << "setGenerationNumber: corrupted transaction.";
437 return FAILED_TRANSACTION;
438 }
439 return bStatus;
440}
441
442String8 H2BGraphicBufferProducer::getConsumerName() const {
443 String8 bName;
444 Return<void> transResult = mBase->getConsumerName(
445 [&bName](hidl_string const& name) {
446 bName = name.c_str();
447 });
448 return bName;
449}
450
451status_t H2BGraphicBufferProducer::setSharedBufferMode(bool sharedBufferMode) {
452 if (sharedBufferMode) {
453 LOG(INFO) << "setSharedBufferMode: not supported.";
454 return INVALID_OPERATION;
455 }
456 return OK;
457}
458
459status_t H2BGraphicBufferProducer::setAutoRefresh(bool autoRefresh) {
460 if (autoRefresh) {
461 LOG(INFO) << "setAutoRefresh: not supported.";
462 return INVALID_OPERATION;
463 }
464 return OK;
465}
466
467status_t H2BGraphicBufferProducer::setDequeueTimeout(nsecs_t timeout) {
468 status_t bStatus{};
469 Return<HStatus> transResult = mBase->setDequeueTimeout(
470 static_cast<int64_t>(timeout));
471 if (!transResult.isOk()) {
472 LOG(ERROR) << "setDequeueTimeout: transaction failed.";
473 return FAILED_TRANSACTION;
474 }
475 if (!h2b(static_cast<HStatus>(transResult), &bStatus)) {
476 LOG(ERROR) << "setDequeueTimeout: corrupted transaction.";
477 return FAILED_TRANSACTION;
478 }
479 return bStatus;
480}
481
482status_t H2BGraphicBufferProducer::getLastQueuedBuffer(
483 sp<GraphicBuffer>*,
484 sp<BFence>*,
485 float[16]) {
486 LOG(INFO) << "getLastQueuedBuffer: not supported.";
487 return INVALID_OPERATION;
488}
489
490void H2BGraphicBufferProducer::getFrameTimestamps(FrameEventHistoryDelta*) {
491 LOG(INFO) << "getFrameTimestamps: not supported.";
492}
493
494status_t H2BGraphicBufferProducer::getUniqueId(uint64_t* outId) const {
495 Return<uint64_t> transResult = mBase->getUniqueId();
496 if (!transResult.isOk()) {
497 LOG(ERROR) << "getUniqueId: transaction failed.";
498 return FAILED_TRANSACTION;
499 }
500 *outId = static_cast<uint64_t>(transResult);
501 return OK;
502}
503
504status_t H2BGraphicBufferProducer::getConsumerUsage(uint64_t*) const {
505 LOG(INFO) << "getConsumerUsage: not supported.";
506 return INVALID_OPERATION;
507}
508
509} // namespace utils
510} // namespace V2_0
511} // namespace bufferqueue
512} // namespace graphics
513} // namespace hardware
514} // namespace android