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