Home | History | Annotate | Download | only in 2.0
      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 (at) 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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    434 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 
    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 
    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 
    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 
    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 
    482 void H2BGraphicBufferProducer::getFrameTimestamps(FrameEventHistoryDelta*) {
    483     LOG(INFO) << "getFrameTimestamps: not supported.";
    484 }
    485 
    486 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 
    496 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