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 <mutex>
22 
23 #include <aidl/android/hardware/graphics/common/PlaneLayoutComponentType.h>
24 #include <android/hardware/graphics/common/1.2/types.h>
25 #include <cutils/native_handle.h>
26 #include <drm/drm_fourcc.h>
27 #include <gralloctypes/Gralloc4.h>
28 #include <hardware/gralloc.h>
29 #include <ui/GraphicBufferAllocator.h>
30 #include <ui/GraphicBufferMapper.h>
31 #include <ui/Rect.h>
32 
33 #include <C2AllocatorGralloc.h>
34 #include <C2Buffer.h>
35 #include <C2Debug.h>
36 #include <C2PlatformSupport.h>
37 
38 using ::android::hardware::hidl_handle;
39 using PixelFormat4 = ::android::hardware::graphics::common::V1_2::PixelFormat;
40 
41 namespace android {
42 
43 namespace /* unnamed */ {
44     enum : uint64_t {
45         /**
46          * Usage mask that is passed through from gralloc to Codec 2.0 usage.
47          */
48         PASSTHROUGH_USAGE_MASK =
49             ~static_cast<uint64_t>(GRALLOC_USAGE_SW_READ_MASK |
50                                    GRALLOC_USAGE_SW_WRITE_MASK |
51                                    GRALLOC_USAGE_PROTECTED)
52     };
53 
54     // verify that passthrough mask is within the platform mask
55     static_assert((~C2MemoryUsage::PLATFORM_MASK & PASSTHROUGH_USAGE_MASK) == 0, "");
56 } // unnamed
57 
isAtLeastT()58 static bool isAtLeastT() {
59     return android_get_device_api_level() >= __ANDROID_API_T__;
60 }
61 
FromGrallocUsage(uint64_t usage)62 C2MemoryUsage C2AndroidMemoryUsage::FromGrallocUsage(uint64_t usage) {
63     // gralloc does not support WRITE_PROTECTED
64     return C2MemoryUsage(
65             ((usage & GRALLOC_USAGE_SW_READ_MASK) ? C2MemoryUsage::CPU_READ : 0) |
66             ((usage & GRALLOC_USAGE_SW_WRITE_MASK) ? C2MemoryUsage::CPU_WRITE : 0) |
67             ((usage & GRALLOC_USAGE_PROTECTED) ? C2MemoryUsage::READ_PROTECTED : 0) |
68             (usage & PASSTHROUGH_USAGE_MASK));
69 }
70 
asGrallocUsage() const71 uint64_t C2AndroidMemoryUsage::asGrallocUsage() const {
72     // gralloc does not support WRITE_PROTECTED
73     return (((expected & C2MemoryUsage::CPU_READ) ? GRALLOC_USAGE_SW_READ_OFTEN : 0) |
74             ((expected & C2MemoryUsage::CPU_WRITE) ? GRALLOC_USAGE_SW_WRITE_OFTEN : 0) |
75             ((expected & C2MemoryUsage::READ_PROTECTED) ? GRALLOC_USAGE_PROTECTED : 0) |
76             (expected & PASSTHROUGH_USAGE_MASK));
77 }
78 
79 namespace /* unnamed */ {
80 
81 /* ===================================== GRALLOC ALLOCATION ==================================== */
native_handle_is_invalid(const native_handle_t * const handle)82 bool native_handle_is_invalid(const native_handle_t *const handle) {
83     // perform basic validation of a native handle
84     if (handle == nullptr) {
85         // null handle is considered valid
86         return false;
87     }
88     return ((size_t)handle->version != sizeof(native_handle_t) ||
89             handle->numFds < 0 ||
90             handle->numInts < 0 ||
91             // for sanity assume handles must occupy less memory than INT_MAX bytes
92             handle->numFds > int((INT_MAX - handle->version) / sizeof(int)) - handle->numInts);
93 }
94 
95 class C2HandleGralloc : public C2Handle {
96 private:
97     struct ExtraData {
98         uint32_t width;
99         uint32_t height;
100         uint32_t format;
101         uint32_t usage_lo;
102         uint32_t usage_hi;
103         uint32_t stride;
104         uint32_t generation;
105         uint32_t igbp_id_lo;
106         uint32_t igbp_id_hi;
107         uint32_t igbp_slot;
108         uint32_t magic;
109     };
110 
111     enum {
112         NUM_INTS = sizeof(ExtraData) / sizeof(int),
113     };
114     const static uint32_t MAGIC = '\xc2gr\x00';
115 
116     static
GetExtraData(const C2Handle * const handle)117     const ExtraData* GetExtraData(const C2Handle *const handle) {
118         if (handle == nullptr
119                 || native_handle_is_invalid(handle)
120                 || handle->numInts < NUM_INTS) {
121             return nullptr;
122         }
123         return reinterpret_cast<const ExtraData*>(
124                 &handle->data[handle->numFds + handle->numInts - NUM_INTS]);
125     }
126 
127     static
GetExtraData(C2Handle * const handle)128     ExtraData *GetExtraData(C2Handle *const handle) {
129         return const_cast<ExtraData *>(GetExtraData(const_cast<const C2Handle *const>(handle)));
130     }
131 
132 public:
getIgbpData(uint32_t * generation,uint64_t * igbp_id,uint32_t * igbp_slot) const133     void getIgbpData(uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) const {
134         const ExtraData *ed = GetExtraData(this);
135         *generation = ed->generation;
136         *igbp_id = unsigned(ed->igbp_id_lo) | uint64_t(unsigned(ed->igbp_id_hi)) << 32;
137         *igbp_slot = ed->igbp_slot;
138     }
139 
IsValid(const C2Handle * const o)140     static bool IsValid(const C2Handle *const o) {
141         if (o == nullptr) { // null handle is always valid
142             return true;
143         }
144         const ExtraData *xd = GetExtraData(o);
145         // we cannot validate width/height/format/usage without accessing gralloc driver
146         return xd != nullptr && xd->magic == MAGIC;
147     }
148 
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)149     static C2HandleGralloc* WrapAndMoveNativeHandle(
150             const native_handle_t *const handle,
151             uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
152             uint32_t stride, uint32_t generation, uint64_t igbp_id = 0, uint32_t igbp_slot = 0) {
153         //CHECK(handle != nullptr);
154         if (native_handle_is_invalid(handle) ||
155             handle->numInts > int((INT_MAX - handle->version) / sizeof(int)) - NUM_INTS - handle->numFds) {
156             return nullptr;
157         }
158         ExtraData xd = {
159             width, height, format, uint32_t(usage & 0xFFFFFFFF), uint32_t(usage >> 32),
160             stride, generation, uint32_t(igbp_id & 0xFFFFFFFF), uint32_t(igbp_id >> 32),
161             igbp_slot, MAGIC
162         };
163         native_handle_t *res = native_handle_create(handle->numFds, handle->numInts + NUM_INTS);
164         if (res != nullptr) {
165             memcpy(&res->data, &handle->data, sizeof(int) * (handle->numFds + handle->numInts));
166             *GetExtraData(res) = xd;
167         }
168         return reinterpret_cast<C2HandleGralloc *>(res);
169     }
170 
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)171     static C2HandleGralloc* WrapNativeHandle(
172             const native_handle_t *const handle,
173             uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
174             uint32_t stride, uint32_t generation, uint64_t igbp_id = 0, uint32_t igbp_slot = 0) {
175         if (handle == nullptr) {
176             return nullptr;
177         }
178         native_handle_t *clone = native_handle_clone(handle);
179         if (clone == nullptr) {
180             return nullptr;
181         }
182         C2HandleGralloc *res = WrapAndMoveNativeHandle(
183                 clone, width, height, format, usage, stride, generation, igbp_id, igbp_slot);
184         if (res == nullptr) {
185             native_handle_close(clone);
186         }
187         native_handle_delete(clone);
188         return res;
189     }
190 
getPixelFormat(const C2Handle * const handle)191     static uint32_t getPixelFormat(const C2Handle *const handle) {
192         if (handle == nullptr) {
193             return 0;
194         }
195         const ExtraData *xd = GetExtraData(handle);
196         return xd->format;
197     }
198 
MigrateNativeHandle(native_handle_t * handle,uint32_t generation,uint64_t igbp_id,uint32_t igbp_slot)199     static bool MigrateNativeHandle(
200             native_handle_t *handle,
201             uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
202         if (handle == nullptr || !IsValid(handle)) {
203             return false;
204         }
205         ExtraData *ed = GetExtraData(handle);
206         if (!ed) return false;
207         ed->generation = generation;
208         ed->igbp_id_lo = uint32_t(igbp_id & 0xFFFFFFFF);
209         ed->igbp_id_hi = uint32_t(igbp_id >> 32);
210         ed->igbp_slot = igbp_slot;
211         return true;
212     }
213 
214 
UnwrapNativeHandle(const C2Handle * const handle)215     static native_handle_t* UnwrapNativeHandle(
216             const C2Handle *const handle) {
217         const ExtraData *xd = GetExtraData(handle);
218         if (xd == nullptr || xd->magic != MAGIC) {
219             return nullptr;
220         }
221         native_handle_t *res = native_handle_create(handle->numFds, handle->numInts - NUM_INTS);
222         if (res != nullptr) {
223             memcpy(&res->data, &handle->data, sizeof(int) * (res->numFds + res->numInts));
224         }
225         return res;
226     }
227 
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)228     static const C2HandleGralloc* Import(
229             const C2Handle *const handle,
230             uint32_t *width, uint32_t *height, uint32_t *format,
231             uint64_t *usage, uint32_t *stride,
232             uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) {
233         const ExtraData *xd = GetExtraData(handle);
234         if (xd == nullptr) {
235             return nullptr;
236         }
237         *width = xd->width;
238         *height = xd->height;
239         *format = xd->format;
240         *usage = xd->usage_lo | (uint64_t(xd->usage_hi) << 32);
241         *stride = xd->stride;
242         *generation = xd->generation;
243         *igbp_id = xd->igbp_id_lo | (uint64_t(xd->igbp_id_hi) << 32);
244         *igbp_slot = xd->igbp_slot;
245         return reinterpret_cast<const C2HandleGralloc *>(handle);
246     }
247 };
248 
249 class C2HandleAhwb : public C2Handle {
250 private:
251     // TODO: remove extradata and use AHardwareBuffer directly.
252     struct ExtraData {
253         uint32_t width;
254         uint32_t height;
255         uint32_t format;
256         uint32_t usage_lo;
257         uint32_t usage_hi;
258         uint32_t stride;
259         uint32_t origId_lo;
260         uint32_t origId_hi;
261         uint32_t magic;
262     };
263 
264     enum {
265         NUM_INTS = sizeof(ExtraData) / sizeof(int),
266     };
267     const static uint32_t MAGIC = '\xc2hw\x00';
268 
269     static
GetExtraData(const C2Handle * const handle)270     const ExtraData* GetExtraData(const C2Handle *const handle) {
271         if (handle == nullptr
272                 || native_handle_is_invalid(handle)
273                 || handle->numInts < NUM_INTS) {
274             return nullptr;
275         }
276         return reinterpret_cast<const ExtraData*>(
277                 &handle->data[handle->numFds + handle->numInts - NUM_INTS]);
278     }
279 
280     static
GetExtraData(C2Handle * const handle)281     ExtraData *GetExtraData(C2Handle *const handle) {
282         return const_cast<ExtraData *>(GetExtraData(const_cast<const C2Handle *const>(handle)));
283     }
284 
285 public:
getOrigId(uint64_t * origId) const286     void getOrigId(uint64_t *origId) const {
287         const ExtraData *ed = GetExtraData(this);
288         *origId = unsigned(ed->origId_lo) | uint64_t(unsigned(ed->origId_hi)) << 32;
289     }
290 
IsValid(const C2Handle * const o)291     static bool IsValid(const C2Handle *const o) {
292         if (o == nullptr) { // null handle is always valid
293             return true;
294         }
295         const ExtraData *xd = GetExtraData(o);
296         // we cannot validate width/height/format/usage without accessing gralloc driver
297         return xd != nullptr && xd->magic == MAGIC;
298     }
299 
WrapAndMoveNativeHandle(const native_handle_t * const handle,uint32_t width,uint32_t height,uint32_t format,uint64_t usage,uint32_t stride,uint64_t origId)300     static C2HandleAhwb* WrapAndMoveNativeHandle(
301             const native_handle_t *const handle,
302             uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
303             uint32_t stride, uint64_t origId) {
304         //CHECK(handle != nullptr);
305         if (native_handle_is_invalid(handle) || handle->numInts >
306                 int((INT_MAX - handle->version) / sizeof(int)) - NUM_INTS - handle->numFds) {
307             return nullptr;
308         }
309         ExtraData xd = {
310             width, height, format, uint32_t(usage & 0xFFFFFFFF), uint32_t(usage >> 32),
311             stride,  uint32_t(origId & 0xFFFFFFFF), uint32_t(origId >> 32), MAGIC
312         };
313         native_handle_t *res = native_handle_create(handle->numFds, handle->numInts + NUM_INTS);
314         if (res != nullptr) {
315             memcpy(&res->data, &handle->data, sizeof(int) * (handle->numFds + handle->numInts));
316             *GetExtraData(res) = xd;
317         }
318         return reinterpret_cast<C2HandleAhwb *>(res);
319     }
320 
getPixelFormat(const C2Handle * const handle)321     static uint32_t getPixelFormat(const C2Handle *const handle) {
322         if (handle == nullptr) {
323             return 0;
324         }
325         const ExtraData *xd = GetExtraData(handle);
326         return xd->format;
327     }
328 
WrapNativeHandle(const native_handle_t * const handle,uint32_t width,uint32_t height,uint32_t format,uint64_t usage,uint32_t stride,uint64_t origId)329     static C2HandleAhwb* WrapNativeHandle(
330             const native_handle_t *const handle,
331             uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
332             uint32_t stride, uint64_t origId) {
333         if (handle == nullptr) {
334             return nullptr;
335         }
336         native_handle_t *clone = native_handle_clone(handle);
337         if (clone == nullptr) {
338             return nullptr;
339         }
340         C2HandleAhwb *res = WrapAndMoveNativeHandle(
341                 clone, width, height, format, usage, stride, origId);
342         if (res == nullptr) {
343             native_handle_close(clone);
344         }
345         native_handle_delete(clone);
346         return res;
347     }
348 
UnwrapNativeHandle(const C2Handle * const handle)349     static native_handle_t* UnwrapNativeHandle(
350             const C2Handle *const handle) {
351         const ExtraData *xd = GetExtraData(handle);
352         if (xd == nullptr || xd->magic != MAGIC) {
353             return nullptr;
354         }
355         native_handle_t *res = native_handle_create(handle->numFds, handle->numInts - NUM_INTS);
356         if (res != nullptr) {
357             memcpy(&res->data, &handle->data, sizeof(int) * (res->numFds + res->numInts));
358         }
359         return res;
360     }
361 
Import(const C2Handle * const handle,uint32_t * width,uint32_t * height,uint32_t * format,uint64_t * usage,uint32_t * stride,uint64_t * origId)362     static const C2HandleAhwb* Import(
363             const C2Handle *const handle,
364             uint32_t *width, uint32_t *height, uint32_t *format,
365             uint64_t *usage, uint32_t *stride,
366             uint64_t *origId) {
367         const ExtraData *xd = GetExtraData(handle);
368         if (xd == nullptr) {
369             return nullptr;
370         }
371         *width = xd->width;
372         *height = xd->height;
373         *format = xd->format;
374         *usage = xd->usage_lo | (uint64_t(xd->usage_hi) << 32);
375         *stride = xd->stride;
376         *origId = xd->origId_lo | (uint64_t(xd->origId_hi) << 32);
377         return reinterpret_cast<const C2HandleAhwb *>(handle);
378     }
379 };
380 
381 static
Gralloc4Mapper_lock(native_handle_t * handle,uint64_t usage,const Rect & bounds,C2PlanarLayout * layout,uint8_t ** addr)382 c2_status_t Gralloc4Mapper_lock(native_handle_t *handle, uint64_t usage, const Rect& bounds,
383         C2PlanarLayout *layout, uint8_t **addr) {
384     GraphicBufferMapper &mapper = GraphicBufferMapper::get();
385 
386     std::vector<ui::PlaneLayout> planes;
387     // this method is only supported on Gralloc 4 or later
388     status_t err = mapper.getPlaneLayouts(handle, &planes);
389     if (err != NO_ERROR || planes.empty()) {
390         return C2_CANNOT_DO;
391     }
392 
393     uint8_t *pointer = nullptr;
394     err = mapper.lock(handle, usage, bounds, (void **)&pointer);
395     if (err != NO_ERROR || pointer == nullptr) {
396         return C2_CORRUPTED;
397     }
398 
399     using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
400     using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
401 
402     layout->type = C2PlanarLayout::TYPE_YUV;
403     layout->numPlanes = 0;
404     layout->rootPlanes = 0;
405 
406     for (const ui::PlaneLayout &plane : planes) {
407         layout->rootPlanes++;
408         uint32_t lastOffsetInBits = 0;
409         uint32_t rootIx = layout->numPlanes;
410 
411         for (const PlaneLayoutComponent &component : plane.components) {
412             if (!gralloc4::isStandardPlaneLayoutComponentType(component.type)) {
413                 mapper.unlock(handle);
414                 return C2_CANNOT_DO;
415             }
416 
417             uint32_t rightShiftBits = component.offsetInBits - lastOffsetInBits;
418             uint32_t allocatedDepthInBits = component.sizeInBits + rightShiftBits;
419             C2PlanarLayout::plane_index_t planeId;
420             C2PlaneInfo::channel_t channel;
421 
422             switch (static_cast<PlaneLayoutComponentType>(component.type.value)) {
423                 case PlaneLayoutComponentType::Y:
424                     planeId = C2PlanarLayout::PLANE_Y;
425                     channel = C2PlaneInfo::CHANNEL_Y;
426                     break;
427                 case PlaneLayoutComponentType::CB:
428                     planeId = C2PlanarLayout::PLANE_U;
429                     channel = C2PlaneInfo::CHANNEL_CB;
430                     break;
431                 case PlaneLayoutComponentType::CR:
432                     planeId = C2PlanarLayout::PLANE_V;
433                     channel = C2PlaneInfo::CHANNEL_CR;
434                     break;
435                 default:
436                     mapper.unlock(handle);
437                     return C2_CORRUPTED;
438             }
439 
440             addr[planeId] = pointer + plane.offsetInBytes + (component.offsetInBits / 8);
441             layout->planes[planeId] = {
442                 channel,                                                // channel
443                 static_cast<int32_t>(plane.sampleIncrementInBits / 8),  // colInc
444                 static_cast<int32_t>(plane.strideInBytes),              // rowInc
445                 static_cast<uint32_t>(plane.horizontalSubsampling),     // mColSampling
446                 static_cast<uint32_t>(plane.verticalSubsampling),       // mRowSampling
447                 allocatedDepthInBits,                                   // allocatedDepth (bits)
448                 static_cast<uint32_t>(component.sizeInBits),            // bitDepth (bits)
449                 rightShiftBits,                                         // rightShift (bits)
450                 C2PlaneInfo::NATIVE,                                    // endianness
451                 rootIx,                                                 // rootIx
452                 static_cast<uint32_t>(component.offsetInBits / 8),      // offset (bytes)
453             };
454 
455             layout->numPlanes++;
456             lastOffsetInBits = component.offsetInBits + component.sizeInBits;
457         }
458     }
459     return C2_OK;
460 }
461 
PopulatePlaneLayout(buffer_handle_t buffer,const Rect & rect,uint32_t format,uint64_t grallocUsage,uint32_t stride,C2PlanarLayout * layout,uint8_t ** addr)462 static c2_status_t PopulatePlaneLayout(
463         buffer_handle_t buffer,
464         const Rect &rect,
465         uint32_t format,
466         uint64_t grallocUsage,
467         uint32_t stride,
468         C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) {
469     // 'NATIVE' on Android means LITTLE_ENDIAN
470     constexpr C2PlaneInfo::endianness_t kEndianness = C2PlaneInfo::NATIVE;
471 
472     // Try to resolve IMPLEMENTATION_DEFINED format to accurate format if
473     // possible.
474     uint32_t fourCc;
475     if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED &&
476         !GraphicBufferMapper::get().getPixelFormatFourCC(buffer, &fourCc)) {
477         switch (fourCc)  {
478             case DRM_FORMAT_XBGR8888:
479                  format = static_cast<uint32_t>(PixelFormat4::RGBX_8888);
480                  break;
481             case DRM_FORMAT_ABGR8888:
482                  format = static_cast<uint32_t>(PixelFormat4::RGBA_8888);
483                  break;
484             default:
485                  break;
486         }
487     }
488 
489     switch (format) {
490         case static_cast<uint32_t>(PixelFormat4::RGBA_1010102): {
491             // TRICKY: this is used for media as YUV444 in the case when it is queued directly to a
492             // Surface. In all other cases it is RGBA. We don't know which case it is here, so
493             // default to YUV for now.
494             void *pointer = nullptr;
495             // TODO: fence
496             status_t err = GraphicBufferMapper::get().lock(
497                     const_cast<native_handle_t *>(buffer), grallocUsage, rect, &pointer);
498             if (err) {
499                 ALOGE("failed transaction: lock(RGBA_1010102)");
500                 return C2_CORRUPTED;
501             }
502             // treat as 32-bit values
503             addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)pointer;
504             addr[C2PlanarLayout::PLANE_U] = (uint8_t *)pointer;
505             addr[C2PlanarLayout::PLANE_V] = (uint8_t *)pointer;
506             addr[C2PlanarLayout::PLANE_A] = (uint8_t *)pointer;
507             layout->type = C2PlanarLayout::TYPE_YUVA;
508             layout->numPlanes = 4;
509             layout->rootPlanes = 1;
510             layout->planes[C2PlanarLayout::PLANE_Y] = {
511                 C2PlaneInfo::CHANNEL_Y,         // channel
512                 4,                              // colInc
513                 static_cast<int32_t>(4 * stride), // rowInc
514                 1,                              // mColSampling
515                 1,                              // mRowSampling
516                 32,                             // allocatedDepth
517                 10,                             // bitDepth
518                 10,                             // rightShift
519                 C2PlaneInfo::LITTLE_END,        // endianness
520                 C2PlanarLayout::PLANE_Y,        // rootIx
521                 0,                              // offset
522             };
523             layout->planes[C2PlanarLayout::PLANE_U] = {
524                 C2PlaneInfo::CHANNEL_CB,         // channel
525                 4,                              // colInc
526                 static_cast<int32_t>(4 * stride), // rowInc
527                 1,                              // mColSampling
528                 1,                              // mRowSampling
529                 32,                             // allocatedDepth
530                 10,                             // bitDepth
531                 0,                              // rightShift
532                 C2PlaneInfo::LITTLE_END,        // endianness
533                 C2PlanarLayout::PLANE_Y,        // rootIx
534                 0,                              // offset
535             };
536             layout->planes[C2PlanarLayout::PLANE_V] = {
537                 C2PlaneInfo::CHANNEL_CR,         // channel
538                 4,                              // colInc
539                 static_cast<int32_t>(4 * stride), // rowInc
540                 1,                              // mColSampling
541                 1,                              // mRowSampling
542                 32,                             // allocatedDepth
543                 10,                             // bitDepth
544                 20,                             // rightShift
545                 C2PlaneInfo::LITTLE_END,        // endianness
546                 C2PlanarLayout::PLANE_Y,        // rootIx
547                 0,                              // offset
548             };
549             layout->planes[C2PlanarLayout::PLANE_A] = {
550                 C2PlaneInfo::CHANNEL_A,         // channel
551                 4,                              // colInc
552                 static_cast<int32_t>(4 * stride), // rowInc
553                 1,                              // mColSampling
554                 1,                              // mRowSampling
555                 32,                             // allocatedDepth
556                 2,                              // bitDepth
557                 30,                             // rightShift
558                 C2PlaneInfo::LITTLE_END,        // endianness
559                 C2PlanarLayout::PLANE_Y,        // rootIx
560                 0,                              // offset
561             };
562             break;
563         }
564 
565         case static_cast<uint32_t>(PixelFormat4::RGBA_8888):
566             // TODO: alpha channel
567             // fall-through
568         case static_cast<uint32_t>(PixelFormat4::RGBX_8888): {
569             void *pointer = nullptr;
570             // TODO: fence
571             status_t err = GraphicBufferMapper::get().lock(
572                     const_cast<native_handle_t*>(buffer), grallocUsage, rect, &pointer);
573             if (err) {
574                 ALOGE("failed transaction: lock(RGBA_8888)");
575                 return C2_CORRUPTED;
576             }
577             addr[C2PlanarLayout::PLANE_R] = (uint8_t *)pointer;
578             addr[C2PlanarLayout::PLANE_G] = (uint8_t *)pointer + 1;
579             addr[C2PlanarLayout::PLANE_B] = (uint8_t *)pointer + 2;
580             layout->type = C2PlanarLayout::TYPE_RGB;
581             layout->numPlanes = 3;
582             layout->rootPlanes = 1;
583             layout->planes[C2PlanarLayout::PLANE_R] = {
584                 C2PlaneInfo::CHANNEL_R,         // channel
585                 4,                              // colInc
586                 static_cast<int32_t>(4 * stride), // rowInc
587                 1,                              // mColSampling
588                 1,                              // mRowSampling
589                 8,                              // allocatedDepth
590                 8,                              // bitDepth
591                 0,                              // rightShift
592                 C2PlaneInfo::NATIVE,            // endianness
593                 C2PlanarLayout::PLANE_R,        // rootIx
594                 0,                              // offset
595             };
596             layout->planes[C2PlanarLayout::PLANE_G] = {
597                 C2PlaneInfo::CHANNEL_G,         // channel
598                 4,                              // colInc
599                 static_cast<int32_t>(4 * stride), // rowInc
600                 1,                              // mColSampling
601                 1,                              // mRowSampling
602                 8,                              // allocatedDepth
603                 8,                              // bitDepth
604                 0,                              // rightShift
605                 C2PlaneInfo::NATIVE,            // endianness
606                 C2PlanarLayout::PLANE_R,        // rootIx
607                 1,                              // offset
608             };
609             layout->planes[C2PlanarLayout::PLANE_B] = {
610                 C2PlaneInfo::CHANNEL_B,         // channel
611                 4,                              // colInc
612                 static_cast<int32_t>(4 * stride), // rowInc
613                 1,                              // mColSampling
614                 1,                              // mRowSampling
615                 8,                              // allocatedDepth
616                 8,                              // bitDepth
617                 0,                              // rightShift
618                 C2PlaneInfo::NATIVE,            // endianness
619                 C2PlanarLayout::PLANE_R,        // rootIx
620                 2,                              // offset
621             };
622             break;
623         }
624 
625         case static_cast<uint32_t>(PixelFormat4::BLOB): {
626             void *pointer = nullptr;
627             // TODO: fence
628             status_t err = GraphicBufferMapper::get().lock(
629                     const_cast<native_handle_t*>(buffer), grallocUsage, rect, &pointer);
630             if (err) {
631                 ALOGE("failed transaction: lock(BLOB)");
632                 return C2_CORRUPTED;
633             }
634             *addr = (uint8_t *)pointer;
635             break;
636         }
637 
638         case static_cast<uint32_t>(PixelFormat4::YCBCR_422_SP):
639             // fall-through
640         case static_cast<uint32_t>(PixelFormat4::YCRCB_420_SP):
641             // fall-through
642         case static_cast<uint32_t>(PixelFormat4::YCBCR_422_I):
643             // fall-through
644         case static_cast<uint32_t>(PixelFormat4::YCBCR_420_888):
645             // fall-through
646         case static_cast<uint32_t>(PixelFormat4::YV12): {
647             android_ycbcr ycbcrLayout;
648 
649             status_t err = GraphicBufferMapper::get().lockYCbCr(
650                     const_cast<native_handle_t*>(buffer), grallocUsage, rect, &ycbcrLayout);
651             if (err) {
652                 ALOGE("failed transaction: lockYCbCr (err=%d)", err);
653                 return C2_CORRUPTED;
654             }
655             if (!ycbcrLayout.y || !ycbcrLayout.cb || !ycbcrLayout.cr
656                     || ycbcrLayout.ystride == 0
657                     || ycbcrLayout.cstride == 0
658                     || ycbcrLayout.chroma_step == 0) {
659                 ALOGE("invalid layout: lockYCbCr (y=%s cb=%s cr=%s "
660                         "ystride=%zu cstride=%zu chroma_step=%zu)",
661                         ycbcrLayout.y ? "(non-null)" : "(null)",
662                         ycbcrLayout.cb ? "(non-null)" : "(null)",
663                         ycbcrLayout.cr ? "(non-null)" : "(null)",
664                         ycbcrLayout.ystride, ycbcrLayout.cstride, ycbcrLayout.chroma_step);
665                 return C2_CORRUPTED;
666             }
667 
668             addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)ycbcrLayout.y;
669             addr[C2PlanarLayout::PLANE_U] = (uint8_t *)ycbcrLayout.cb;
670             addr[C2PlanarLayout::PLANE_V] = (uint8_t *)ycbcrLayout.cr;
671             layout->type = C2PlanarLayout::TYPE_YUV;
672             layout->numPlanes = 3;
673             layout->rootPlanes = 3;
674             layout->planes[C2PlanarLayout::PLANE_Y] = {
675                 C2PlaneInfo::CHANNEL_Y,         // channel
676                 1,                              // colInc
677                 (int32_t)ycbcrLayout.ystride,   // rowInc
678                 1,                              // mColSampling
679                 1,                              // mRowSampling
680                 8,                              // allocatedDepth
681                 8,                              // bitDepth
682                 0,                              // rightShift
683                 C2PlaneInfo::NATIVE,            // endianness
684                 C2PlanarLayout::PLANE_Y,        // rootIx
685                 0,                              // offset
686             };
687             layout->planes[C2PlanarLayout::PLANE_U] = {
688                 C2PlaneInfo::CHANNEL_CB,          // channel
689                 (int32_t)ycbcrLayout.chroma_step, // colInc
690                 (int32_t)ycbcrLayout.cstride,     // rowInc
691                 2,                                // mColSampling
692                 2,                                // mRowSampling
693                 8,                                // allocatedDepth
694                 8,                                // bitDepth
695                 0,                                // rightShift
696                 C2PlaneInfo::NATIVE,              // endianness
697                 C2PlanarLayout::PLANE_U,          // rootIx
698                 0,                                // offset
699             };
700             layout->planes[C2PlanarLayout::PLANE_V] = {
701                 C2PlaneInfo::CHANNEL_CR,          // channel
702                 (int32_t)ycbcrLayout.chroma_step, // colInc
703                 (int32_t)ycbcrLayout.cstride,     // rowInc
704                 2,                                // mColSampling
705                 2,                                // mRowSampling
706                 8,                                // allocatedDepth
707                 8,                                // bitDepth
708                 0,                                // rightShift
709                 C2PlaneInfo::NATIVE,              // endianness
710                 C2PlanarLayout::PLANE_V,          // rootIx
711                 0,                                // offset
712             };
713             break;
714         }
715 
716         case static_cast<uint32_t>(PixelFormat4::YCBCR_P010): {
717             // In Android T, P010 is relaxed to allow arbitrary stride for the Y and UV planes,
718             // try locking with the gralloc4 mapper first.
719             c2_status_t status = Gralloc4Mapper_lock(
720                     const_cast<native_handle_t*>(buffer), grallocUsage, rect, layout, addr);
721             if (status == C2_OK) {
722                 break;
723             }
724 
725             void *pointer = nullptr;
726             status_t err = GraphicBufferMapper::get().lock(
727                     const_cast<native_handle_t *>(buffer), grallocUsage, rect, &pointer);
728             if (err) {
729                 ALOGE("failed transaction: lock(YCBCR_P010)");
730                 return C2_CORRUPTED;
731             }
732             addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)pointer;
733             addr[C2PlanarLayout::PLANE_U] = (uint8_t *)pointer + stride * 2 * rect.height();
734             addr[C2PlanarLayout::PLANE_V] = addr[C2PlanarLayout::PLANE_U] + 2;
735             layout->type = C2PlanarLayout::TYPE_YUV;
736             layout->numPlanes = 3;
737             layout->rootPlanes = 2;
738             layout->planes[C2PlanarLayout::PLANE_Y] = {
739                 C2PlaneInfo::CHANNEL_Y,         // channel
740                 2,                              // colInc
741                 static_cast<int32_t>(2 * stride), // rowInc
742                 1,                              // mColSampling
743                 1,                              // mRowSampling
744                 16,                             // allocatedDepth
745                 10,                             // bitDepth
746                 6,                              // rightShift
747                 kEndianness,                    // endianness
748                 C2PlanarLayout::PLANE_Y,        // rootIx
749                 0,                              // offset
750             };
751             layout->planes[C2PlanarLayout::PLANE_U] = {
752                 C2PlaneInfo::CHANNEL_CB,        // channel
753                 4,                              // colInc
754                 static_cast<int32_t>(2 * stride), // rowInc
755                 2,                              // mColSampling
756                 2,                              // mRowSampling
757                 16,                             // allocatedDepth
758                 10,                             // bitDepth
759                 6,                              // rightShift
760                 kEndianness,                    // endianness
761                 C2PlanarLayout::PLANE_U,        // rootIx
762                 0,                              // offset
763             };
764             layout->planes[C2PlanarLayout::PLANE_V] = {
765                 C2PlaneInfo::CHANNEL_CR,        // channel
766                 4,                              // colInc
767                 static_cast<int32_t>(2 * stride), // rowInc
768                 2,                              // mColSampling
769                 2,                              // mRowSampling
770                 16,                             // allocatedDepth
771                 10,                             // bitDepth
772                 6,                              // rightShift
773                 kEndianness,                    // endianness
774                 C2PlanarLayout::PLANE_U,        // rootIx
775                 2,                              // offset
776             };
777             break;
778         }
779 
780         default: {
781             // We don't know what it is, let's try to lock it with gralloc4
782             android_ycbcr ycbcrLayout;
783             if (isAtLeastT()) {
784                 c2_status_t status = Gralloc4Mapper_lock(
785                         const_cast<native_handle_t*>(buffer), grallocUsage, rect, layout, addr);
786                 if (status == C2_OK) {
787                     break;
788                 }
789             }
790 
791             // fallback to lockYCbCr
792             status_t err = GraphicBufferMapper::get().lockYCbCr(
793                     const_cast<native_handle_t*>(buffer), grallocUsage, rect, &ycbcrLayout);
794             if (err == OK && ycbcrLayout.y && ycbcrLayout.cb && ycbcrLayout.cr
795                     && ycbcrLayout.ystride > 0
796                     && ycbcrLayout.cstride > 0
797                     && ycbcrLayout.chroma_step > 0) {
798                 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)ycbcrLayout.y;
799                 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)ycbcrLayout.cb;
800                 addr[C2PlanarLayout::PLANE_V] = (uint8_t *)ycbcrLayout.cr;
801                 layout->type = C2PlanarLayout::TYPE_YUV;
802                 layout->numPlanes = 3;
803                 layout->rootPlanes = 3;
804                 layout->planes[C2PlanarLayout::PLANE_Y] = {
805                     C2PlaneInfo::CHANNEL_Y,         // channel
806                     1,                              // colInc
807                     (int32_t)ycbcrLayout.ystride,   // rowInc
808                     1,                              // mColSampling
809                     1,                              // mRowSampling
810                     8,                              // allocatedDepth
811                     8,                              // bitDepth
812                     0,                              // rightShift
813                     C2PlaneInfo::NATIVE,            // endianness
814                     C2PlanarLayout::PLANE_Y,        // rootIx
815                     0,                              // offset
816                 };
817                 layout->planes[C2PlanarLayout::PLANE_U] = {
818                     C2PlaneInfo::CHANNEL_CB,          // channel
819                     (int32_t)ycbcrLayout.chroma_step, // colInc
820                     (int32_t)ycbcrLayout.cstride,     // rowInc
821                     2,                                // mColSampling
822                     2,                                // mRowSampling
823                     8,                                // allocatedDepth
824                     8,                                // bitDepth
825                     0,                                // rightShift
826                     C2PlaneInfo::NATIVE,              // endianness
827                     C2PlanarLayout::PLANE_U,          // rootIx
828                     0,                                // offset
829                 };
830                 layout->planes[C2PlanarLayout::PLANE_V] = {
831                     C2PlaneInfo::CHANNEL_CR,          // channel
832                     (int32_t)ycbcrLayout.chroma_step, // colInc
833                     (int32_t)ycbcrLayout.cstride,     // rowInc
834                     2,                                // mColSampling
835                     2,                                // mRowSampling
836                     8,                                // allocatedDepth
837                     8,                                // bitDepth
838                     0,                                // rightShift
839                     C2PlaneInfo::NATIVE,              // endianness
840                     C2PlanarLayout::PLANE_V,          // rootIx
841                     0,                                // offset
842                 };
843                 break;
844             }
845 
846             // We really don't know what this is; lock the buffer and pass it through ---
847             // the client may know how to interpret it.
848 
849             // unlock previous allocation if it was successful
850             if (err == OK) {
851                 err = GraphicBufferMapper::get().unlock(buffer);
852                 if (err) {
853                     ALOGE("failed transaction: unlock");
854                     return C2_CORRUPTED;
855                 }
856             }
857 
858             void *pointer = nullptr;
859             err = GraphicBufferMapper::get().lock(
860                     const_cast<native_handle_t *>(buffer), grallocUsage, rect, &pointer);
861             if (err) {
862                 ALOGE("failed transaction: lock(??? %x)", format);
863                 return C2_CORRUPTED;
864             }
865             addr[0] = (uint8_t *)pointer;
866             layout->type = C2PlanarLayout::TYPE_UNKNOWN;
867             layout->numPlanes = 1;
868             layout->rootPlanes = 1;
869             layout->planes[0] = {
870                 // TODO: CHANNEL_UNKNOWN?
871                 C2PlaneInfo::channel_t(0xFF),   // channel
872                 1,                              // colInc
873                 int32_t(stride),               // rowInc
874                 1,                              // mColSampling
875                 1,                              // mRowSampling
876                 8,                              // allocatedDepth
877                 8,                              // bitDepth
878                 0,                              // rightShift
879                 C2PlaneInfo::NATIVE,            // endianness
880                 0,                              // rootIx
881                 0,                              // offset
882             };
883             break;
884         }
885     }
886     return C2_OK;
887 }
888 
HandleInterleavedPlanes(C2PlanarLayout * layout,uint8_t ** addr)889 static void HandleInterleavedPlanes(
890         C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) {
891     if (layout->type == C2PlanarLayout::TYPE_YUV && layout->rootPlanes == 3) {
892         intptr_t uvOffset = addr[C2PlanarLayout::PLANE_V] - addr[C2PlanarLayout::PLANE_U];
893         intptr_t uvColInc = layout->planes[C2PlanarLayout::PLANE_U].colInc;
894         if (uvOffset > 0 && uvOffset < uvColInc) {
895             layout->rootPlanes = 2;
896             layout->planes[C2PlanarLayout::PLANE_V].rootIx = C2PlanarLayout::PLANE_U;
897             layout->planes[C2PlanarLayout::PLANE_V].offset = uvOffset;
898         } else if (uvOffset < 0 && uvOffset > -uvColInc) {
899             layout->rootPlanes = 2;
900             layout->planes[C2PlanarLayout::PLANE_U].rootIx = C2PlanarLayout::PLANE_V;
901             layout->planes[C2PlanarLayout::PLANE_U].offset = -uvOffset;
902         }
903     }
904 }
905 
906 } // unnamed namespace
907 
908 
UnwrapNativeCodec2GrallocHandle(const C2Handle * const handle)909 native_handle_t *UnwrapNativeCodec2GrallocHandle(const C2Handle *const handle) {
910     if (handle == nullptr) {
911         return nullptr;
912     }
913     if (C2AllocatorGralloc::CheckHandle(handle)) {
914         return C2HandleGralloc::UnwrapNativeHandle(handle);
915     }
916     if (C2AllocatorAhwb::CheckHandle(handle)) {
917         return C2HandleAhwb::UnwrapNativeHandle(handle);
918     }
919     ALOGE("tried to unwrap non c2 compatible handle");
920     return nullptr;
921 }
922 
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)923 C2Handle *WrapNativeCodec2GrallocHandle(
924         const native_handle_t *const handle,
925         uint32_t width, uint32_t height, uint32_t format, uint64_t usage, uint32_t stride,
926         uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
927     return C2HandleGralloc::WrapNativeHandle(handle, width, height, format, usage, stride,
928                                              generation, igbp_id, igbp_slot);
929 }
930 
ExtractFormatFromCodec2GrallocHandle(const C2Handle * const handle)931 uint32_t ExtractFormatFromCodec2GrallocHandle(const C2Handle *const handle) {
932     if (C2AllocatorGralloc::CheckHandle(handle)) {
933         return C2HandleGralloc::getPixelFormat(handle);
934     }
935     if (C2AllocatorAhwb::CheckHandle(handle)) {
936         return C2HandleAhwb::getPixelFormat(handle);
937     }
938     ALOGE("tried to extract pixelformat from non c2 compatible handle");
939     return 0;
940 }
941 
ExtractMetadataFromCodec2GrallocHandle(const C2Handle * const handle,uint32_t * width,uint32_t * height,uint32_t * format,uint64_t * usage,uint32_t * stride)942 bool ExtractMetadataFromCodec2GrallocHandle(
943         const C2Handle *const handle,
944         uint32_t *width, uint32_t *height, uint32_t *format, uint64_t *usage, uint32_t *stride) {
945     if (handle == nullptr) {
946         ALOGE("ExtractMetadata from nullptr");
947         return false;
948     }
949     if (C2AllocatorGralloc::CheckHandle(handle)) {
950         uint32_t generation;
951         uint64_t igbp_id;
952         uint32_t igbp_slot;
953         (void)C2HandleGralloc::Import(handle, width, height, format, usage, stride,
954                                       &generation, &igbp_id, &igbp_slot);
955         return true;
956     }
957     if (C2AllocatorAhwb::CheckHandle(handle)) {
958         uint64_t origId;
959         (void)C2HandleAhwb::Import(handle, width, height, format, usage, stride, &origId);
960         return true;
961     }
962     ALOGE("ExtractMetadata from non compatible handle");
963     return false;
964 }
965 
MigrateNativeCodec2GrallocHandle(native_handle_t * handle,uint32_t generation,uint64_t igbp_id,uint32_t igbp_slot)966 bool MigrateNativeCodec2GrallocHandle(
967         native_handle_t *handle,
968         uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
969     return C2HandleGralloc::MigrateNativeHandle(handle, generation, igbp_id, igbp_slot);
970 }
971 
972 
973 
974 class C2AllocationGralloc : public C2GraphicAllocation {
975 public:
976     virtual ~C2AllocationGralloc() override;
977 
978     virtual c2_status_t map(
979             C2Rect c2Rect, C2MemoryUsage usage, C2Fence *fence,
980             C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) override;
981     virtual c2_status_t unmap(
982             uint8_t **addr /* nonnull */, C2Rect rect, C2Fence *fence /* nullable */) override;
getAllocatorId() const983     virtual C2Allocator::id_t getAllocatorId() const override { return mAllocatorId; }
handle() const984     virtual const C2Handle *handle() const override { return mLockedHandle ? : mHandle; }
985     virtual bool equals(const std::shared_ptr<const C2GraphicAllocation> &other) const override;
986 
987     // internal methods
988     // |handle| will be moved.
989 
990     C2AllocationGralloc(
991               uint32_t width, uint32_t height,
992               uint32_t format, uint32_t layerCount,
993               uint64_t grallocUsage, uint32_t stride,
994               hidl_handle &hidlHandle,
995               const C2HandleGralloc *const handle,
996               C2Allocator::id_t allocatorId);
997     int dup() const;
998     c2_status_t status() const;
999 
1000 private:
1001     const uint32_t mWidth;
1002     const uint32_t mHeight;
1003     const uint32_t mFormat;
1004     const uint32_t mLayerCount;
1005     const uint64_t mGrallocUsage;
1006     const uint32_t mStride;
1007     const hidl_handle mHidlHandle;
1008     const C2HandleGralloc *mHandle;
1009     buffer_handle_t mBuffer;
1010     const C2HandleGralloc *mLockedHandle;
1011     bool mLocked;
1012     C2Allocator::id_t mAllocatorId;
1013     std::mutex mMappedLock;
1014 };
1015 
C2AllocationGralloc(uint32_t width,uint32_t height,uint32_t format,uint32_t layerCount,uint64_t grallocUsage,uint32_t stride,hidl_handle & hidlHandle,const C2HandleGralloc * const handle,C2Allocator::id_t allocatorId)1016 C2AllocationGralloc::C2AllocationGralloc(
1017           uint32_t width, uint32_t height,
1018           uint32_t format, uint32_t layerCount,
1019           uint64_t grallocUsage, uint32_t stride,
1020           hidl_handle &hidlHandle,
1021           const C2HandleGralloc *const handle,
1022           C2Allocator::id_t allocatorId)
1023     : C2GraphicAllocation(width, height),
1024       mWidth(width),
1025       mHeight(height),
1026       mFormat(format),
1027       mLayerCount(layerCount),
1028       mGrallocUsage(grallocUsage),
1029       mStride(stride),
1030       mHidlHandle(std::move(hidlHandle)),
1031       mHandle(handle),
1032       mBuffer(nullptr),
1033       mLockedHandle(nullptr),
1034       mLocked(false),
1035       mAllocatorId(allocatorId) {
1036 }
1037 
~C2AllocationGralloc()1038 C2AllocationGralloc::~C2AllocationGralloc() {
1039     if (mBuffer && mLocked) {
1040         // implementation ignores address and rect
1041         uint8_t* addr[C2PlanarLayout::MAX_NUM_PLANES] = {};
1042         unmap(addr, C2Rect(), nullptr);
1043     }
1044     if (mBuffer) {
1045         status_t err = GraphicBufferMapper::get().freeBuffer(mBuffer);
1046         if (err) {
1047             ALOGE("failed transaction: freeBuffer");
1048         }
1049     }
1050     if (mHandle) {
1051         native_handle_delete(
1052                 const_cast<native_handle_t *>(reinterpret_cast<const native_handle_t *>(mHandle)));
1053     }
1054     if (mLockedHandle) {
1055         native_handle_delete(
1056                 const_cast<native_handle_t *>(
1057                         reinterpret_cast<const native_handle_t *>(mLockedHandle)));
1058     }
1059 }
1060 
map(C2Rect c2Rect,C2MemoryUsage usage,C2Fence * fence,C2PlanarLayout * layout,uint8_t ** addr)1061 c2_status_t C2AllocationGralloc::map(
1062         C2Rect c2Rect, C2MemoryUsage usage, C2Fence *fence,
1063         C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) {
1064     const Rect rect{(int32_t)c2Rect.left, (int32_t)c2Rect.top,
1065                     (int32_t)(c2Rect.left + c2Rect.width) /* right */,
1066                     (int32_t)(c2Rect.top + c2Rect.height) /* bottom */};
1067 
1068     uint64_t grallocUsage = static_cast<C2AndroidMemoryUsage>(usage).asGrallocUsage();
1069     ALOGV("mapping buffer with usage %#llx => %#llx",
1070           (long long)usage.expected, (long long)grallocUsage);
1071 
1072     // TODO
1073     (void)fence;
1074 
1075     std::lock_guard<std::mutex> lock(mMappedLock);
1076     if (mBuffer && mLocked) {
1077         ALOGD("already mapped");
1078         return C2_DUPLICATE;
1079     }
1080     if (!layout || !addr) {
1081         ALOGD("wrong param");
1082         return C2_BAD_VALUE;
1083     }
1084 
1085     if (!mBuffer) {
1086         status_t err = GraphicBufferMapper::get().importBuffer(
1087                             mHidlHandle.getNativeHandle(), mWidth, mHeight, mLayerCount,
1088                             mFormat, mGrallocUsage, mStride, &mBuffer);
1089         if (err) {
1090             ALOGE("failed transaction: importBuffer");
1091             return C2_CORRUPTED;
1092         }
1093         if (mBuffer == nullptr) {
1094             ALOGD("importBuffer returned null buffer");
1095             return C2_CORRUPTED;
1096         }
1097         uint32_t generation = 0;
1098         uint64_t igbp_id = 0;
1099         uint32_t igbp_slot = 0;
1100         if (mHandle) {
1101             mHandle->getIgbpData(&generation, &igbp_id, &igbp_slot);
1102         }
1103 
1104         mLockedHandle = C2HandleGralloc::WrapAndMoveNativeHandle(
1105                 mBuffer, mWidth, mHeight, mFormat, mGrallocUsage,
1106                 mStride, generation, igbp_id, igbp_slot);
1107     }
1108 
1109     c2_status_t ret = PopulatePlaneLayout(
1110             mBuffer, rect, mFormat, grallocUsage, mStride, layout, addr);
1111     if (ret != C2_OK) {
1112         return ret;
1113     }
1114     mLocked = true;
1115 
1116     HandleInterleavedPlanes(layout, addr);
1117 
1118     ALOGV("C2AllocationGralloc::map: layout: type=%d numPlanes=%d rootPlanes=%d",
1119           layout->type, layout->numPlanes, layout->rootPlanes);
1120     for (int i = 0; i < layout->numPlanes; ++i) {
1121         const C2PlaneInfo &plane = layout->planes[i];
1122         ALOGV("C2AllocationGralloc::map: plane[%d]: colInc=%d rowInc=%d rootIx=%u offset=%u",
1123               i, plane.colInc, plane.rowInc, plane.rootIx, plane.offset);
1124     }
1125 
1126     return C2_OK;
1127 }
1128 
unmap(uint8_t ** addr,C2Rect rect,C2Fence * fence)1129 c2_status_t C2AllocationGralloc::unmap(
1130         uint8_t **addr, C2Rect rect, C2Fence *fence /* nullable */) {
1131     // TODO: check addr and size, use fence
1132     (void)addr;
1133     (void)rect;
1134     (void)fence;
1135 
1136     std::lock_guard<std::mutex> lock(mMappedLock);
1137     // TODO: fence
1138     status_t err = GraphicBufferMapper::get().unlock(mBuffer);
1139     if (err) {
1140         ALOGE("failed transaction: unlock");
1141         return C2_CORRUPTED;
1142     }
1143 
1144     mLocked = false;
1145     return C2_OK;
1146 }
1147 
equals(const std::shared_ptr<const C2GraphicAllocation> & other) const1148 bool C2AllocationGralloc::equals(const std::shared_ptr<const C2GraphicAllocation> &other) const {
1149     return other && other->handle() == handle();
1150 }
1151 
1152 /* ===================================== GRALLOC ALLOCATOR ==================================== */
1153 class C2AllocatorGralloc::Impl {
1154 public:
1155     Impl(id_t id, bool bufferQueue);
1156 
getId() const1157     id_t getId() const {
1158         return mTraits->id;
1159     }
1160 
getName() const1161     C2String getName() const {
1162         return mTraits->name;
1163     }
1164 
getTraits() const1165     std::shared_ptr<const C2Allocator::Traits> getTraits() const {
1166         return mTraits;
1167     }
1168 
1169     c2_status_t newGraphicAllocation(
1170             uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
1171             std::shared_ptr<C2GraphicAllocation> *allocation);
1172 
1173     c2_status_t priorGraphicAllocation(
1174             const C2Handle *handle,
1175             std::shared_ptr<C2GraphicAllocation> *allocation);
1176 
status() const1177     c2_status_t status() const { return mInit; }
1178 
1179 private:
1180     std::shared_ptr<C2Allocator::Traits> mTraits;
1181     c2_status_t mInit;
1182     const bool mBufferQueue;
1183 };
1184 
_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)1185 void _UnwrapNativeCodec2GrallocMetadata(
1186         const C2Handle *const handle,
1187         uint32_t *width, uint32_t *height, uint32_t *format,uint64_t *usage, uint32_t *stride,
1188         uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) {
1189     if (C2AllocatorGralloc::CheckHandle(handle)) {
1190         (void)C2HandleGralloc::Import(handle, width, height, format, usage, stride,
1191                                       generation, igbp_id, igbp_slot);
1192         return;
1193     }
1194     if (C2AllocatorAhwb::CheckHandle(handle)) {
1195         uint64_t origId;
1196         (void)C2HandleAhwb::Import(handle, width, height, format, usage, stride, &origId);
1197         return;
1198     }
1199     ALOGE("Tried to extract metadata from non c2 compatible handle");
1200 }
1201 
Impl(id_t id,bool bufferQueue)1202 C2AllocatorGralloc::Impl::Impl(id_t id, bool bufferQueue)
1203     : mInit(C2_OK), mBufferQueue(bufferQueue) {
1204     // TODO: get this from allocator
1205     C2MemoryUsage minUsage = { 0, 0 }, maxUsage = { ~(uint64_t)0, ~(uint64_t)0 };
1206     Traits traits = { "android.allocator.gralloc", id, C2Allocator::GRAPHIC, minUsage, maxUsage };
1207     mTraits = std::make_shared<C2Allocator::Traits>(traits);
1208 }
1209 
newGraphicAllocation(uint32_t width,uint32_t height,uint32_t format,const C2MemoryUsage & usage,std::shared_ptr<C2GraphicAllocation> * allocation)1210 c2_status_t C2AllocatorGralloc::Impl::newGraphicAllocation(
1211         uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
1212         std::shared_ptr<C2GraphicAllocation> *allocation) {
1213     uint64_t grallocUsage = static_cast<C2AndroidMemoryUsage>(usage).asGrallocUsage();
1214     ALOGV("allocating buffer with usage %#llx => %#llx",
1215           (long long)usage.expected, (long long)grallocUsage);
1216 
1217     buffer_handle_t buffer;
1218 
1219     uint32_t stride = 0;
1220 
1221     status_t err = GraphicBufferAllocator::get().allocateRawHandle(width, height, format,
1222             1u /* layer count */, grallocUsage, &buffer, &stride, "C2GrallocAllocation");
1223     if (err) {
1224         ALOGE("failed transaction: allocate");
1225         return C2_CORRUPTED;
1226     }
1227 
1228     hidl_handle hidlHandle;
1229     hidlHandle.setTo(const_cast<native_handle_t*>(buffer), true);
1230 
1231     allocation->reset(new C2AllocationGralloc(
1232             width, height, format, 1u /* layer count */, grallocUsage, stride, hidlHandle,
1233             C2HandleGralloc::WrapAndMoveNativeHandle(
1234                     hidlHandle, width, height,
1235                     format, grallocUsage, stride,
1236                     0, 0, mBufferQueue ? ~0 : 0),
1237             mTraits->id));
1238     return C2_OK;
1239 }
1240 
priorGraphicAllocation(const C2Handle * handle,std::shared_ptr<C2GraphicAllocation> * allocation)1241 c2_status_t C2AllocatorGralloc::Impl::priorGraphicAllocation(
1242         const C2Handle *handle,
1243         std::shared_ptr<C2GraphicAllocation> *allocation) {
1244 
1245     uint32_t generation;
1246     uint64_t igbp_id;
1247     uint32_t igbp_slot;
1248 
1249     uint32_t width;
1250     uint32_t height;
1251     uint32_t format;
1252     uint32_t layerCount = 1;
1253     uint64_t grallocUsage;
1254     uint32_t stride;
1255 
1256     const C2HandleGralloc *grallocHandle = C2HandleGralloc::Import(
1257             handle, &width, &height, &format, &grallocUsage, &stride,
1258             &generation, &igbp_id, &igbp_slot);
1259     if (grallocHandle == nullptr) {
1260         return C2_BAD_VALUE;
1261     }
1262 
1263     hidl_handle hidlHandle;
1264     hidlHandle.setTo(C2HandleGralloc::UnwrapNativeHandle(grallocHandle), true);
1265 
1266     allocation->reset(new C2AllocationGralloc(
1267             width, height, format, layerCount,
1268             grallocUsage, stride, hidlHandle, grallocHandle, mTraits->id));
1269     return C2_OK;
1270 }
1271 
C2AllocatorGralloc(id_t id,bool bufferQueue)1272 C2AllocatorGralloc::C2AllocatorGralloc(id_t id, bool bufferQueue)
1273         : mImpl(new Impl(id, bufferQueue)) {}
1274 
~C2AllocatorGralloc()1275 C2AllocatorGralloc::~C2AllocatorGralloc() { delete mImpl; }
1276 
getId() const1277 C2Allocator::id_t C2AllocatorGralloc::getId() const {
1278     return mImpl->getId();
1279 }
1280 
getName() const1281 C2String C2AllocatorGralloc::getName() const {
1282     return mImpl->getName();
1283 }
1284 
getTraits() const1285 std::shared_ptr<const C2Allocator::Traits> C2AllocatorGralloc::getTraits() const {
1286     return mImpl->getTraits();
1287 }
1288 
newGraphicAllocation(uint32_t width,uint32_t height,uint32_t format,C2MemoryUsage usage,std::shared_ptr<C2GraphicAllocation> * allocation)1289 c2_status_t C2AllocatorGralloc::newGraphicAllocation(
1290         uint32_t width, uint32_t height, uint32_t format, C2MemoryUsage usage,
1291         std::shared_ptr<C2GraphicAllocation> *allocation) {
1292     return mImpl->newGraphicAllocation(width, height, format, usage, allocation);
1293 }
1294 
priorGraphicAllocation(const C2Handle * handle,std::shared_ptr<C2GraphicAllocation> * allocation)1295 c2_status_t C2AllocatorGralloc::priorGraphicAllocation(
1296         const C2Handle *handle,
1297         std::shared_ptr<C2GraphicAllocation> *allocation) {
1298     return mImpl->priorGraphicAllocation(handle, allocation);
1299 }
1300 
status() const1301 c2_status_t C2AllocatorGralloc::status() const {
1302     return mImpl->status();
1303 }
1304 
1305 // static
CheckHandle(const C2Handle * const o)1306 bool C2AllocatorGralloc::CheckHandle(const C2Handle* const o) {
1307     return C2HandleGralloc::IsValid(o);
1308 }
1309 
1310 
WrapNativeCodec2AhwbHandle(const native_handle_t * const handle,uint32_t width,uint32_t height,uint32_t format,uint64_t usage,uint32_t stride,uint64_t origId)1311 C2Handle *WrapNativeCodec2AhwbHandle(
1312         const native_handle_t *const handle,
1313         uint32_t width, uint32_t height, uint32_t format, uint64_t usage, uint32_t stride,
1314         uint64_t origId) {
1315     return C2HandleAhwb::WrapNativeHandle(handle, width, height, format, usage, stride,
1316                                           origId);
1317 }
1318 
1319 class C2AllocationAhwb : public C2GraphicAllocation {
1320 public:
1321     virtual ~C2AllocationAhwb() override;
1322 
1323     virtual c2_status_t map(
1324             C2Rect c2Rect, C2MemoryUsage usage, C2Fence *fence,
1325             C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) override;
1326     virtual c2_status_t unmap(
1327             uint8_t **addr /* nonnull */, C2Rect rect, C2Fence *fence /* nullable */) override;
getAllocatorId() const1328     virtual C2Allocator::id_t getAllocatorId() const override { return mAllocatorId; }
handle() const1329     virtual const C2Handle *handle() const override { return mLockedHandle ? : mHandle; }
1330     virtual bool equals(const std::shared_ptr<const C2GraphicAllocation> &other) const override;
1331 
1332     // internal methods
1333     // |handle| will be moved.
1334 
1335     C2AllocationAhwb(
1336               uint32_t width, uint32_t height,
1337               uint32_t format, uint32_t layerCount,
1338               uint64_t grallocUsage, uint32_t stride,
1339               const C2HandleAhwb *const handle,
1340               C2Allocator::id_t allocatorId);
1341     int dup() const;
1342     c2_status_t status() const;
1343 
1344 private:
1345     const uint32_t mWidth;
1346     const uint32_t mHeight;
1347     const uint32_t mFormat;
1348     const uint32_t mLayerCount;
1349     const uint64_t mGrallocUsage;
1350     const uint32_t mStride;
1351     const native_handle_t *mRawHandle;
1352     const C2HandleAhwb *mHandle;
1353     buffer_handle_t mBuffer;
1354     const C2HandleAhwb *mLockedHandle;
1355     bool mLocked;
1356     C2Allocator::id_t mAllocatorId;
1357     std::mutex mMappedLock;
1358 };
1359 
C2AllocationAhwb(uint32_t width,uint32_t height,uint32_t format,uint32_t layerCount,uint64_t grallocUsage,uint32_t stride,const C2HandleAhwb * const handle,C2Allocator::id_t allocatorId)1360 C2AllocationAhwb::C2AllocationAhwb(
1361           uint32_t width, uint32_t height,
1362           uint32_t format, uint32_t layerCount,
1363           uint64_t grallocUsage, uint32_t stride,
1364           const C2HandleAhwb *const handle,
1365           C2Allocator::id_t allocatorId)
1366     : C2GraphicAllocation(width, height),
1367       mWidth(width),
1368       mHeight(height),
1369       mFormat(format),
1370       mLayerCount(layerCount),
1371       mGrallocUsage(grallocUsage),
1372       mStride(stride),
1373       mRawHandle(C2HandleAhwb::UnwrapNativeHandle(handle)),
1374       mHandle(handle),
1375       mBuffer(nullptr),
1376       mLockedHandle(nullptr),
1377       mLocked(false),
1378       mAllocatorId(allocatorId) {
1379 }
1380 
~C2AllocationAhwb()1381 C2AllocationAhwb::~C2AllocationAhwb() {
1382     if (mBuffer && mLocked) {
1383         // implementation ignores address and rect
1384         uint8_t* addr[C2PlanarLayout::MAX_NUM_PLANES] = {};
1385         unmap(addr, C2Rect(), nullptr);
1386     }
1387     if (mBuffer) {
1388         status_t err = GraphicBufferMapper::get().freeBuffer(mBuffer);
1389         if (err) {
1390             ALOGE("failed transaction: freeBuffer");
1391         }
1392     }
1393     if (mRawHandle) {
1394         native_handle_close(
1395                 const_cast<native_handle_t *>(
1396                         reinterpret_cast<const native_handle_t *>(mRawHandle)));
1397         native_handle_delete(
1398                 const_cast<native_handle_t *>(
1399                         reinterpret_cast<const native_handle_t *>(mRawHandle)));
1400     }
1401     if (mHandle) {
1402         native_handle_delete(
1403                 const_cast<native_handle_t *>(reinterpret_cast<const native_handle_t *>(mHandle)));
1404     }
1405     if (mLockedHandle) {
1406         native_handle_delete(
1407                 const_cast<native_handle_t *>(
1408                         reinterpret_cast<const native_handle_t *>(mLockedHandle)));
1409     }
1410 }
1411 
map(C2Rect c2Rect,C2MemoryUsage usage,C2Fence * fence,C2PlanarLayout * layout,uint8_t ** addr)1412 c2_status_t C2AllocationAhwb::map(
1413         C2Rect c2Rect, C2MemoryUsage usage, C2Fence *fence,
1414         C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) {
1415     const Rect rect{(int32_t)c2Rect.left, (int32_t)c2Rect.top,
1416                     (int32_t)(c2Rect.left + c2Rect.width) /* right */,
1417                     (int32_t)(c2Rect.top + c2Rect.height) /* bottom */};
1418 
1419     uint64_t grallocUsage = static_cast<C2AndroidMemoryUsage>(usage).asGrallocUsage();
1420     ALOGV("mapping buffer with usage %#llx => %#llx",
1421           (long long)usage.expected, (long long)grallocUsage);
1422 
1423     // TODO
1424     (void)fence;
1425 
1426     std::lock_guard<std::mutex> lock(mMappedLock);
1427     if (mBuffer && mLocked) {
1428         ALOGD("already mapped");
1429         return C2_DUPLICATE;
1430     }
1431     if (!layout || !addr) {
1432         ALOGD("wrong param");
1433         return C2_BAD_VALUE;
1434     }
1435 
1436     if (!mBuffer) {
1437         // TODO: libui/libgui dependency removal (b/214400477)
1438         status_t err = GraphicBufferMapper::get().importBuffer(
1439                             mRawHandle, mWidth, mHeight, mLayerCount,
1440                             mFormat, mGrallocUsage, mStride, &mBuffer);
1441         if (err) {
1442             ALOGE("failed transaction: importBuffer");
1443             return C2_CORRUPTED;
1444         }
1445         if (mBuffer == nullptr) {
1446             ALOGD("importBuffer returned null buffer");
1447             return C2_CORRUPTED;
1448         }
1449         uint64_t origId = 0;
1450         if (mHandle) {
1451             mHandle->getOrigId(&origId);
1452         }
1453 
1454         mLockedHandle = C2HandleAhwb::WrapAndMoveNativeHandle(
1455                 mBuffer, mWidth, mHeight, mFormat, mGrallocUsage,
1456                 mStride, origId);
1457     }
1458 
1459     c2_status_t ret = PopulatePlaneLayout(
1460             mBuffer, rect, mFormat, grallocUsage, mStride, layout, addr);
1461     if (ret != C2_OK) {
1462         return ret;
1463     }
1464     mLocked = true;
1465 
1466     HandleInterleavedPlanes(layout, addr);
1467 
1468     ALOGV("C2AllocationGralloc::map: layout: type=%d numPlanes=%d rootPlanes=%d",
1469           layout->type, layout->numPlanes, layout->rootPlanes);
1470     for (int i = 0; i < layout->numPlanes; ++i) {
1471         const C2PlaneInfo &plane = layout->planes[i];
1472         ALOGV("C2AllocationGralloc::map: plane[%d]: colInc=%d rowInc=%d rootIx=%u offset=%u",
1473               i, plane.colInc, plane.rowInc, plane.rootIx, plane.offset);
1474     }
1475 
1476     return C2_OK;
1477 }
1478 
unmap(uint8_t ** addr,C2Rect rect,C2Fence * fence)1479 c2_status_t C2AllocationAhwb::unmap(
1480         uint8_t **addr, C2Rect rect, C2Fence *fence /* nullable */) {
1481     // TODO: check addr and size, use fence
1482     (void)addr;
1483     (void)rect;
1484     (void)fence;
1485 
1486     std::lock_guard<std::mutex> lock(mMappedLock);
1487     // TODO: fence
1488     status_t err = GraphicBufferMapper::get().unlock(mBuffer);
1489     if (err) {
1490         ALOGE("failed transaction: unlock");
1491         return C2_CORRUPTED;
1492     }
1493 
1494     mLocked = false;
1495     return C2_OK;
1496 }
1497 
equals(const std::shared_ptr<const C2GraphicAllocation> & other) const1498 bool C2AllocationAhwb::equals(const std::shared_ptr<const C2GraphicAllocation> &other) const {
1499     return other && other->handle() == handle();
1500 }
1501 
1502 /* ===================================== AHARDWAREBUFFER ALLOCATOR ============================= */
1503 class C2AllocatorAhwb::Impl {
1504 public:
1505     Impl(id_t id);
1506 
getId() const1507     id_t getId() const {
1508         return mTraits->id;
1509     }
1510 
getName() const1511     C2String getName() const {
1512         return mTraits->name;
1513     }
1514 
getTraits() const1515     std::shared_ptr<const C2Allocator::Traits> getTraits() const {
1516         return mTraits;
1517     }
1518 
1519     c2_status_t newGraphicAllocation(
1520             uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
1521             std::shared_ptr<C2GraphicAllocation> *allocation);
1522 
1523     c2_status_t priorGraphicAllocation(
1524             const C2Handle *handle,
1525             std::shared_ptr<C2GraphicAllocation> *allocation);
1526 
status() const1527     c2_status_t status() const { return mInit; }
1528 
1529 private:
1530     std::shared_ptr<C2Allocator::Traits> mTraits;
1531     c2_status_t mInit;
1532 };
1533 
Impl(id_t id)1534 C2AllocatorAhwb::Impl::Impl(id_t id)
1535     : mInit(C2_OK) {
1536     // TODO: get this from allocator
1537     C2MemoryUsage minUsage = { 0, 0 }, maxUsage = { ~(uint64_t)0, ~(uint64_t)0 };
1538     Traits traits = { "android.allocator.ahwb", id, C2Allocator::GRAPHIC, minUsage, maxUsage };
1539     mTraits = std::make_shared<C2Allocator::Traits>(traits);
1540 }
1541 
newGraphicAllocation(uint32_t width,uint32_t height,uint32_t format,const C2MemoryUsage & usage,std::shared_ptr<C2GraphicAllocation> * allocation)1542 c2_status_t C2AllocatorAhwb::Impl::newGraphicAllocation(
1543         uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
1544         std::shared_ptr<C2GraphicAllocation> *allocation) {
1545     // TODO: for client side usage
1546     // HAL side Ahwb allocation should be done via IGBA currently.
1547     (void) width;
1548     (void) height;
1549     (void) format;
1550     (void) usage;
1551     (void) allocation;
1552     return C2_OMITTED;
1553 }
1554 
priorGraphicAllocation(const C2Handle * handle,std::shared_ptr<C2GraphicAllocation> * allocation)1555 c2_status_t C2AllocatorAhwb::Impl::priorGraphicAllocation(
1556         const C2Handle *handle,
1557         std::shared_ptr<C2GraphicAllocation> *allocation) {
1558 
1559     uint32_t width;
1560     uint32_t height;
1561     uint32_t format;
1562     uint32_t layerCount = 1;
1563     uint64_t grallocUsage;
1564     uint32_t stride;
1565     uint64_t origId;
1566 
1567     const C2HandleAhwb *ahwbHandle = C2HandleAhwb::Import(
1568             handle, &width, &height, &format, &grallocUsage, &stride, &origId);
1569     if (ahwbHandle == nullptr) {
1570         return C2_BAD_VALUE;
1571     }
1572 
1573     allocation->reset(new C2AllocationAhwb(
1574             width, height, format, layerCount,
1575             grallocUsage, stride, ahwbHandle, mTraits->id));
1576     return C2_OK;
1577 }
1578 
C2AllocatorAhwb(id_t id)1579 C2AllocatorAhwb::C2AllocatorAhwb(id_t id)
1580         : mImpl(new Impl(id)) {}
1581 
~C2AllocatorAhwb()1582 C2AllocatorAhwb::~C2AllocatorAhwb() { delete mImpl; }
1583 
getId() const1584 C2Allocator::id_t C2AllocatorAhwb::getId() const {
1585     return mImpl->getId();
1586 }
1587 
getName() const1588 C2String C2AllocatorAhwb::getName() const {
1589     return mImpl->getName();
1590 }
1591 
getTraits() const1592 std::shared_ptr<const C2Allocator::Traits> C2AllocatorAhwb::getTraits() const {
1593     return mImpl->getTraits();
1594 }
1595 
newGraphicAllocation(uint32_t width,uint32_t height,uint32_t format,C2MemoryUsage usage,std::shared_ptr<C2GraphicAllocation> * allocation)1596 c2_status_t C2AllocatorAhwb::newGraphicAllocation(
1597         uint32_t width, uint32_t height, uint32_t format, C2MemoryUsage usage,
1598         std::shared_ptr<C2GraphicAllocation> *allocation) {
1599     return mImpl->newGraphicAllocation(width, height, format, usage, allocation);
1600 }
1601 
priorGraphicAllocation(const C2Handle * handle,std::shared_ptr<C2GraphicAllocation> * allocation)1602 c2_status_t C2AllocatorAhwb::priorGraphicAllocation(
1603         const C2Handle *handle,
1604         std::shared_ptr<C2GraphicAllocation> *allocation) {
1605     return mImpl->priorGraphicAllocation(handle, allocation);
1606 }
1607 
status() const1608 c2_status_t C2AllocatorAhwb::status() const {
1609     return mImpl->status();
1610 }
1611 
1612 // static
CheckHandle(const C2Handle * const o)1613 bool C2AllocatorAhwb::CheckHandle(const C2Handle* const o) {
1614     return C2HandleAhwb::IsValid(o);
1615 }
1616 } // namespace android
1617