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 
FromGrallocUsage(uint64_t usage)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 
asGrallocUsage() const56 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 ==================================== */
maperr2error(Error2 maperr)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 
maperr2error(Error3 maperr)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 
native_handle_is_invalid(const native_handle_t * const handle)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
getExtraData(const C2Handle * const handle)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
getExtraData(C2Handle * const handle)163     ExtraData *getExtraData(C2Handle *const handle) {
164         return const_cast<ExtraData *>(getExtraData(const_cast<const C2Handle *const>(handle)));
165     }
166 
167 public:
getIgbpData(uint32_t * generation,uint64_t * igbp_id,uint32_t * igbp_slot) const168     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 
isValid(const C2Handle * const o)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 
WrapAndMoveNativeHandle(const native_handle_t * const handle,uint32_t width,uint32_t height,uint32_t format,uint64_t usage,uint32_t stride,uint32_t generation,uint64_t igbp_id=0,uint32_t igbp_slot=0)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 
WrapNativeHandle(const native_handle_t * const handle,uint32_t width,uint32_t height,uint32_t format,uint64_t usage,uint32_t stride,uint32_t generation,uint64_t igbp_id=0,uint32_t igbp_slot=0)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 
MigrateNativeHandle(native_handle_t * handle,uint32_t generation,uint64_t igbp_id,uint32_t igbp_slot)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 
UnwrapNativeHandle(const C2Handle * const handle)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 
Import(const C2Handle * const handle,uint32_t * width,uint32_t * height,uint32_t * format,uint64_t * usage,uint32_t * stride,uint32_t * generation,uint64_t * igbp_id,uint32_t * igbp_slot)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 
UnwrapNativeCodec2GrallocHandle(const C2Handle * const handle)278 native_handle_t *UnwrapNativeCodec2GrallocHandle(const C2Handle *const handle) {
279     return C2HandleGralloc::UnwrapNativeHandle(handle);
280 }
281 
WrapNativeCodec2GrallocHandle(const native_handle_t * const handle,uint32_t width,uint32_t height,uint32_t format,uint64_t usage,uint32_t stride,uint32_t generation,uint64_t igbp_id,uint32_t igbp_slot)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 
MigrateNativeCodec2GrallocHandle(native_handle_t * handle,uint32_t generation,uint64_t igbp_id,uint32_t igbp_slot)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;
getAllocatorId() const306     virtual C2Allocator::id_t getAllocatorId() const override { return mAllocatorId; }
handle() const307     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 
C2AllocationGralloc(const BufferDescriptorInfo2 & info,const sp<IMapper2> & mapper,hidl_handle & hidlHandle,const C2HandleGralloc * const handle,C2Allocator::id_t allocatorId)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 
C2AllocationGralloc(const BufferDescriptorInfo3 & info,const sp<IMapper3> & mapper,hidl_handle & hidlHandle,const C2HandleGralloc * const handle,C2Allocator::id_t allocatorId)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 
~C2AllocationGralloc()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 
map(C2Rect rect,C2MemoryUsage usage,C2Fence * fence,C2PlanarLayout * layout,uint8_t ** addr)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 
unmap(uint8_t ** addr,C2Rect rect,C2Fence * fence)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 
equals(const std::shared_ptr<const C2GraphicAllocation> & other) const864 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 
getId() const873     id_t getId() const {
874         return mTraits->id;
875     }
876 
getName() const877     C2String getName() const {
878         return mTraits->name;
879     }
880 
getTraits() const881     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 
status() const893     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 
_UnwrapNativeCodec2GrallocMetadata(const C2Handle * const handle,uint32_t * width,uint32_t * height,uint32_t * format,uint64_t * usage,uint32_t * stride,uint32_t * generation,uint64_t * igbp_id,uint32_t * igbp_slot)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 
Impl(id_t id,bool bufferQueue)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 
newGraphicAllocation(uint32_t width,uint32_t height,uint32_t format,const C2MemoryUsage & usage,std::shared_ptr<C2GraphicAllocation> * allocation)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 
priorGraphicAllocation(const C2Handle * handle,std::shared_ptr<C2GraphicAllocation> * allocation)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 
C2AllocatorGralloc(id_t id,bool bufferQueue)1115 C2AllocatorGralloc::C2AllocatorGralloc(id_t id, bool bufferQueue)
1116         : mImpl(new Impl(id, bufferQueue)) {}
1117 
~C2AllocatorGralloc()1118 C2AllocatorGralloc::~C2AllocatorGralloc() { delete mImpl; }
1119 
getId() const1120 C2Allocator::id_t C2AllocatorGralloc::getId() const {
1121     return mImpl->getId();
1122 }
1123 
getName() const1124 C2String C2AllocatorGralloc::getName() const {
1125     return mImpl->getName();
1126 }
1127 
getTraits() const1128 std::shared_ptr<const C2Allocator::Traits> C2AllocatorGralloc::getTraits() const {
1129     return mImpl->getTraits();
1130 }
1131 
newGraphicAllocation(uint32_t width,uint32_t height,uint32_t format,C2MemoryUsage usage,std::shared_ptr<C2GraphicAllocation> * allocation)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 
priorGraphicAllocation(const C2Handle * handle,std::shared_ptr<C2GraphicAllocation> * allocation)1138 c2_status_t C2AllocatorGralloc::priorGraphicAllocation(
1139         const C2Handle *handle,
1140         std::shared_ptr<C2GraphicAllocation> *allocation) {
1141     return mImpl->priorGraphicAllocation(handle, allocation);
1142 }
1143 
status() const1144 c2_status_t C2AllocatorGralloc::status() const {
1145     return mImpl->status();
1146 }
1147 
isValid(const C2Handle * const o)1148 bool C2AllocatorGralloc::isValid(const C2Handle* const o) {
1149     return C2HandleGralloc::isValid(o);
1150 }
1151 
1152 } // namespace android
1153