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