Home | History | Annotate | Download | only in ui
      1 /*
      2  * Copyright 2016 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_TAG "Gralloc2"
     18 
     19 #include <hidl/ServiceManagement.h>
     20 #include <hwbinder/IPCThreadState.h>
     21 #include <ui/Gralloc2.h>
     22 
     23 #include <inttypes.h>
     24 #include <log/log.h>
     25 #pragma clang diagnostic push
     26 #pragma clang diagnostic ignored "-Wzero-length-array"
     27 #include <sync/sync.h>
     28 #pragma clang diagnostic pop
     29 
     30 using android::hardware::graphics::allocator::V2_0::IAllocator;
     31 using android::hardware::graphics::common::V1_1::BufferUsage;
     32 using android::hardware::graphics::common::V1_1::PixelFormat;
     33 using android::hardware::graphics::mapper::V2_0::BufferDescriptor;
     34 using android::hardware::graphics::mapper::V2_0::Error;
     35 using android::hardware::graphics::mapper::V2_0::YCbCrLayout;
     36 using android::hardware::graphics::mapper::V2_1::IMapper;
     37 
     38 namespace android {
     39 
     40 namespace {
     41 
     42 static constexpr Error kTransactionError = Error::NO_RESOURCES;
     43 
     44 uint64_t getValid10UsageBits() {
     45     static const uint64_t valid10UsageBits = []() -> uint64_t {
     46         using hardware::graphics::common::V1_0::BufferUsage;
     47         uint64_t bits = 0;
     48         for (const auto bit : hardware::hidl_enum_range<BufferUsage>()) {
     49             bits = bits | bit;
     50         }
     51         return bits;
     52     }();
     53     return valid10UsageBits;
     54 }
     55 
     56 uint64_t getValid11UsageBits() {
     57     static const uint64_t valid11UsageBits = []() -> uint64_t {
     58         using hardware::graphics::common::V1_1::BufferUsage;
     59         uint64_t bits = 0;
     60         for (const auto bit : hardware::hidl_enum_range<BufferUsage>()) {
     61             bits = bits | bit;
     62         }
     63         return bits;
     64     }();
     65     return valid11UsageBits;
     66 }
     67 
     68 static inline IMapper::Rect sGralloc2Rect(const Rect& rect) {
     69     IMapper::Rect outRect{};
     70     outRect.left = rect.left;
     71     outRect.top = rect.top;
     72     outRect.width = rect.width();
     73     outRect.height = rect.height();
     74     return outRect;
     75 }
     76 
     77 }  // anonymous namespace
     78 
     79 void Gralloc2Mapper::preload() {
     80     android::hardware::preloadPassthroughService<hardware::graphics::mapper::V2_0::IMapper>();
     81 }
     82 
     83 Gralloc2Mapper::Gralloc2Mapper() {
     84     mMapper = hardware::graphics::mapper::V2_0::IMapper::getService();
     85     if (mMapper == nullptr) {
     86         ALOGW("mapper 2.x is not supported");
     87         return;
     88     }
     89     if (mMapper->isRemote()) {
     90         LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode");
     91     }
     92 
     93     // IMapper 2.1 is optional
     94     mMapperV2_1 = IMapper::castFrom(mMapper);
     95 }
     96 
     97 bool Gralloc2Mapper::isLoaded() const {
     98     return mMapper != nullptr;
     99 }
    100 
    101 status_t Gralloc2Mapper::validateBufferDescriptorInfo(
    102         IMapper::BufferDescriptorInfo* descriptorInfo) const {
    103     uint64_t validUsageBits = getValid10UsageBits();
    104     if (mMapperV2_1 != nullptr) {
    105         validUsageBits = validUsageBits | getValid11UsageBits();
    106     }
    107 
    108     if (descriptorInfo->usage & ~validUsageBits) {
    109         ALOGE("buffer descriptor contains invalid usage bits 0x%" PRIx64,
    110               descriptorInfo->usage & ~validUsageBits);
    111         return BAD_VALUE;
    112     }
    113     return NO_ERROR;
    114 }
    115 
    116 status_t Gralloc2Mapper::createDescriptor(void* bufferDescriptorInfo,
    117                                           void* outBufferDescriptor) const {
    118     IMapper::BufferDescriptorInfo* descriptorInfo =
    119             static_cast<IMapper::BufferDescriptorInfo*>(bufferDescriptorInfo);
    120     BufferDescriptor* outDescriptor = static_cast<BufferDescriptor*>(outBufferDescriptor);
    121 
    122     status_t status = validateBufferDescriptorInfo(descriptorInfo);
    123     if (status != NO_ERROR) {
    124         return status;
    125     }
    126 
    127     Error error;
    128     auto hidl_cb = [&](const auto& tmpError, const auto& tmpDescriptor)
    129                    {
    130                        error = tmpError;
    131                        if (error != Error::NONE) {
    132                            return;
    133                        }
    134 
    135                        *outDescriptor = tmpDescriptor;
    136                    };
    137 
    138     hardware::Return<void> ret;
    139     if (mMapperV2_1 != nullptr) {
    140         ret = mMapperV2_1->createDescriptor_2_1(*descriptorInfo, hidl_cb);
    141     } else {
    142         const hardware::graphics::mapper::V2_0::IMapper::BufferDescriptorInfo info = {
    143                 descriptorInfo->width,
    144                 descriptorInfo->height,
    145                 descriptorInfo->layerCount,
    146                 static_cast<hardware::graphics::common::V1_0::PixelFormat>(descriptorInfo->format),
    147                 descriptorInfo->usage,
    148         };
    149         ret = mMapper->createDescriptor(info, hidl_cb);
    150     }
    151 
    152     return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
    153 }
    154 
    155 status_t Gralloc2Mapper::importBuffer(const hardware::hidl_handle& rawHandle,
    156                                       buffer_handle_t* outBufferHandle) const {
    157     Error error;
    158     auto ret = mMapper->importBuffer(rawHandle,
    159             [&](const auto& tmpError, const auto& tmpBuffer)
    160             {
    161                 error = tmpError;
    162                 if (error != Error::NONE) {
    163                     return;
    164                 }
    165 
    166                 *outBufferHandle = static_cast<buffer_handle_t>(tmpBuffer);
    167             });
    168 
    169     return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
    170 }
    171 
    172 void Gralloc2Mapper::freeBuffer(buffer_handle_t bufferHandle) const {
    173     auto buffer = const_cast<native_handle_t*>(bufferHandle);
    174     auto ret = mMapper->freeBuffer(buffer);
    175 
    176     auto error = (ret.isOk()) ? static_cast<Error>(ret) : kTransactionError;
    177     ALOGE_IF(error != Error::NONE, "freeBuffer(%p) failed with %d",
    178             buffer, error);
    179 }
    180 
    181 status_t Gralloc2Mapper::validateBufferSize(buffer_handle_t bufferHandle, uint32_t width,
    182                                             uint32_t height, android::PixelFormat format,
    183                                             uint32_t layerCount, uint64_t usage,
    184                                             uint32_t stride) const {
    185     if (mMapperV2_1 == nullptr) {
    186         return NO_ERROR;
    187     }
    188 
    189     IMapper::BufferDescriptorInfo descriptorInfo = {};
    190     descriptorInfo.width = width;
    191     descriptorInfo.height = height;
    192     descriptorInfo.layerCount = layerCount;
    193     descriptorInfo.format = static_cast<hardware::graphics::common::V1_1::PixelFormat>(format);
    194     descriptorInfo.usage = usage;
    195 
    196     auto buffer = const_cast<native_handle_t*>(bufferHandle);
    197     auto ret = mMapperV2_1->validateBufferSize(buffer, descriptorInfo, stride);
    198 
    199     return static_cast<status_t>((ret.isOk()) ? static_cast<Error>(ret) : kTransactionError);
    200 }
    201 
    202 void Gralloc2Mapper::getTransportSize(buffer_handle_t bufferHandle, uint32_t* outNumFds,
    203                                       uint32_t* outNumInts) const {
    204     *outNumFds = uint32_t(bufferHandle->numFds);
    205     *outNumInts = uint32_t(bufferHandle->numInts);
    206 
    207     if (mMapperV2_1 == nullptr) {
    208         return;
    209     }
    210 
    211     Error error;
    212     auto buffer = const_cast<native_handle_t*>(bufferHandle);
    213     auto ret = mMapperV2_1->getTransportSize(buffer,
    214             [&](const auto& tmpError, const auto& tmpNumFds, const auto& tmpNumInts) {
    215                 error = tmpError;
    216                 if (error != Error::NONE) {
    217                     return;
    218                 }
    219 
    220                 *outNumFds = tmpNumFds;
    221                 *outNumInts = tmpNumInts;
    222             });
    223 
    224     error = (ret.isOk()) ? error : kTransactionError;
    225 
    226     ALOGE_IF(error != Error::NONE, "getTransportSize(%p) failed with %d", buffer, error);
    227 }
    228 
    229 status_t Gralloc2Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
    230                               int acquireFence, void** outData, int32_t* outBytesPerPixel,
    231                               int32_t* outBytesPerStride) const {
    232     if (outBytesPerPixel) {
    233         *outBytesPerPixel = -1;
    234     }
    235     if (outBytesPerStride) {
    236         *outBytesPerStride = -1;
    237     }
    238     auto buffer = const_cast<native_handle_t*>(bufferHandle);
    239 
    240     IMapper::Rect accessRegion = sGralloc2Rect(bounds);
    241 
    242     // put acquireFence in a hidl_handle
    243     hardware::hidl_handle acquireFenceHandle;
    244     NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
    245     if (acquireFence >= 0) {
    246         auto h = native_handle_init(acquireFenceStorage, 1, 0);
    247         h->data[0] = acquireFence;
    248         acquireFenceHandle = h;
    249     }
    250 
    251     Error error;
    252     auto ret = mMapper->lock(buffer, usage, accessRegion, acquireFenceHandle,
    253             [&](const auto& tmpError, const auto& tmpData)
    254             {
    255                 error = tmpError;
    256                 if (error != Error::NONE) {
    257                     return;
    258                 }
    259 
    260                 *outData = tmpData;
    261             });
    262 
    263     // we own acquireFence even on errors
    264     if (acquireFence >= 0) {
    265         close(acquireFence);
    266     }
    267 
    268     error = (ret.isOk()) ? error : kTransactionError;
    269 
    270     ALOGW_IF(error != Error::NONE, "lock(%p, ...) failed: %d", bufferHandle, error);
    271 
    272     return static_cast<status_t>(error);
    273 }
    274 
    275 status_t Gralloc2Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
    276                               int acquireFence, android_ycbcr* ycbcr) const {
    277     auto buffer = const_cast<native_handle_t*>(bufferHandle);
    278 
    279     IMapper::Rect accessRegion = sGralloc2Rect(bounds);
    280 
    281     // put acquireFence in a hidl_handle
    282     hardware::hidl_handle acquireFenceHandle;
    283     NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
    284     if (acquireFence >= 0) {
    285         auto h = native_handle_init(acquireFenceStorage, 1, 0);
    286         h->data[0] = acquireFence;
    287         acquireFenceHandle = h;
    288     }
    289 
    290     YCbCrLayout layout;
    291     Error error;
    292     auto ret = mMapper->lockYCbCr(buffer, usage, accessRegion,
    293             acquireFenceHandle,
    294             [&](const auto& tmpError, const auto& tmpLayout)
    295             {
    296                 error = tmpError;
    297                 if (error != Error::NONE) {
    298                     return;
    299                 }
    300 
    301                 layout = tmpLayout;
    302             });
    303 
    304     if (error == Error::NONE) {
    305         ycbcr->y = layout.y;
    306         ycbcr->cb = layout.cb;
    307         ycbcr->cr = layout.cr;
    308         ycbcr->ystride = static_cast<size_t>(layout.yStride);
    309         ycbcr->cstride = static_cast<size_t>(layout.cStride);
    310         ycbcr->chroma_step = static_cast<size_t>(layout.chromaStep);
    311     }
    312 
    313     // we own acquireFence even on errors
    314     if (acquireFence >= 0) {
    315         close(acquireFence);
    316     }
    317 
    318     return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
    319 }
    320 
    321 int Gralloc2Mapper::unlock(buffer_handle_t bufferHandle) const {
    322     auto buffer = const_cast<native_handle_t*>(bufferHandle);
    323 
    324     int releaseFence = -1;
    325     Error error;
    326     auto ret = mMapper->unlock(buffer,
    327             [&](const auto& tmpError, const auto& tmpReleaseFence)
    328             {
    329                 error = tmpError;
    330                 if (error != Error::NONE) {
    331                     return;
    332                 }
    333 
    334                 auto fenceHandle = tmpReleaseFence.getNativeHandle();
    335                 if (fenceHandle && fenceHandle->numFds == 1) {
    336                     int fd = dup(fenceHandle->data[0]);
    337                     if (fd >= 0) {
    338                         releaseFence = fd;
    339                     } else {
    340                         ALOGD("failed to dup unlock release fence");
    341                         sync_wait(fenceHandle->data[0], -1);
    342                     }
    343                 }
    344             });
    345 
    346     error = (ret.isOk()) ? error : kTransactionError;
    347     if (error != Error::NONE) {
    348         ALOGE("unlock(%p) failed with %d", buffer, error);
    349     }
    350 
    351     return releaseFence;
    352 }
    353 
    354 status_t Gralloc2Mapper::isSupported(uint32_t /*width*/, uint32_t /*height*/,
    355                                      android::PixelFormat /*format*/, uint32_t /*layerCount*/,
    356                                      uint64_t /*usage*/, bool* /*outSupported*/) const {
    357     return INVALID_OPERATION;
    358 }
    359 
    360 Gralloc2Allocator::Gralloc2Allocator(const Gralloc2Mapper& mapper) : mMapper(mapper) {
    361     mAllocator = IAllocator::getService();
    362     if (mAllocator == nullptr) {
    363         ALOGW("allocator 2.x is not supported");
    364         return;
    365     }
    366 }
    367 
    368 bool Gralloc2Allocator::isLoaded() const {
    369     return mAllocator != nullptr;
    370 }
    371 
    372 std::string Gralloc2Allocator::dumpDebugInfo() const {
    373     std::string debugInfo;
    374 
    375     mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) {
    376         debugInfo = tmpDebugInfo.c_str();
    377     });
    378 
    379     return debugInfo;
    380 }
    381 
    382 status_t Gralloc2Allocator::allocate(uint32_t width, uint32_t height, PixelFormat format,
    383                                      uint32_t layerCount, uint64_t usage, uint32_t bufferCount,
    384                                      uint32_t* outStride, buffer_handle_t* outBufferHandles) const {
    385     IMapper::BufferDescriptorInfo descriptorInfo = {};
    386     descriptorInfo.width = width;
    387     descriptorInfo.height = height;
    388     descriptorInfo.layerCount = layerCount;
    389     descriptorInfo.format = static_cast<hardware::graphics::common::V1_1::PixelFormat>(format);
    390     descriptorInfo.usage = usage;
    391 
    392     BufferDescriptor descriptor;
    393     status_t error = mMapper.createDescriptor(static_cast<void*>(&descriptorInfo),
    394                                               static_cast<void*>(&descriptor));
    395     if (error != NO_ERROR) {
    396         return error;
    397     }
    398 
    399     auto ret = mAllocator->allocate(descriptor, bufferCount,
    400                                     [&](const auto& tmpError, const auto& tmpStride,
    401                                         const auto& tmpBuffers) {
    402                                         error = static_cast<status_t>(tmpError);
    403                                         if (tmpError != Error::NONE) {
    404                                             return;
    405                                         }
    406 
    407                                         // import buffers
    408                                         for (uint32_t i = 0; i < bufferCount; i++) {
    409                                             error = mMapper.importBuffer(tmpBuffers[i],
    410                                                                          &outBufferHandles[i]);
    411                                             if (error != NO_ERROR) {
    412                                                 for (uint32_t j = 0; j < i; j++) {
    413                                                     mMapper.freeBuffer(outBufferHandles[j]);
    414                                                     outBufferHandles[j] = nullptr;
    415                                                 }
    416                                                 return;
    417                                             }
    418                                         }
    419 
    420                                         *outStride = tmpStride;
    421                                     });
    422 
    423     // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now
    424     hardware::IPCThreadState::self()->flushCommands();
    425 
    426     return (ret.isOk()) ? error : static_cast<status_t>(kTransactionError);
    427 }
    428 
    429 } // namespace android
    430