Home | History | Annotate | Download | only in vndk
      1 /*
      2  * Copyright (C) 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_NDEBUG 0
     18 #define LOG_TAG "C2AllocatorGralloc"
     19 #include <utils/Log.h>
     20 
     21 #include <android/hardware/graphics/allocator/2.0/IAllocator.h>
     22 #include <android/hardware/graphics/mapper/2.0/IMapper.h>
     23 #include <android/hardware/graphics/allocator/3.0/IAllocator.h>
     24 #include <android/hardware/graphics/mapper/3.0/IMapper.h>
     25 #include <cutils/native_handle.h>
     26 #include <hardware/gralloc.h>
     27 
     28 #include <C2AllocatorGralloc.h>
     29 #include <C2Buffer.h>
     30 #include <C2PlatformSupport.h>
     31 
     32 namespace android {
     33 
     34 namespace /* unnamed */ {
     35     enum : uint64_t {
     36         /**
     37          * Usage mask that is passed through from gralloc to Codec 2.0 usage.
     38          */
     39         PASSTHROUGH_USAGE_MASK =
     40             ~(GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK | GRALLOC_USAGE_PROTECTED)
     41     };
     42 
     43     // verify that passthrough mask is within the platform mask
     44     static_assert((~C2MemoryUsage::PLATFORM_MASK & PASSTHROUGH_USAGE_MASK) == 0, "");
     45 } // unnamed
     46 
     47 C2MemoryUsage C2AndroidMemoryUsage::FromGrallocUsage(uint64_t usage) {
     48     // gralloc does not support WRITE_PROTECTED
     49     return C2MemoryUsage(
     50             ((usage & GRALLOC_USAGE_SW_READ_MASK) ? C2MemoryUsage::CPU_READ : 0) |
     51             ((usage & GRALLOC_USAGE_SW_WRITE_MASK) ? C2MemoryUsage::CPU_WRITE : 0) |
     52             ((usage & GRALLOC_USAGE_PROTECTED) ? C2MemoryUsage::READ_PROTECTED : 0) |
     53             (usage & PASSTHROUGH_USAGE_MASK));
     54 }
     55 
     56 uint64_t C2AndroidMemoryUsage::asGrallocUsage() const {
     57     // gralloc does not support WRITE_PROTECTED
     58     return (((expected & C2MemoryUsage::CPU_READ) ? GRALLOC_USAGE_SW_READ_OFTEN : 0) |
     59             ((expected & C2MemoryUsage::CPU_WRITE) ? GRALLOC_USAGE_SW_WRITE_OFTEN : 0) |
     60             ((expected & C2MemoryUsage::READ_PROTECTED) ? GRALLOC_USAGE_PROTECTED : 0) |
     61             (expected & PASSTHROUGH_USAGE_MASK));
     62 }
     63 
     64 using ::android::hardware::hidl_handle;
     65 using ::android::hardware::hidl_vec;
     66 using ::android::hardware::graphics::common::V1_0::BufferUsage;
     67 using PixelFormat2 = ::android::hardware::graphics::common::V1_0::PixelFormat;
     68 using PixelFormat3 = ::android::hardware::graphics::common::V1_2::PixelFormat;
     69 
     70 using IAllocator2 = ::android::hardware::graphics::allocator::V2_0::IAllocator;
     71 using BufferDescriptor2 = ::android::hardware::graphics::mapper::V2_0::BufferDescriptor;
     72 using Error2 = ::android::hardware::graphics::mapper::V2_0::Error;
     73 using IMapper2 = ::android::hardware::graphics::mapper::V2_0::IMapper;
     74 
     75 using IAllocator3 = ::android::hardware::graphics::allocator::V3_0::IAllocator;
     76 using BufferDescriptor3 = ::android::hardware::graphics::mapper::V3_0::BufferDescriptor;
     77 using Error3 = ::android::hardware::graphics::mapper::V3_0::Error;
     78 using IMapper3 = ::android::hardware::graphics::mapper::V3_0::IMapper;
     79 
     80 namespace /* unnamed */ {
     81 
     82 struct BufferDescriptorInfo2 {
     83     IMapper2::BufferDescriptorInfo mapperInfo;
     84     uint32_t stride;
     85 };
     86 
     87 struct BufferDescriptorInfo3 {
     88     IMapper3::BufferDescriptorInfo mapperInfo;
     89     uint32_t stride;
     90 };
     91 
     92 /* ===================================== GRALLOC ALLOCATION ==================================== */
     93 c2_status_t maperr2error(Error2 maperr) {
     94     switch (maperr) {
     95         case Error2::NONE:           return C2_OK;
     96         case Error2::BAD_DESCRIPTOR: return C2_BAD_VALUE;
     97         case Error2::BAD_BUFFER:     return C2_BAD_VALUE;
     98         case Error2::BAD_VALUE:      return C2_BAD_VALUE;
     99         case Error2::NO_RESOURCES:   return C2_NO_MEMORY;
    100         case Error2::UNSUPPORTED:    return C2_CANNOT_DO;
    101     }
    102     return C2_CORRUPTED;
    103 }
    104 
    105 c2_status_t maperr2error(Error3 maperr) {
    106     switch (maperr) {
    107         case Error3::NONE:           return C2_OK;
    108         case Error3::BAD_DESCRIPTOR: return C2_BAD_VALUE;
    109         case Error3::BAD_BUFFER:     return C2_BAD_VALUE;
    110         case Error3::BAD_VALUE:      return C2_BAD_VALUE;
    111         case Error3::NO_RESOURCES:   return C2_NO_MEMORY;
    112         case Error3::UNSUPPORTED:    return C2_CANNOT_DO;
    113     }
    114     return C2_CORRUPTED;
    115 }
    116 
    117 bool native_handle_is_invalid(const native_handle_t *const handle) {
    118     // perform basic validation of a native handle
    119     if (handle == nullptr) {
    120         // null handle is considered valid
    121         return false;
    122     }
    123     return ((size_t)handle->version != sizeof(native_handle_t) ||
    124             handle->numFds < 0 ||
    125             handle->numInts < 0 ||
    126             // for sanity assume handles must occupy less memory than INT_MAX bytes
    127             handle->numFds > int((INT_MAX - handle->version) / sizeof(int)) - handle->numInts);
    128 }
    129 
    130 class C2HandleGralloc : public C2Handle {
    131 private:
    132     struct ExtraData {
    133         uint32_t width;
    134         uint32_t height;
    135         uint32_t format;
    136         uint32_t usage_lo;
    137         uint32_t usage_hi;
    138         uint32_t stride;
    139         uint32_t generation;
    140         uint32_t igbp_id_lo;
    141         uint32_t igbp_id_hi;
    142         uint32_t igbp_slot;
    143         uint32_t magic;
    144     };
    145 
    146     enum {
    147         NUM_INTS = sizeof(ExtraData) / sizeof(int),
    148     };
    149     const static uint32_t MAGIC = '\xc2gr\x00';
    150 
    151     static
    152     const ExtraData* getExtraData(const C2Handle *const handle) {
    153         if (handle == nullptr
    154                 || native_handle_is_invalid(handle)
    155                 || handle->numInts < NUM_INTS) {
    156             return nullptr;
    157         }
    158         return reinterpret_cast<const ExtraData*>(
    159                 &handle->data[handle->numFds + handle->numInts - NUM_INTS]);
    160     }
    161 
    162     static
    163     ExtraData *getExtraData(C2Handle *const handle) {
    164         return const_cast<ExtraData *>(getExtraData(const_cast<const C2Handle *const>(handle)));
    165     }
    166 
    167 public:
    168     void getIgbpData(uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) const {
    169         const ExtraData *ed = getExtraData(this);
    170         *generation = ed->generation;
    171         *igbp_id = unsigned(ed->igbp_id_lo) | uint64_t(unsigned(ed->igbp_id_hi)) << 32;
    172         *igbp_slot = ed->igbp_slot;
    173     }
    174 
    175     static bool isValid(const C2Handle *const o) {
    176         if (o == nullptr) { // null handle is always valid
    177             return true;
    178         }
    179         const ExtraData *xd = getExtraData(o);
    180         // we cannot validate width/height/format/usage without accessing gralloc driver
    181         return xd != nullptr && xd->magic == MAGIC;
    182     }
    183 
    184     static C2HandleGralloc* WrapAndMoveNativeHandle(
    185             const native_handle_t *const handle,
    186             uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
    187             uint32_t stride, uint32_t generation, uint64_t igbp_id = 0, uint32_t igbp_slot = 0) {
    188         //CHECK(handle != nullptr);
    189         if (native_handle_is_invalid(handle) ||
    190             handle->numInts > int((INT_MAX - handle->version) / sizeof(int)) - NUM_INTS - handle->numFds) {
    191             return nullptr;
    192         }
    193         ExtraData xd = {
    194             width, height, format, uint32_t(usage & 0xFFFFFFFF), uint32_t(usage >> 32),
    195             stride, generation, uint32_t(igbp_id & 0xFFFFFFFF), uint32_t(igbp_id >> 32),
    196             igbp_slot, MAGIC
    197         };
    198         native_handle_t *res = native_handle_create(handle->numFds, handle->numInts + NUM_INTS);
    199         if (res != nullptr) {
    200             memcpy(&res->data, &handle->data, sizeof(int) * (handle->numFds + handle->numInts));
    201             *getExtraData(res) = xd;
    202         }
    203         return reinterpret_cast<C2HandleGralloc *>(res);
    204     }
    205 
    206     static C2HandleGralloc* WrapNativeHandle(
    207             const native_handle_t *const handle,
    208             uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
    209             uint32_t stride, uint32_t generation, uint64_t igbp_id = 0, uint32_t igbp_slot = 0) {
    210         if (handle == nullptr) {
    211             return nullptr;
    212         }
    213         native_handle_t *clone = native_handle_clone(handle);
    214         if (clone == nullptr) {
    215             return nullptr;
    216         }
    217         C2HandleGralloc *res = WrapAndMoveNativeHandle(
    218                 clone, width, height, format, usage, stride, generation, igbp_id, igbp_slot);
    219         if (res == nullptr) {
    220             native_handle_close(clone);
    221         }
    222         native_handle_delete(clone);
    223         return res;
    224     }
    225 
    226     static bool MigrateNativeHandle(
    227             native_handle_t *handle,
    228             uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
    229         if (handle == nullptr || !isValid(handle)) {
    230             return false;
    231         }
    232         ExtraData *ed = getExtraData(handle);
    233         if (!ed) return false;
    234         ed->generation = generation;
    235         ed->igbp_id_lo = uint32_t(igbp_id & 0xFFFFFFFF);
    236         ed->igbp_id_hi = uint32_t(igbp_id >> 32);
    237         ed->igbp_slot = igbp_slot;
    238         return true;
    239     }
    240 
    241 
    242     static native_handle_t* UnwrapNativeHandle(
    243             const C2Handle *const handle) {
    244         const ExtraData *xd = getExtraData(handle);
    245         if (xd == nullptr || xd->magic != MAGIC) {
    246             return nullptr;
    247         }
    248         native_handle_t *res = native_handle_create(handle->numFds, handle->numInts - NUM_INTS);
    249         if (res != nullptr) {
    250             memcpy(&res->data, &handle->data, sizeof(int) * (res->numFds + res->numInts));
    251         }
    252         return res;
    253     }
    254 
    255     static const C2HandleGralloc* Import(
    256             const C2Handle *const handle,
    257             uint32_t *width, uint32_t *height, uint32_t *format,
    258             uint64_t *usage, uint32_t *stride,
    259             uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) {
    260         const ExtraData *xd = getExtraData(handle);
    261         if (xd == nullptr) {
    262             return nullptr;
    263         }
    264         *width = xd->width;
    265         *height = xd->height;
    266         *format = xd->format;
    267         *usage = xd->usage_lo | (uint64_t(xd->usage_hi) << 32);
    268         *stride = xd->stride;
    269         *generation = xd->generation;
    270         *igbp_id = xd->igbp_id_lo | (uint64_t(xd->igbp_id_hi) << 32);
    271         *igbp_slot = xd->igbp_slot;
    272         return reinterpret_cast<const C2HandleGralloc *>(handle);
    273     }
    274 };
    275 
    276 } // unnamed namespace
    277 
    278 native_handle_t *UnwrapNativeCodec2GrallocHandle(const C2Handle *const handle) {
    279     return C2HandleGralloc::UnwrapNativeHandle(handle);
    280 }
    281 
    282 C2Handle *WrapNativeCodec2GrallocHandle(
    283         const native_handle_t *const handle,
    284         uint32_t width, uint32_t height, uint32_t format, uint64_t usage, uint32_t stride,
    285         uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
    286     return C2HandleGralloc::WrapNativeHandle(handle, width, height, format, usage, stride,
    287                                              generation, igbp_id, igbp_slot);
    288 }
    289 
    290 bool MigrateNativeCodec2GrallocHandle(
    291         native_handle_t *handle,
    292         uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
    293     return C2HandleGralloc::MigrateNativeHandle(handle, generation, igbp_id, igbp_slot);
    294 }
    295 
    296 
    297 class C2AllocationGralloc : public C2GraphicAllocation {
    298 public:
    299     virtual ~C2AllocationGralloc() override;
    300 
    301     virtual c2_status_t map(
    302             C2Rect rect, C2MemoryUsage usage, C2Fence *fence,
    303             C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) override;
    304     virtual c2_status_t unmap(
    305             uint8_t **addr /* nonnull */, C2Rect rect, C2Fence *fence /* nullable */) override;
    306     virtual C2Allocator::id_t getAllocatorId() const override { return mAllocatorId; }
    307     virtual const C2Handle *handle() const override { return mLockedHandle ? : mHandle; }
    308     virtual bool equals(const std::shared_ptr<const C2GraphicAllocation> &other) const override;
    309 
    310     // internal methods
    311     // |handle| will be moved.
    312     C2AllocationGralloc(
    313               const BufferDescriptorInfo2 &info,
    314               const sp<IMapper2> &mapper,
    315               hidl_handle &hidlHandle,
    316               const C2HandleGralloc *const handle,
    317               C2Allocator::id_t allocatorId);
    318     C2AllocationGralloc(
    319               const BufferDescriptorInfo3 &info,
    320               const sp<IMapper3> &mapper,
    321               hidl_handle &hidlHandle,
    322               const C2HandleGralloc *const handle,
    323               C2Allocator::id_t allocatorId);
    324     int dup() const;
    325     c2_status_t status() const;
    326 
    327 private:
    328     const BufferDescriptorInfo2 mInfo2{};
    329     const sp<IMapper2> mMapper2{nullptr};
    330     const BufferDescriptorInfo3 mInfo3{};
    331     const sp<IMapper3> mMapper3{nullptr};
    332     const hidl_handle mHidlHandle;
    333     const C2HandleGralloc *mHandle;
    334     buffer_handle_t mBuffer;
    335     const C2HandleGralloc *mLockedHandle;
    336     bool mLocked;
    337     C2Allocator::id_t mAllocatorId;
    338     std::mutex mMappedLock;
    339 };
    340 
    341 C2AllocationGralloc::C2AllocationGralloc(
    342           const BufferDescriptorInfo2 &info,
    343           const sp<IMapper2> &mapper,
    344           hidl_handle &hidlHandle,
    345           const C2HandleGralloc *const handle,
    346           C2Allocator::id_t allocatorId)
    347     : C2GraphicAllocation(info.mapperInfo.width, info.mapperInfo.height),
    348       mInfo2(info),
    349       mMapper2(mapper),
    350       mHidlHandle(std::move(hidlHandle)),
    351       mHandle(handle),
    352       mBuffer(nullptr),
    353       mLockedHandle(nullptr),
    354       mLocked(false),
    355       mAllocatorId(allocatorId) {
    356 }
    357 
    358 C2AllocationGralloc::C2AllocationGralloc(
    359           const BufferDescriptorInfo3 &info,
    360           const sp<IMapper3> &mapper,
    361           hidl_handle &hidlHandle,
    362           const C2HandleGralloc *const handle,
    363           C2Allocator::id_t allocatorId)
    364     : C2GraphicAllocation(info.mapperInfo.width, info.mapperInfo.height),
    365       mInfo3(info),
    366       mMapper3(mapper),
    367       mHidlHandle(std::move(hidlHandle)),
    368       mHandle(handle),
    369       mBuffer(nullptr),
    370       mLockedHandle(nullptr),
    371       mLocked(false),
    372       mAllocatorId(allocatorId) {
    373 }
    374 
    375 C2AllocationGralloc::~C2AllocationGralloc() {
    376     if (mBuffer && mLocked) {
    377         // implementation ignores addresss and rect
    378         uint8_t* addr[C2PlanarLayout::MAX_NUM_PLANES] = {};
    379         unmap(addr, C2Rect(), nullptr);
    380     }
    381     if (mBuffer) {
    382         if (mMapper2) {
    383             if (!mMapper2->freeBuffer(const_cast<native_handle_t *>(
    384                     mBuffer)).isOk()) {
    385                 ALOGE("failed transaction: freeBuffer");
    386             }
    387         } else {
    388             if (!mMapper3->freeBuffer(const_cast<native_handle_t *>(
    389                     mBuffer)).isOk()) {
    390                 ALOGE("failed transaction: freeBuffer");
    391             }
    392         }
    393     }
    394     if (mHandle) {
    395         native_handle_delete(
    396                 const_cast<native_handle_t *>(reinterpret_cast<const native_handle_t *>(mHandle)));
    397     }
    398     if (mLockedHandle) {
    399         native_handle_delete(
    400                 const_cast<native_handle_t *>(
    401                         reinterpret_cast<const native_handle_t *>(mLockedHandle)));
    402     }
    403 }
    404 
    405 c2_status_t C2AllocationGralloc::map(
    406         C2Rect rect, C2MemoryUsage usage, C2Fence *fence,
    407         C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) {
    408     uint64_t grallocUsage = static_cast<C2AndroidMemoryUsage>(usage).asGrallocUsage();
    409     ALOGV("mapping buffer with usage %#llx => %#llx",
    410           (long long)usage.expected, (long long)grallocUsage);
    411 
    412     // TODO
    413     (void) fence;
    414 
    415     std::lock_guard<std::mutex> lock(mMappedLock);
    416     if (mBuffer && mLocked) {
    417         ALOGD("already mapped");
    418         return C2_DUPLICATE;
    419     }
    420     if (!layout || !addr) {
    421         ALOGD("wrong param");
    422         return C2_BAD_VALUE;
    423     }
    424 
    425     c2_status_t err = C2_OK;
    426     if (!mBuffer) {
    427         if (mMapper2) {
    428             if (!mMapper2->importBuffer(
    429                     mHidlHandle, [&err, this](const auto &maperr, const auto &buffer) {
    430                         err = maperr2error(maperr);
    431                         if (err == C2_OK) {
    432                             mBuffer = static_cast<buffer_handle_t>(buffer);
    433                         }
    434                     }).isOk()) {
    435                 ALOGE("failed transaction: importBuffer");
    436                 return C2_CORRUPTED;
    437             }
    438         } else {
    439             if (!mMapper3->importBuffer(
    440                     mHidlHandle, [&err, this](const auto &maperr, const auto &buffer) {
    441                         err = maperr2error(maperr);
    442                         if (err == C2_OK) {
    443                             mBuffer = static_cast<buffer_handle_t>(buffer);
    444                         }
    445                     }).isOk()) {
    446                 ALOGE("failed transaction: importBuffer (@3.0)");
    447                 return C2_CORRUPTED;
    448             }
    449         }
    450         if (err != C2_OK) {
    451             ALOGD("importBuffer failed: %d", err);
    452             return err;
    453         }
    454         if (mBuffer == nullptr) {
    455             ALOGD("importBuffer returned null buffer");
    456             return C2_CORRUPTED;
    457         }
    458         uint32_t generation = 0;
    459         uint64_t igbp_id = 0;
    460         uint32_t igbp_slot = 0;
    461         if (mHandle) {
    462             mHandle->getIgbpData(&generation, &igbp_id, &igbp_slot);
    463         }
    464         if (mMapper2) {
    465             mLockedHandle = C2HandleGralloc::WrapAndMoveNativeHandle(
    466                     mBuffer, mInfo2.mapperInfo.width, mInfo2.mapperInfo.height,
    467                     (uint32_t)mInfo2.mapperInfo.format, mInfo2.mapperInfo.usage,
    468                     mInfo2.stride, generation, igbp_id, igbp_slot);
    469         } else {
    470             mLockedHandle = C2HandleGralloc::WrapAndMoveNativeHandle(
    471                     mBuffer, mInfo3.mapperInfo.width, mInfo3.mapperInfo.height,
    472                     (uint32_t)mInfo3.mapperInfo.format, mInfo3.mapperInfo.usage,
    473                     mInfo3.stride, generation, igbp_id, igbp_slot);
    474         }
    475     }
    476 
    477     PixelFormat3 format = mMapper2 ?
    478             PixelFormat3(mInfo2.mapperInfo.format) :
    479             PixelFormat3(mInfo3.mapperInfo.format);
    480     switch (format) {
    481         case PixelFormat3::RGBA_1010102: {
    482             // TRICKY: this is used for media as YUV444 in the case when it is queued directly to a
    483             // Surface. In all other cases it is RGBA. We don't know which case it is here, so
    484             // default to YUV for now.
    485             void *pointer = nullptr;
    486             if (mMapper2) {
    487                 if (!mMapper2->lock(
    488                         const_cast<native_handle_t *>(mBuffer),
    489                         grallocUsage,
    490                         { (int32_t)rect.left, (int32_t)rect.top,
    491                           (int32_t)rect.width, (int32_t)rect.height },
    492                         // TODO: fence
    493                         hidl_handle(),
    494                         [&err, &pointer](const auto &maperr, const auto &mapPointer) {
    495                             err = maperr2error(maperr);
    496                             if (err == C2_OK) {
    497                                 pointer = mapPointer;
    498                             }
    499                         }).isOk()) {
    500                     ALOGE("failed transaction: lock(RGBA_1010102)");
    501                     return C2_CORRUPTED;
    502                 }
    503             } else {
    504                 if (!mMapper3->lock(
    505                         const_cast<native_handle_t *>(mBuffer),
    506                         grallocUsage,
    507                         { (int32_t)rect.left, (int32_t)rect.top,
    508                           (int32_t)rect.width, (int32_t)rect.height },
    509                         // TODO: fence
    510                         hidl_handle(),
    511                         [&err, &pointer](const auto &maperr, const auto &mapPointer,
    512                                          int32_t bytesPerPixel, int32_t bytesPerStride) {
    513                             err = maperr2error(maperr);
    514                             if (err == C2_OK) {
    515                                 pointer = mapPointer;
    516                             }
    517                             (void)bytesPerPixel;
    518                             (void)bytesPerStride;
    519                         }).isOk()) {
    520                     ALOGE("failed transaction: lock(RGBA_1010102) (@3.0)");
    521                     return C2_CORRUPTED;
    522                 }
    523             }
    524             if (err != C2_OK) {
    525                 ALOGD("lock failed: %d", err);
    526                 return err;
    527             }
    528             // treat as 32-bit values
    529             addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)pointer;
    530             addr[C2PlanarLayout::PLANE_U] = (uint8_t *)pointer;
    531             addr[C2PlanarLayout::PLANE_V] = (uint8_t *)pointer;
    532             addr[C2PlanarLayout::PLANE_A] = (uint8_t *)pointer;
    533             layout->type = C2PlanarLayout::TYPE_YUVA;
    534             layout->numPlanes = 4;
    535             layout->rootPlanes = 1;
    536             int32_t stride = mMapper2 ?
    537                     int32_t(mInfo2.stride) :
    538                     int32_t(mInfo3.stride);
    539             layout->planes[C2PlanarLayout::PLANE_Y] = {
    540                 C2PlaneInfo::CHANNEL_Y,         // channel
    541                 4,                              // colInc
    542                 4 * stride,                     // rowInc
    543                 1,                              // mColSampling
    544                 1,                              // mRowSampling
    545                 32,                             // allocatedDepth
    546                 10,                             // bitDepth
    547                 10,                             // rightShift
    548                 C2PlaneInfo::LITTLE_END,        // endianness
    549                 C2PlanarLayout::PLANE_Y,        // rootIx
    550                 0,                              // offset
    551             };
    552             layout->planes[C2PlanarLayout::PLANE_U] = {
    553                 C2PlaneInfo::CHANNEL_CB,         // channel
    554                 4,                              // colInc
    555                 4 * stride,                     // rowInc
    556                 1,                              // mColSampling
    557                 1,                              // mRowSampling
    558                 32,                             // allocatedDepth
    559                 10,                             // bitDepth
    560                 0,                              // rightShift
    561                 C2PlaneInfo::LITTLE_END,        // endianness
    562                 C2PlanarLayout::PLANE_Y,        // rootIx
    563                 0,                              // offset
    564             };
    565             layout->planes[C2PlanarLayout::PLANE_V] = {
    566                 C2PlaneInfo::CHANNEL_CR,         // channel
    567                 4,                              // colInc
    568                 4 * stride,                     // rowInc
    569                 1,                              // mColSampling
    570                 1,                              // mRowSampling
    571                 32,                             // allocatedDepth
    572                 10,                             // bitDepth
    573                 20,                             // rightShift
    574                 C2PlaneInfo::LITTLE_END,        // endianness
    575                 C2PlanarLayout::PLANE_Y,        // rootIx
    576                 0,                              // offset
    577             };
    578             layout->planes[C2PlanarLayout::PLANE_A] = {
    579                 C2PlaneInfo::CHANNEL_A,         // channel
    580                 4,                              // colInc
    581                 4 * stride,                     // rowInc
    582                 1,                              // mColSampling
    583                 1,                              // mRowSampling
    584                 32,                             // allocatedDepth
    585                 2,                              // bitDepth
    586                 30,                             // rightShift
    587                 C2PlaneInfo::LITTLE_END,        // endianness
    588                 C2PlanarLayout::PLANE_Y,        // rootIx
    589                 0,                              // offset
    590             };
    591             break;
    592         }
    593 
    594         case PixelFormat3::RGBA_8888:
    595             // TODO: alpha channel
    596             // fall-through
    597         case PixelFormat3::RGBX_8888: {
    598             void *pointer = nullptr;
    599             if (mMapper2) {
    600                 if (!mMapper2->lock(
    601                         const_cast<native_handle_t *>(mBuffer),
    602                         grallocUsage,
    603                         { (int32_t)rect.left, (int32_t)rect.top,
    604                           (int32_t)rect.width, (int32_t)rect.height },
    605                         // TODO: fence
    606                         hidl_handle(),
    607                         [&err, &pointer](const auto &maperr, const auto &mapPointer) {
    608                             err = maperr2error(maperr);
    609                             if (err == C2_OK) {
    610                                 pointer = mapPointer;
    611                             }
    612                         }).isOk()) {
    613                     ALOGE("failed transaction: lock(RGBA_8888)");
    614                     return C2_CORRUPTED;
    615                 }
    616             } else {
    617                 if (!mMapper3->lock(
    618                         const_cast<native_handle_t *>(mBuffer),
    619                         grallocUsage,
    620                         { (int32_t)rect.left, (int32_t)rect.top,
    621                           (int32_t)rect.width, (int32_t)rect.height },
    622                         // TODO: fence
    623                         hidl_handle(),
    624                         [&err, &pointer](const auto &maperr, const auto &mapPointer,
    625                                          int32_t bytesPerPixel, int32_t bytesPerStride) {
    626                             err = maperr2error(maperr);
    627                             if (err == C2_OK) {
    628                                 pointer = mapPointer;
    629                             }
    630                             (void)bytesPerPixel;
    631                             (void)bytesPerStride;
    632                         }).isOk()) {
    633                     ALOGE("failed transaction: lock(RGBA_8888) (@3.0)");
    634                     return C2_CORRUPTED;
    635                 }
    636             }
    637             if (err != C2_OK) {
    638                 ALOGD("lock failed: %d", err);
    639                 return err;
    640             }
    641             addr[C2PlanarLayout::PLANE_R] = (uint8_t *)pointer;
    642             addr[C2PlanarLayout::PLANE_G] = (uint8_t *)pointer + 1;
    643             addr[C2PlanarLayout::PLANE_B] = (uint8_t *)pointer + 2;
    644             layout->type = C2PlanarLayout::TYPE_RGB;
    645             layout->numPlanes = 3;
    646             layout->rootPlanes = 1;
    647             int32_t stride = mMapper2 ?
    648                     int32_t(mInfo2.stride) :
    649                     int32_t(mInfo3.stride);
    650             layout->planes[C2PlanarLayout::PLANE_R] = {
    651                 C2PlaneInfo::CHANNEL_R,         // channel
    652                 4,                              // colInc
    653                 4 * stride,                     // rowInc
    654                 1,                              // mColSampling
    655                 1,                              // mRowSampling
    656                 8,                              // allocatedDepth
    657                 8,                              // bitDepth
    658                 0,                              // rightShift
    659                 C2PlaneInfo::NATIVE,            // endianness
    660                 C2PlanarLayout::PLANE_R,        // rootIx
    661                 0,                              // offset
    662             };
    663             layout->planes[C2PlanarLayout::PLANE_G] = {
    664                 C2PlaneInfo::CHANNEL_G,         // channel
    665                 4,                              // colInc
    666                 4 * stride,                     // rowInc
    667                 1,                              // mColSampling
    668                 1,                              // mRowSampling
    669                 8,                              // allocatedDepth
    670                 8,                              // bitDepth
    671                 0,                              // rightShift
    672                 C2PlaneInfo::NATIVE,            // endianness
    673                 C2PlanarLayout::PLANE_R,        // rootIx
    674                 1,                              // offset
    675             };
    676             layout->planes[C2PlanarLayout::PLANE_B] = {
    677                 C2PlaneInfo::CHANNEL_B,         // channel
    678                 4,                              // colInc
    679                 4 * stride,                     // rowInc
    680                 1,                              // mColSampling
    681                 1,                              // mRowSampling
    682                 8,                              // allocatedDepth
    683                 8,                              // bitDepth
    684                 0,                              // rightShift
    685                 C2PlaneInfo::NATIVE,            // endianness
    686                 C2PlanarLayout::PLANE_R,        // rootIx
    687                 2,                              // offset
    688             };
    689             break;
    690         }
    691 
    692         case PixelFormat3::YCBCR_420_888:
    693             // fall-through
    694         case PixelFormat3::YV12:
    695             // fall-through
    696         default: {
    697             struct YCbCrLayout {
    698                 void* y;
    699                 void* cb;
    700                 void* cr;
    701                 uint32_t yStride;
    702                 uint32_t cStride;
    703                 uint32_t chromaStep;
    704             };
    705             YCbCrLayout ycbcrLayout;
    706             if (mMapper2) {
    707                 if (!mMapper2->lockYCbCr(
    708                         const_cast<native_handle_t *>(mBuffer), grallocUsage,
    709                         { (int32_t)rect.left, (int32_t)rect.top,
    710                           (int32_t)rect.width, (int32_t)rect.height },
    711                         // TODO: fence
    712                         hidl_handle(),
    713                         [&err, &ycbcrLayout](const auto &maperr, const auto &mapLayout) {
    714                             err = maperr2error(maperr);
    715                             if (err == C2_OK) {
    716                                 ycbcrLayout = YCbCrLayout{
    717                                         mapLayout.y,
    718                                         mapLayout.cb,
    719                                         mapLayout.cr,
    720                                         mapLayout.yStride,
    721                                         mapLayout.cStride,
    722                                         mapLayout.chromaStep};
    723                             }
    724                         }).isOk()) {
    725                     ALOGE("failed transaction: lockYCbCr");
    726                     return C2_CORRUPTED;
    727                 }
    728             } else {
    729                 if (!mMapper3->lockYCbCr(
    730                         const_cast<native_handle_t *>(mBuffer), grallocUsage,
    731                         { (int32_t)rect.left, (int32_t)rect.top,
    732                           (int32_t)rect.width, (int32_t)rect.height },
    733                         // TODO: fence
    734                         hidl_handle(),
    735                         [&err, &ycbcrLayout](const auto &maperr, const auto &mapLayout) {
    736                             err = maperr2error(maperr);
    737                             if (err == C2_OK) {
    738                                 ycbcrLayout = YCbCrLayout{
    739                                         mapLayout.y,
    740                                         mapLayout.cb,
    741                                         mapLayout.cr,
    742                                         mapLayout.yStride,
    743                                         mapLayout.cStride,
    744                                         mapLayout.chromaStep};
    745                             }
    746                         }).isOk()) {
    747                     ALOGE("failed transaction: lockYCbCr (@3.0)");
    748                     return C2_CORRUPTED;
    749                 }
    750             }
    751             if (err != C2_OK) {
    752                 ALOGD("lockYCbCr failed: %d", err);
    753                 return err;
    754             }
    755             addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)ycbcrLayout.y;
    756             addr[C2PlanarLayout::PLANE_U] = (uint8_t *)ycbcrLayout.cb;
    757             addr[C2PlanarLayout::PLANE_V] = (uint8_t *)ycbcrLayout.cr;
    758             layout->type = C2PlanarLayout::TYPE_YUV;
    759             layout->numPlanes = 3;
    760             layout->rootPlanes = 3;
    761             layout->planes[C2PlanarLayout::PLANE_Y] = {
    762                 C2PlaneInfo::CHANNEL_Y,         // channel
    763                 1,                              // colInc
    764                 (int32_t)ycbcrLayout.yStride,   // rowInc
    765                 1,                              // mColSampling
    766                 1,                              // mRowSampling
    767                 8,                              // allocatedDepth
    768                 8,                              // bitDepth
    769                 0,                              // rightShift
    770                 C2PlaneInfo::NATIVE,            // endianness
    771                 C2PlanarLayout::PLANE_Y,        // rootIx
    772                 0,                              // offset
    773             };
    774             layout->planes[C2PlanarLayout::PLANE_U] = {
    775                 C2PlaneInfo::CHANNEL_CB,          // channel
    776                 (int32_t)ycbcrLayout.chromaStep,  // colInc
    777                 (int32_t)ycbcrLayout.cStride,     // rowInc
    778                 2,                                // mColSampling
    779                 2,                                // mRowSampling
    780                 8,                                // allocatedDepth
    781                 8,                                // bitDepth
    782                 0,                                // rightShift
    783                 C2PlaneInfo::NATIVE,              // endianness
    784                 C2PlanarLayout::PLANE_U,          // rootIx
    785                 0,                                // offset
    786             };
    787             layout->planes[C2PlanarLayout::PLANE_V] = {
    788                 C2PlaneInfo::CHANNEL_CR,          // channel
    789                 (int32_t)ycbcrLayout.chromaStep,  // colInc
    790                 (int32_t)ycbcrLayout.cStride,     // rowInc
    791                 2,                                // mColSampling
    792                 2,                                // mRowSampling
    793                 8,                                // allocatedDepth
    794                 8,                                // bitDepth
    795                 0,                                // rightShift
    796                 C2PlaneInfo::NATIVE,              // endianness
    797                 C2PlanarLayout::PLANE_V,          // rootIx
    798                 0,                                // offset
    799             };
    800             // handle interleaved formats
    801             intptr_t uvOffset = addr[C2PlanarLayout::PLANE_V] - addr[C2PlanarLayout::PLANE_U];
    802             if (uvOffset > 0 && uvOffset < (intptr_t)ycbcrLayout.chromaStep) {
    803                 layout->rootPlanes = 2;
    804                 layout->planes[C2PlanarLayout::PLANE_V].rootIx = C2PlanarLayout::PLANE_U;
    805                 layout->planes[C2PlanarLayout::PLANE_V].offset = uvOffset;
    806             } else if (uvOffset < 0 && uvOffset > -(intptr_t)ycbcrLayout.chromaStep) {
    807                 layout->rootPlanes = 2;
    808                 layout->planes[C2PlanarLayout::PLANE_U].rootIx = C2PlanarLayout::PLANE_V;
    809                 layout->planes[C2PlanarLayout::PLANE_U].offset = -uvOffset;
    810             }
    811             break;
    812         }
    813     }
    814     mLocked = true;
    815 
    816     return C2_OK;
    817 }
    818 
    819 c2_status_t C2AllocationGralloc::unmap(
    820         uint8_t **addr, C2Rect rect, C2Fence *fence /* nullable */) {
    821     // TODO: check addr and size, use fence
    822     (void)addr;
    823     (void)rect;
    824 
    825     std::lock_guard<std::mutex> lock(mMappedLock);
    826     c2_status_t err = C2_OK;
    827     if (mMapper2) {
    828         if (!mMapper2->unlock(
    829                 const_cast<native_handle_t *>(mBuffer),
    830                 [&err, &fence](const auto &maperr, const auto &releaseFence) {
    831                     // TODO
    832                     (void) fence;
    833                     (void) releaseFence;
    834                     err = maperr2error(maperr);
    835                     if (err == C2_OK) {
    836                         // TODO: fence
    837                     }
    838                 }).isOk()) {
    839             ALOGE("failed transaction: unlock");
    840             return C2_CORRUPTED;
    841         }
    842     } else {
    843         if (!mMapper3->unlock(
    844                 const_cast<native_handle_t *>(mBuffer),
    845                 [&err, &fence](const auto &maperr, const auto &releaseFence) {
    846                     // TODO
    847                     (void) fence;
    848                     (void) releaseFence;
    849                     err = maperr2error(maperr);
    850                     if (err == C2_OK) {
    851                         // TODO: fence
    852                     }
    853                 }).isOk()) {
    854             ALOGE("failed transaction: unlock (@3.0)");
    855             return C2_CORRUPTED;
    856         }
    857     }
    858     if (err == C2_OK) {
    859         mLocked = false;
    860     }
    861     return err;
    862 }
    863 
    864 bool C2AllocationGralloc::equals(const std::shared_ptr<const C2GraphicAllocation> &other) const {
    865     return other && other->handle() == handle();
    866 }
    867 
    868 /* ===================================== GRALLOC ALLOCATOR ==================================== */
    869 class C2AllocatorGralloc::Impl {
    870 public:
    871     Impl(id_t id, bool bufferQueue);
    872 
    873     id_t getId() const {
    874         return mTraits->id;
    875     }
    876 
    877     C2String getName() const {
    878         return mTraits->name;
    879     }
    880 
    881     std::shared_ptr<const C2Allocator::Traits> getTraits() const {
    882         return mTraits;
    883     }
    884 
    885     c2_status_t newGraphicAllocation(
    886             uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
    887             std::shared_ptr<C2GraphicAllocation> *allocation);
    888 
    889     c2_status_t priorGraphicAllocation(
    890             const C2Handle *handle,
    891             std::shared_ptr<C2GraphicAllocation> *allocation);
    892 
    893     c2_status_t status() const { return mInit; }
    894 
    895 private:
    896     std::shared_ptr<C2Allocator::Traits> mTraits;
    897     c2_status_t mInit;
    898     sp<IAllocator2> mAllocator2;
    899     sp<IMapper2> mMapper2;
    900     sp<IAllocator3> mAllocator3;
    901     sp<IMapper3> mMapper3;
    902     const bool mBufferQueue;
    903 };
    904 
    905 void _UnwrapNativeCodec2GrallocMetadata(
    906         const C2Handle *const handle,
    907         uint32_t *width, uint32_t *height, uint32_t *format,uint64_t *usage, uint32_t *stride,
    908         uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) {
    909     (void)C2HandleGralloc::Import(handle, width, height, format, usage, stride,
    910                                   generation, igbp_id, igbp_slot);
    911 }
    912 
    913 C2AllocatorGralloc::Impl::Impl(id_t id, bool bufferQueue)
    914     : mInit(C2_OK), mBufferQueue(bufferQueue) {
    915     // TODO: get this from allocator
    916     C2MemoryUsage minUsage = { 0, 0 }, maxUsage = { ~(uint64_t)0, ~(uint64_t)0 };
    917     Traits traits = { "android.allocator.gralloc", id, C2Allocator::GRAPHIC, minUsage, maxUsage };
    918     mTraits = std::make_shared<C2Allocator::Traits>(traits);
    919 
    920     // gralloc allocator is a singleton, so all objects share a global service
    921     mAllocator3 = IAllocator3::getService();
    922     mMapper3 = IMapper3::getService();
    923     if (!mAllocator3 || !mMapper3) {
    924         mAllocator3 = nullptr;
    925         mMapper3 = nullptr;
    926         mAllocator2 = IAllocator2::getService();
    927         mMapper2 = IMapper2::getService();
    928         if (!mAllocator2 || !mMapper2) {
    929             mAllocator2 = nullptr;
    930             mMapper2 = nullptr;
    931             mInit = C2_CORRUPTED;
    932         }
    933     }
    934 }
    935 
    936 c2_status_t C2AllocatorGralloc::Impl::newGraphicAllocation(
    937         uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
    938         std::shared_ptr<C2GraphicAllocation> *allocation) {
    939     uint64_t grallocUsage = static_cast<C2AndroidMemoryUsage>(usage).asGrallocUsage();
    940     ALOGV("allocating buffer with usage %#llx => %#llx",
    941           (long long)usage.expected, (long long)grallocUsage);
    942 
    943     c2_status_t err = C2_OK;
    944     hidl_handle buffer{};
    945 
    946     if (mMapper2) {
    947         BufferDescriptorInfo2 info = {
    948             {
    949                 width,
    950                 height,
    951                 1u,  // layerCount
    952                 PixelFormat2(format),
    953                 grallocUsage,
    954             },
    955             0u,  // stride placeholder
    956         };
    957         BufferDescriptor2 desc;
    958         if (!mMapper2->createDescriptor(
    959                 info.mapperInfo, [&err, &desc](const auto &maperr, const auto &descriptor) {
    960                     err = maperr2error(maperr);
    961                     if (err == C2_OK) {
    962                         desc = descriptor;
    963                     }
    964                 }).isOk()) {
    965             ALOGE("failed transaction: createDescriptor");
    966             return C2_CORRUPTED;
    967         }
    968         if (err != C2_OK) {
    969             return err;
    970         }
    971 
    972         // IAllocator shares IMapper error codes.
    973         if (!mAllocator2->allocate(
    974                 desc,
    975                 1u,
    976                 [&err, &buffer, &info](const auto &maperr, const auto &stride, auto &buffers) {
    977                     err = maperr2error(maperr);
    978                     if (err != C2_OK) {
    979                         return;
    980                     }
    981                     if (buffers.size() != 1u) {
    982                         err = C2_CORRUPTED;
    983                         return;
    984                     }
    985                     info.stride = stride;
    986                     buffer = buffers[0];
    987                 }).isOk()) {
    988             ALOGE("failed transaction: allocate");
    989             return C2_CORRUPTED;
    990         }
    991         if (err != C2_OK) {
    992             return err;
    993         }
    994         allocation->reset(new C2AllocationGralloc(
    995                 info, mMapper2, buffer,
    996                 C2HandleGralloc::WrapAndMoveNativeHandle(
    997                         buffer.getNativeHandle(),
    998                         width, height,
    999                         format, grallocUsage, info.stride,
   1000                         0, 0, mBufferQueue ? ~0 : 0),
   1001                 mTraits->id));
   1002         return C2_OK;
   1003     } else {
   1004         BufferDescriptorInfo3 info = {
   1005             {
   1006                 width,
   1007                 height,
   1008                 1u,  // layerCount
   1009                 PixelFormat3(format),
   1010                 grallocUsage,
   1011             },
   1012             0u,  // stride placeholder
   1013         };
   1014         BufferDescriptor3 desc;
   1015         if (!mMapper3->createDescriptor(
   1016                 info.mapperInfo, [&err, &desc](const auto &maperr, const auto &descriptor) {
   1017                     err = maperr2error(maperr);
   1018                     if (err == C2_OK) {
   1019                         desc = descriptor;
   1020                     }
   1021                 }).isOk()) {
   1022             ALOGE("failed transaction: createDescriptor");
   1023             return C2_CORRUPTED;
   1024         }
   1025         if (err != C2_OK) {
   1026             return err;
   1027         }
   1028 
   1029         // IAllocator shares IMapper error codes.
   1030         if (!mAllocator3->allocate(
   1031                 desc,
   1032                 1u,
   1033                 [&err, &buffer, &info](const auto &maperr, const auto &stride, auto &buffers) {
   1034                     err = maperr2error(maperr);
   1035                     if (err != C2_OK) {
   1036                         return;
   1037                     }
   1038                     if (buffers.size() != 1u) {
   1039                         err = C2_CORRUPTED;
   1040                         return;
   1041                     }
   1042                     info.stride = stride;
   1043                     buffer = buffers[0];
   1044                 }).isOk()) {
   1045             ALOGE("failed transaction: allocate");
   1046             return C2_CORRUPTED;
   1047         }
   1048         if (err != C2_OK) {
   1049             return err;
   1050         }
   1051         allocation->reset(new C2AllocationGralloc(
   1052                 info, mMapper3, buffer,
   1053                 C2HandleGralloc::WrapAndMoveNativeHandle(
   1054                         buffer.getNativeHandle(),
   1055                         width, height,
   1056                         format, grallocUsage, info.stride,
   1057                         0, 0, mBufferQueue ? ~0 : 0),
   1058                 mTraits->id));
   1059         return C2_OK;
   1060     }
   1061 }
   1062 
   1063 c2_status_t C2AllocatorGralloc::Impl::priorGraphicAllocation(
   1064         const C2Handle *handle,
   1065         std::shared_ptr<C2GraphicAllocation> *allocation) {
   1066     if (mMapper2) {
   1067         BufferDescriptorInfo2 info;
   1068         info.mapperInfo.layerCount = 1u;
   1069         uint32_t generation;
   1070         uint64_t igbp_id;
   1071         uint32_t igbp_slot;
   1072         const C2HandleGralloc *grallocHandle = C2HandleGralloc::Import(
   1073                 handle,
   1074                 &info.mapperInfo.width, &info.mapperInfo.height,
   1075                 (uint32_t *)&info.mapperInfo.format,
   1076                 (uint64_t *)&info.mapperInfo.usage,
   1077                 &info.stride,
   1078                 &generation, &igbp_id, &igbp_slot);
   1079         if (grallocHandle == nullptr) {
   1080             return C2_BAD_VALUE;
   1081         }
   1082 
   1083         hidl_handle hidlHandle;
   1084         hidlHandle.setTo(C2HandleGralloc::UnwrapNativeHandle(grallocHandle), true);
   1085 
   1086         allocation->reset(new C2AllocationGralloc(
   1087                 info, mMapper2, hidlHandle, grallocHandle, mTraits->id));
   1088         return C2_OK;
   1089     } else {
   1090         BufferDescriptorInfo3 info;
   1091         info.mapperInfo.layerCount = 1u;
   1092         uint32_t generation;
   1093         uint64_t igbp_id;
   1094         uint32_t igbp_slot;
   1095         const C2HandleGralloc *grallocHandle = C2HandleGralloc::Import(
   1096                 handle,
   1097                 &info.mapperInfo.width, &info.mapperInfo.height,
   1098                 (uint32_t *)&info.mapperInfo.format,
   1099                 (uint64_t *)&info.mapperInfo.usage,
   1100                 &info.stride,
   1101                 &generation, &igbp_id, &igbp_slot);
   1102         if (grallocHandle == nullptr) {
   1103             return C2_BAD_VALUE;
   1104         }
   1105 
   1106         hidl_handle hidlHandle;
   1107         hidlHandle.setTo(C2HandleGralloc::UnwrapNativeHandle(grallocHandle), true);
   1108 
   1109         allocation->reset(new C2AllocationGralloc(
   1110                 info, mMapper3, hidlHandle, grallocHandle, mTraits->id));
   1111         return C2_OK;
   1112     }
   1113 }
   1114 
   1115 C2AllocatorGralloc::C2AllocatorGralloc(id_t id, bool bufferQueue)
   1116         : mImpl(new Impl(id, bufferQueue)) {}
   1117 
   1118 C2AllocatorGralloc::~C2AllocatorGralloc() { delete mImpl; }
   1119 
   1120 C2Allocator::id_t C2AllocatorGralloc::getId() const {
   1121     return mImpl->getId();
   1122 }
   1123 
   1124 C2String C2AllocatorGralloc::getName() const {
   1125     return mImpl->getName();
   1126 }
   1127 
   1128 std::shared_ptr<const C2Allocator::Traits> C2AllocatorGralloc::getTraits() const {
   1129     return mImpl->getTraits();
   1130 }
   1131 
   1132 c2_status_t C2AllocatorGralloc::newGraphicAllocation(
   1133         uint32_t width, uint32_t height, uint32_t format, C2MemoryUsage usage,
   1134         std::shared_ptr<C2GraphicAllocation> *allocation) {
   1135     return mImpl->newGraphicAllocation(width, height, format, usage, allocation);
   1136 }
   1137 
   1138 c2_status_t C2AllocatorGralloc::priorGraphicAllocation(
   1139         const C2Handle *handle,
   1140         std::shared_ptr<C2GraphicAllocation> *allocation) {
   1141     return mImpl->priorGraphicAllocation(handle, allocation);
   1142 }
   1143 
   1144 c2_status_t C2AllocatorGralloc::status() const {
   1145     return mImpl->status();
   1146 }
   1147 
   1148 bool C2AllocatorGralloc::isValid(const C2Handle* const o) {
   1149     return C2HandleGralloc::isValid(o);
   1150 }
   1151 
   1152 } // namespace android
   1153