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