• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
31 namespace android {
32 namespace hardware {
33 namespace graphics {
34 namespace bufferqueue {
35 namespace V2_0 {
36 namespace utils {
37 
38 namespace /* unnamed */ {
39 
40 using BQueueBufferInput = ::android::
41         IGraphicBufferProducer::QueueBufferInput;
42 using HQueueBufferInput = ::android::hardware::graphics::bufferqueue::V2_0::
43         IGraphicBufferProducer::QueueBufferInput;
44 using BQueueBufferOutput = ::android::
45         IGraphicBufferProducer::QueueBufferOutput;
46 using HQueueBufferOutput = ::android::hardware::graphics::bufferqueue::V2_0::
47         IGraphicBufferProducer::QueueBufferOutput;
48 
49 using ::android::hardware::graphics::bufferqueue::V2_0::utils::b2h;
50 using ::android::hardware::graphics::bufferqueue::V2_0::utils::h2b;
51 
b2h(BQueueBufferInput const & from,HQueueBufferInput * to,HFenceWrapper * hFenceWrapper)52 bool 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 
h2b(HQueueBufferOutput const & from,BQueueBufferOutput * to)68 bool 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 
80 // H2BGraphicBufferProducer
81 // ========================
82 
requestBuffer(int slot,sp<GraphicBuffer> * bBuffer)83 status_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 
setMaxDequeuedBufferCount(int maxDequeuedBuffers)110 status_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 
setAsyncMode(bool async)126 status_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 
dequeueBuffer(int * slot,sp<BFence> * fence,uint32_t w,uint32_t h,PixelFormat format,uint64_t usage,uint64_t * outBufferAge,FrameEventHistoryDelta *)140 status_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 
detachBuffer(int slot)179 status_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 
detachNextBuffer(sp<GraphicBuffer> * outBuffer,sp<BFence> * outFence)194 status_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 
attachBuffer(int * outSlot,sp<GraphicBuffer> const & buffer)218 status_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 
queueBuffer(int slot,QueueBufferInput const & input,QueueBufferOutput * output)249 status_t H2BGraphicBufferProducer::queueBuffer(
250         int slot,
251         QueueBufferInput const& input,
252         QueueBufferOutput* output) {
253     HQueueBufferInput hInput{};
254     HFenceWrapper hFenceWrapper;
255     if (!b2h(input, &hInput, &hFenceWrapper)) {
256         LOG(ERROR) << "queueBuffer: corrupted input.";
257         return UNKNOWN_ERROR;
258     }
259 
260     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,
267                     HQueueBufferOutput const& hOutput) {
268                 converted = h2b(hStatus, &bStatus) && h2b(hOutput, output);
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 
cancelBuffer(int slot,sp<BFence> const & fence)282 status_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 
query(int what,int * value)303 int 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 
connect(sp<IProducerListener> const & listener,int api,bool producerControlledByApp,QueueBufferOutput * output)318 status_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     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,
343                     HQueueBufferOutput const& hOutput) {
344                 converted = h2b(hStatus, &bStatus) && h2b(hOutput, output);
345             });
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 
disconnect(int api,DisconnectMode mode)358 status_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 
setSidebandStream(sp<NativeHandle> const & stream)380 status_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 
allocateBuffers(uint32_t width,uint32_t height,PixelFormat format,uint64_t usage)389 void 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 
allowAllocation(bool allow)405 status_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 
setGenerationNumber(uint32_t generationNumber)419 status_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 
getConsumerName() const434 String8 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 
setSharedBufferMode(bool sharedBufferMode)443 status_t H2BGraphicBufferProducer::setSharedBufferMode(bool sharedBufferMode) {
444     if (sharedBufferMode) {
445         LOG(INFO) << "setSharedBufferMode: not supported.";
446         return INVALID_OPERATION;
447     }
448     return OK;
449 }
450 
setAutoRefresh(bool autoRefresh)451 status_t H2BGraphicBufferProducer::setAutoRefresh(bool autoRefresh) {
452     if (autoRefresh) {
453         LOG(INFO) << "setAutoRefresh: not supported.";
454         return INVALID_OPERATION;
455     }
456     return OK;
457 }
458 
setDequeueTimeout(nsecs_t timeout)459 status_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 
getLastQueuedBuffer(sp<GraphicBuffer> *,sp<BFence> *,float[16])474 status_t H2BGraphicBufferProducer::getLastQueuedBuffer(
475         sp<GraphicBuffer>*,
476         sp<BFence>*,
477         float[16]) {
478     LOG(INFO) << "getLastQueuedBuffer: not supported.";
479     return INVALID_OPERATION;
480 }
481 
getFrameTimestamps(FrameEventHistoryDelta *)482 void H2BGraphicBufferProducer::getFrameTimestamps(FrameEventHistoryDelta*) {
483     LOG(INFO) << "getFrameTimestamps: not supported.";
484 }
485 
getUniqueId(uint64_t * outId) const486 status_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 
getConsumerUsage(uint64_t *) const496 status_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
507