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