blob: 107ce89f613fbfcdd52af4e49de92b028126cf15 [file] [log] [blame]
Pawin Vongmasa36653902018-11-15 00:10:25 -08001/*
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
Marissa Wall2a24a302019-11-25 11:19:18 -080021#include <mutex>
22
Praveen Chavan34493f12021-02-18 00:51:50 -080023#include <aidl/android/hardware/graphics/common/PlaneLayoutComponentType.h>
Marissa Wall2a24a302019-11-25 11:19:18 -080024#include <android/hardware/graphics/common/1.2/types.h>
Pawin Vongmasa36653902018-11-15 00:10:25 -080025#include <cutils/native_handle.h>
Tao Wu9d482892023-09-15 02:28:41 +000026#include <drm/drm_fourcc.h>
Praveen Chavan34493f12021-02-18 00:51:50 -080027#include <gralloctypes/Gralloc4.h>
Pawin Vongmasa36653902018-11-15 00:10:25 -080028#include <hardware/gralloc.h>
Marissa Wall2a24a302019-11-25 11:19:18 -080029#include <ui/GraphicBufferAllocator.h>
30#include <ui/GraphicBufferMapper.h>
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +090031#include <ui/Rect.h>
Pawin Vongmasa36653902018-11-15 00:10:25 -080032
33#include <C2AllocatorGralloc.h>
34#include <C2Buffer.h>
Praveen Chavan34493f12021-02-18 00:51:50 -080035#include <C2Debug.h>
Pawin Vongmasa36653902018-11-15 00:10:25 -080036#include <C2PlatformSupport.h>
37
Marissa Wall2a24a302019-11-25 11:19:18 -080038using ::android::hardware::hidl_handle;
39using PixelFormat4 = ::android::hardware::graphics::common::V1_2::PixelFormat;
40
Pawin Vongmasa36653902018-11-15 00:10:25 -080041namespace android {
42
Pawin Vongmasad032f2d2019-05-15 08:42:44 -070043namespace /* unnamed */ {
Pawin Vongmasa36653902018-11-15 00:10:25 -080044 enum : uint64_t {
45 /**
46 * Usage mask that is passed through from gralloc to Codec 2.0 usage.
47 */
48 PASSTHROUGH_USAGE_MASK =
Charlie Chen49d3fe72021-03-25 20:02:37 +080049 ~static_cast<uint64_t>(GRALLOC_USAGE_SW_READ_MASK |
50 GRALLOC_USAGE_SW_WRITE_MASK |
51 GRALLOC_USAGE_PROTECTED)
Pawin Vongmasa36653902018-11-15 00:10:25 -080052 };
53
54 // verify that passthrough mask is within the platform mask
55 static_assert((~C2MemoryUsage::PLATFORM_MASK & PASSTHROUGH_USAGE_MASK) == 0, "");
Pawin Vongmasad032f2d2019-05-15 08:42:44 -070056} // unnamed
Pawin Vongmasa36653902018-11-15 00:10:25 -080057
Harish Mahendrakar7dc54f92022-06-30 20:36:23 -070058static bool isAtLeastT() {
59 return android_get_device_api_level() >= __ANDROID_API_T__;
60}
61
Pawin Vongmasa36653902018-11-15 00:10:25 -080062C2MemoryUsage C2AndroidMemoryUsage::FromGrallocUsage(uint64_t usage) {
63 // gralloc does not support WRITE_PROTECTED
64 return C2MemoryUsage(
65 ((usage & GRALLOC_USAGE_SW_READ_MASK) ? C2MemoryUsage::CPU_READ : 0) |
66 ((usage & GRALLOC_USAGE_SW_WRITE_MASK) ? C2MemoryUsage::CPU_WRITE : 0) |
67 ((usage & GRALLOC_USAGE_PROTECTED) ? C2MemoryUsage::READ_PROTECTED : 0) |
68 (usage & PASSTHROUGH_USAGE_MASK));
69}
70
71uint64_t C2AndroidMemoryUsage::asGrallocUsage() const {
72 // gralloc does not support WRITE_PROTECTED
73 return (((expected & C2MemoryUsage::CPU_READ) ? GRALLOC_USAGE_SW_READ_OFTEN : 0) |
74 ((expected & C2MemoryUsage::CPU_WRITE) ? GRALLOC_USAGE_SW_WRITE_OFTEN : 0) |
75 ((expected & C2MemoryUsage::READ_PROTECTED) ? GRALLOC_USAGE_PROTECTED : 0) |
76 (expected & PASSTHROUGH_USAGE_MASK));
77}
78
Pawin Vongmasad032f2d2019-05-15 08:42:44 -070079namespace /* unnamed */ {
80
Pawin Vongmasa36653902018-11-15 00:10:25 -080081/* ===================================== GRALLOC ALLOCATION ==================================== */
Pawin Vongmasa36653902018-11-15 00:10:25 -080082bool native_handle_is_invalid(const native_handle_t *const handle) {
83 // perform basic validation of a native handle
84 if (handle == nullptr) {
85 // null handle is considered valid
86 return false;
87 }
88 return ((size_t)handle->version != sizeof(native_handle_t) ||
89 handle->numFds < 0 ||
90 handle->numInts < 0 ||
91 // for sanity assume handles must occupy less memory than INT_MAX bytes
92 handle->numFds > int((INT_MAX - handle->version) / sizeof(int)) - handle->numInts);
93}
94
95class C2HandleGralloc : public C2Handle {
96private:
97 struct ExtraData {
98 uint32_t width;
99 uint32_t height;
100 uint32_t format;
101 uint32_t usage_lo;
102 uint32_t usage_hi;
103 uint32_t stride;
104 uint32_t generation;
105 uint32_t igbp_id_lo;
106 uint32_t igbp_id_hi;
107 uint32_t igbp_slot;
108 uint32_t magic;
109 };
110
111 enum {
112 NUM_INTS = sizeof(ExtraData) / sizeof(int),
113 };
114 const static uint32_t MAGIC = '\xc2gr\x00';
115
116 static
John Stultz653ddd12020-09-19 05:26:24 +0000117 const ExtraData* GetExtraData(const C2Handle *const handle) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800118 if (handle == nullptr
119 || native_handle_is_invalid(handle)
120 || handle->numInts < NUM_INTS) {
121 return nullptr;
122 }
123 return reinterpret_cast<const ExtraData*>(
124 &handle->data[handle->numFds + handle->numInts - NUM_INTS]);
125 }
126
127 static
John Stultz653ddd12020-09-19 05:26:24 +0000128 ExtraData *GetExtraData(C2Handle *const handle) {
129 return const_cast<ExtraData *>(GetExtraData(const_cast<const C2Handle *const>(handle)));
Pawin Vongmasa36653902018-11-15 00:10:25 -0800130 }
131
132public:
133 void getIgbpData(uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) const {
John Stultz653ddd12020-09-19 05:26:24 +0000134 const ExtraData *ed = GetExtraData(this);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800135 *generation = ed->generation;
136 *igbp_id = unsigned(ed->igbp_id_lo) | uint64_t(unsigned(ed->igbp_id_hi)) << 32;
137 *igbp_slot = ed->igbp_slot;
138 }
139
John Stultz653ddd12020-09-19 05:26:24 +0000140 static bool IsValid(const C2Handle *const o) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800141 if (o == nullptr) { // null handle is always valid
142 return true;
143 }
John Stultz653ddd12020-09-19 05:26:24 +0000144 const ExtraData *xd = GetExtraData(o);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800145 // we cannot validate width/height/format/usage without accessing gralloc driver
146 return xd != nullptr && xd->magic == MAGIC;
147 }
148
Sungtak Leea4d13be2019-01-23 15:24:46 -0800149 static C2HandleGralloc* WrapAndMoveNativeHandle(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800150 const native_handle_t *const handle,
151 uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
152 uint32_t stride, uint32_t generation, uint64_t igbp_id = 0, uint32_t igbp_slot = 0) {
153 //CHECK(handle != nullptr);
154 if (native_handle_is_invalid(handle) ||
155 handle->numInts > int((INT_MAX - handle->version) / sizeof(int)) - NUM_INTS - handle->numFds) {
156 return nullptr;
157 }
158 ExtraData xd = {
159 width, height, format, uint32_t(usage & 0xFFFFFFFF), uint32_t(usage >> 32),
160 stride, generation, uint32_t(igbp_id & 0xFFFFFFFF), uint32_t(igbp_id >> 32),
161 igbp_slot, MAGIC
162 };
163 native_handle_t *res = native_handle_create(handle->numFds, handle->numInts + NUM_INTS);
164 if (res != nullptr) {
165 memcpy(&res->data, &handle->data, sizeof(int) * (handle->numFds + handle->numInts));
John Stultz653ddd12020-09-19 05:26:24 +0000166 *GetExtraData(res) = xd;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800167 }
168 return reinterpret_cast<C2HandleGralloc *>(res);
169 }
170
Sungtak Leea4d13be2019-01-23 15:24:46 -0800171 static C2HandleGralloc* WrapNativeHandle(
172 const native_handle_t *const handle,
173 uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
174 uint32_t stride, uint32_t generation, uint64_t igbp_id = 0, uint32_t igbp_slot = 0) {
175 if (handle == nullptr) {
176 return nullptr;
177 }
178 native_handle_t *clone = native_handle_clone(handle);
179 if (clone == nullptr) {
180 return nullptr;
181 }
182 C2HandleGralloc *res = WrapAndMoveNativeHandle(
183 clone, width, height, format, usage, stride, generation, igbp_id, igbp_slot);
184 if (res == nullptr) {
185 native_handle_close(clone);
186 }
187 native_handle_delete(clone);
188 return res;
189 }
190
Songyue Han1e6769b2023-08-30 18:09:27 +0000191 static uint32_t getPixelFormat(const C2Handle *const handle) {
192 if (handle == nullptr) {
193 return 0;
194 }
195 const ExtraData *xd = GetExtraData(handle);
196 return xd->format;
197 }
198
Sungtak Lee08515812019-06-05 11:16:32 -0700199 static bool MigrateNativeHandle(
200 native_handle_t *handle,
201 uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
John Stultz653ddd12020-09-19 05:26:24 +0000202 if (handle == nullptr || !IsValid(handle)) {
Sungtak Lee08515812019-06-05 11:16:32 -0700203 return false;
204 }
John Stultz653ddd12020-09-19 05:26:24 +0000205 ExtraData *ed = GetExtraData(handle);
Sungtak Lee08515812019-06-05 11:16:32 -0700206 if (!ed) return false;
207 ed->generation = generation;
208 ed->igbp_id_lo = uint32_t(igbp_id & 0xFFFFFFFF);
209 ed->igbp_id_hi = uint32_t(igbp_id >> 32);
210 ed->igbp_slot = igbp_slot;
211 return true;
212 }
213
214
Pawin Vongmasa36653902018-11-15 00:10:25 -0800215 static native_handle_t* UnwrapNativeHandle(
216 const C2Handle *const handle) {
John Stultz653ddd12020-09-19 05:26:24 +0000217 const ExtraData *xd = GetExtraData(handle);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800218 if (xd == nullptr || xd->magic != MAGIC) {
219 return nullptr;
220 }
221 native_handle_t *res = native_handle_create(handle->numFds, handle->numInts - NUM_INTS);
222 if (res != nullptr) {
223 memcpy(&res->data, &handle->data, sizeof(int) * (res->numFds + res->numInts));
224 }
225 return res;
226 }
227
Pawin Vongmasa36653902018-11-15 00:10:25 -0800228 static const C2HandleGralloc* Import(
229 const C2Handle *const handle,
230 uint32_t *width, uint32_t *height, uint32_t *format,
231 uint64_t *usage, uint32_t *stride,
232 uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) {
John Stultz653ddd12020-09-19 05:26:24 +0000233 const ExtraData *xd = GetExtraData(handle);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800234 if (xd == nullptr) {
235 return nullptr;
236 }
237 *width = xd->width;
238 *height = xd->height;
239 *format = xd->format;
240 *usage = xd->usage_lo | (uint64_t(xd->usage_hi) << 32);
241 *stride = xd->stride;
242 *generation = xd->generation;
243 *igbp_id = xd->igbp_id_lo | (uint64_t(xd->igbp_id_hi) << 32);
244 *igbp_slot = xd->igbp_slot;
245 return reinterpret_cast<const C2HandleGralloc *>(handle);
246 }
247};
248
Sungtak Lee1a67c9d2023-09-14 19:41:00 +0000249class C2HandleAhwb : public C2Handle {
250private:
251 // TODO: remove extradata and use AHardwareBuffer directly.
252 struct ExtraData {
253 uint32_t width;
254 uint32_t height;
255 uint32_t format;
256 uint32_t usage_lo;
257 uint32_t usage_hi;
258 uint32_t stride;
259 uint32_t origId_lo;
260 uint32_t origId_hi;
261 uint32_t magic;
262 };
263
264 enum {
265 NUM_INTS = sizeof(ExtraData) / sizeof(int),
266 };
267 const static uint32_t MAGIC = '\xc2hw\x00';
268
269 static
270 const ExtraData* GetExtraData(const C2Handle *const handle) {
271 if (handle == nullptr
272 || native_handle_is_invalid(handle)
273 || handle->numInts < NUM_INTS) {
274 return nullptr;
275 }
276 return reinterpret_cast<const ExtraData*>(
277 &handle->data[handle->numFds + handle->numInts - NUM_INTS]);
278 }
279
280 static
281 ExtraData *GetExtraData(C2Handle *const handle) {
282 return const_cast<ExtraData *>(GetExtraData(const_cast<const C2Handle *const>(handle)));
283 }
284
285public:
286 void getOrigId(uint64_t *origId) const {
287 const ExtraData *ed = GetExtraData(this);
288 *origId = unsigned(ed->origId_lo) | uint64_t(unsigned(ed->origId_hi)) << 32;
289 }
290
291 static bool IsValid(const C2Handle *const o) {
292 if (o == nullptr) { // null handle is always valid
293 return true;
294 }
295 const ExtraData *xd = GetExtraData(o);
296 // we cannot validate width/height/format/usage without accessing gralloc driver
297 return xd != nullptr && xd->magic == MAGIC;
298 }
299
300 static C2HandleAhwb* WrapAndMoveNativeHandle(
301 const native_handle_t *const handle,
302 uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
303 uint32_t stride, uint64_t origId) {
304 //CHECK(handle != nullptr);
305 if (native_handle_is_invalid(handle) || handle->numInts >
306 int((INT_MAX - handle->version) / sizeof(int)) - NUM_INTS - handle->numFds) {
307 return nullptr;
308 }
309 ExtraData xd = {
310 width, height, format, uint32_t(usage & 0xFFFFFFFF), uint32_t(usage >> 32),
311 stride, uint32_t(origId & 0xFFFFFFFF), uint32_t(origId >> 32), MAGIC
312 };
313 native_handle_t *res = native_handle_create(handle->numFds, handle->numInts + NUM_INTS);
314 if (res != nullptr) {
315 memcpy(&res->data, &handle->data, sizeof(int) * (handle->numFds + handle->numInts));
316 *GetExtraData(res) = xd;
317 }
318 return reinterpret_cast<C2HandleAhwb *>(res);
319 }
320
321 static C2HandleAhwb* WrapNativeHandle(
322 const native_handle_t *const handle,
323 uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
324 uint32_t stride, uint64_t origId) {
325 if (handle == nullptr) {
326 return nullptr;
327 }
328 native_handle_t *clone = native_handle_clone(handle);
329 if (clone == nullptr) {
330 return nullptr;
331 }
332 C2HandleAhwb *res = WrapAndMoveNativeHandle(
333 clone, width, height, format, usage, stride, origId);
334 if (res == nullptr) {
335 native_handle_close(clone);
336 }
337 native_handle_delete(clone);
338 return res;
339 }
340
341 static native_handle_t* UnwrapNativeHandle(
342 const C2Handle *const handle) {
343 const ExtraData *xd = GetExtraData(handle);
344 if (xd == nullptr || xd->magic != MAGIC) {
345 return nullptr;
346 }
347 native_handle_t *res = native_handle_create(handle->numFds, handle->numInts - NUM_INTS);
348 if (res != nullptr) {
349 memcpy(&res->data, &handle->data, sizeof(int) * (res->numFds + res->numInts));
350 }
351 return res;
352 }
353
354 static const C2HandleAhwb* Import(
355 const C2Handle *const handle,
356 uint32_t *width, uint32_t *height, uint32_t *format,
357 uint64_t *usage, uint32_t *stride,
358 uint64_t *origId) {
359 const ExtraData *xd = GetExtraData(handle);
360 if (xd == nullptr) {
361 return nullptr;
362 }
363 *width = xd->width;
364 *height = xd->height;
365 *format = xd->format;
366 *usage = xd->usage_lo | (uint64_t(xd->usage_hi) << 32);
367 *stride = xd->stride;
368 *origId = xd->origId_lo | (uint64_t(xd->origId_hi) << 32);
369 return reinterpret_cast<const C2HandleAhwb *>(handle);
370 }
371};
372
Praveen Chavan34493f12021-02-18 00:51:50 -0800373static
374c2_status_t Gralloc4Mapper_lock(native_handle_t *handle, uint64_t usage, const Rect& bounds,
375 C2PlanarLayout *layout, uint8_t **addr) {
376 GraphicBufferMapper &mapper = GraphicBufferMapper::get();
377
378 std::vector<ui::PlaneLayout> planes;
379 // this method is only supported on Gralloc 4 or later
380 status_t err = mapper.getPlaneLayouts(handle, &planes);
381 if (err != NO_ERROR || planes.empty()) {
382 return C2_CANNOT_DO;
383 }
384
385 uint8_t *pointer = nullptr;
386 err = mapper.lock(handle, usage, bounds, (void **)&pointer, nullptr, nullptr);
387 if (err != NO_ERROR || pointer == nullptr) {
388 return C2_CORRUPTED;
389 }
390
391 using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
392 using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
393
394 layout->type = C2PlanarLayout::TYPE_YUV;
395 layout->numPlanes = 0;
396 layout->rootPlanes = 0;
397
398 for (const ui::PlaneLayout &plane : planes) {
399 layout->rootPlanes++;
400 uint32_t lastOffsetInBits = 0;
Wonsik Kimf12bebc2022-03-24 16:25:03 -0700401 uint32_t rootIx = layout->numPlanes;
Praveen Chavan34493f12021-02-18 00:51:50 -0800402
403 for (const PlaneLayoutComponent &component : plane.components) {
404 if (!gralloc4::isStandardPlaneLayoutComponentType(component.type)) {
Praveen Chavan2c580d92022-02-24 12:23:46 -0800405 mapper.unlock(handle);
Praveen Chavan34493f12021-02-18 00:51:50 -0800406 return C2_CANNOT_DO;
407 }
408
409 uint32_t rightShiftBits = component.offsetInBits - lastOffsetInBits;
410 uint32_t allocatedDepthInBits = component.sizeInBits + rightShiftBits;
411 C2PlanarLayout::plane_index_t planeId;
412 C2PlaneInfo::channel_t channel;
413
414 switch (static_cast<PlaneLayoutComponentType>(component.type.value)) {
415 case PlaneLayoutComponentType::Y:
416 planeId = C2PlanarLayout::PLANE_Y;
417 channel = C2PlaneInfo::CHANNEL_Y;
418 break;
419 case PlaneLayoutComponentType::CB:
420 planeId = C2PlanarLayout::PLANE_U;
421 channel = C2PlaneInfo::CHANNEL_CB;
422 break;
423 case PlaneLayoutComponentType::CR:
424 planeId = C2PlanarLayout::PLANE_V;
425 channel = C2PlaneInfo::CHANNEL_CR;
426 break;
427 default:
Praveen Chavan2c580d92022-02-24 12:23:46 -0800428 mapper.unlock(handle);
Praveen Chavan34493f12021-02-18 00:51:50 -0800429 return C2_CORRUPTED;
430 }
431
432 addr[planeId] = pointer + plane.offsetInBytes + (component.offsetInBits / 8);
433 layout->planes[planeId] = {
434 channel, // channel
435 static_cast<int32_t>(plane.sampleIncrementInBits / 8), // colInc
436 static_cast<int32_t>(plane.strideInBytes), // rowInc
437 static_cast<uint32_t>(plane.horizontalSubsampling), // mColSampling
438 static_cast<uint32_t>(plane.verticalSubsampling), // mRowSampling
439 allocatedDepthInBits, // allocatedDepth (bits)
440 static_cast<uint32_t>(component.sizeInBits), // bitDepth (bits)
441 rightShiftBits, // rightShift (bits)
442 C2PlaneInfo::NATIVE, // endianness
443 rootIx, // rootIx
444 static_cast<uint32_t>(component.offsetInBits / 8), // offset (bytes)
445 };
446
447 layout->numPlanes++;
448 lastOffsetInBits = component.offsetInBits + component.sizeInBits;
Praveen Chavan34493f12021-02-18 00:51:50 -0800449 }
450 }
451 return C2_OK;
452}
453
Sungtak Lee25e33ee2023-09-15 08:06:37 +0000454static c2_status_t PopulatePlaneLayout(
455 buffer_handle_t buffer,
456 const Rect &rect,
457 uint32_t format,
458 uint64_t grallocUsage,
459 uint32_t stride,
460 C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) {
461 // 'NATIVE' on Android means LITTLE_ENDIAN
462 constexpr C2PlaneInfo::endianness_t kEndianness = C2PlaneInfo::NATIVE;
463
464 // Try to resolve IMPLEMENTATION_DEFINED format to accurate format if
465 // possible.
466 uint32_t fourCc;
467 if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED &&
468 !GraphicBufferMapper::get().getPixelFormatFourCC(buffer, &fourCc)) {
469 switch (fourCc) {
470 case DRM_FORMAT_XBGR8888:
471 format = static_cast<uint32_t>(PixelFormat4::RGBX_8888);
472 break;
473 case DRM_FORMAT_ABGR8888:
474 format = static_cast<uint32_t>(PixelFormat4::RGBA_8888);
475 break;
476 default:
477 break;
478 }
479 }
480
481 switch (format) {
482 case static_cast<uint32_t>(PixelFormat4::RGBA_1010102): {
483 // TRICKY: this is used for media as YUV444 in the case when it is queued directly to a
484 // Surface. In all other cases it is RGBA. We don't know which case it is here, so
485 // default to YUV for now.
486 void *pointer = nullptr;
487 // TODO: fence
488 status_t err = GraphicBufferMapper::get().lock(
489 const_cast<native_handle_t *>(buffer), grallocUsage, rect, &pointer);
490 if (err) {
491 ALOGE("failed transaction: lock(RGBA_1010102)");
492 return C2_CORRUPTED;
493 }
494 // treat as 32-bit values
495 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)pointer;
496 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)pointer;
497 addr[C2PlanarLayout::PLANE_V] = (uint8_t *)pointer;
498 addr[C2PlanarLayout::PLANE_A] = (uint8_t *)pointer;
499 layout->type = C2PlanarLayout::TYPE_YUVA;
500 layout->numPlanes = 4;
501 layout->rootPlanes = 1;
502 layout->planes[C2PlanarLayout::PLANE_Y] = {
503 C2PlaneInfo::CHANNEL_Y, // channel
504 4, // colInc
505 static_cast<int32_t>(4 * stride), // rowInc
506 1, // mColSampling
507 1, // mRowSampling
508 32, // allocatedDepth
509 10, // bitDepth
510 10, // rightShift
511 C2PlaneInfo::LITTLE_END, // endianness
512 C2PlanarLayout::PLANE_Y, // rootIx
513 0, // offset
514 };
515 layout->planes[C2PlanarLayout::PLANE_U] = {
516 C2PlaneInfo::CHANNEL_CB, // 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 0, // rightShift
524 C2PlaneInfo::LITTLE_END, // endianness
525 C2PlanarLayout::PLANE_Y, // rootIx
526 0, // offset
527 };
528 layout->planes[C2PlanarLayout::PLANE_V] = {
529 C2PlaneInfo::CHANNEL_CR, // 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 20, // rightShift
537 C2PlaneInfo::LITTLE_END, // endianness
538 C2PlanarLayout::PLANE_Y, // rootIx
539 0, // offset
540 };
541 layout->planes[C2PlanarLayout::PLANE_A] = {
542 C2PlaneInfo::CHANNEL_A, // channel
543 4, // colInc
544 static_cast<int32_t>(4 * stride), // rowInc
545 1, // mColSampling
546 1, // mRowSampling
547 32, // allocatedDepth
548 2, // bitDepth
549 30, // rightShift
550 C2PlaneInfo::LITTLE_END, // endianness
551 C2PlanarLayout::PLANE_Y, // rootIx
552 0, // offset
553 };
554 break;
555 }
556
557 case static_cast<uint32_t>(PixelFormat4::RGBA_8888):
558 // TODO: alpha channel
559 // fall-through
560 case static_cast<uint32_t>(PixelFormat4::RGBX_8888): {
561 void *pointer = nullptr;
562 // TODO: fence
563 status_t err = GraphicBufferMapper::get().lock(
564 const_cast<native_handle_t*>(buffer), grallocUsage, rect, &pointer);
565 if (err) {
566 ALOGE("failed transaction: lock(RGBA_8888)");
567 return C2_CORRUPTED;
568 }
569 addr[C2PlanarLayout::PLANE_R] = (uint8_t *)pointer;
570 addr[C2PlanarLayout::PLANE_G] = (uint8_t *)pointer + 1;
571 addr[C2PlanarLayout::PLANE_B] = (uint8_t *)pointer + 2;
572 layout->type = C2PlanarLayout::TYPE_RGB;
573 layout->numPlanes = 3;
574 layout->rootPlanes = 1;
575 layout->planes[C2PlanarLayout::PLANE_R] = {
576 C2PlaneInfo::CHANNEL_R, // channel
577 4, // colInc
578 static_cast<int32_t>(4 * stride), // rowInc
579 1, // mColSampling
580 1, // mRowSampling
581 8, // allocatedDepth
582 8, // bitDepth
583 0, // rightShift
584 C2PlaneInfo::NATIVE, // endianness
585 C2PlanarLayout::PLANE_R, // rootIx
586 0, // offset
587 };
588 layout->planes[C2PlanarLayout::PLANE_G] = {
589 C2PlaneInfo::CHANNEL_G, // 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 1, // offset
600 };
601 layout->planes[C2PlanarLayout::PLANE_B] = {
602 C2PlaneInfo::CHANNEL_B, // 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 2, // offset
613 };
614 break;
615 }
616
617 case static_cast<uint32_t>(PixelFormat4::BLOB): {
618 void *pointer = nullptr;
619 // TODO: fence
620 status_t err = GraphicBufferMapper::get().lock(
621 const_cast<native_handle_t*>(buffer), grallocUsage, rect, &pointer);
622 if (err) {
623 ALOGE("failed transaction: lock(BLOB)");
624 return C2_CORRUPTED;
625 }
626 *addr = (uint8_t *)pointer;
627 break;
628 }
629
630 case static_cast<uint32_t>(PixelFormat4::YCBCR_422_SP):
631 // fall-through
632 case static_cast<uint32_t>(PixelFormat4::YCRCB_420_SP):
633 // fall-through
634 case static_cast<uint32_t>(PixelFormat4::YCBCR_422_I):
635 // fall-through
636 case static_cast<uint32_t>(PixelFormat4::YCBCR_420_888):
637 // fall-through
638 case static_cast<uint32_t>(PixelFormat4::YV12): {
639 android_ycbcr ycbcrLayout;
640
641 status_t err = GraphicBufferMapper::get().lockYCbCr(
642 const_cast<native_handle_t*>(buffer), grallocUsage, rect, &ycbcrLayout);
643 if (err) {
644 ALOGE("failed transaction: lockYCbCr (err=%d)", err);
645 return C2_CORRUPTED;
646 }
647 if (!ycbcrLayout.y || !ycbcrLayout.cb || !ycbcrLayout.cr
648 || ycbcrLayout.ystride == 0
649 || ycbcrLayout.cstride == 0
650 || ycbcrLayout.chroma_step == 0) {
651 ALOGE("invalid layout: lockYCbCr (y=%s cb=%s cr=%s "
652 "ystride=%zu cstride=%zu chroma_step=%zu)",
653 ycbcrLayout.y ? "(non-null)" : "(null)",
654 ycbcrLayout.cb ? "(non-null)" : "(null)",
655 ycbcrLayout.cr ? "(non-null)" : "(null)",
656 ycbcrLayout.ystride, ycbcrLayout.cstride, ycbcrLayout.chroma_step);
657 return C2_CORRUPTED;
658 }
659
660 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)ycbcrLayout.y;
661 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)ycbcrLayout.cb;
662 addr[C2PlanarLayout::PLANE_V] = (uint8_t *)ycbcrLayout.cr;
663 layout->type = C2PlanarLayout::TYPE_YUV;
664 layout->numPlanes = 3;
665 layout->rootPlanes = 3;
666 layout->planes[C2PlanarLayout::PLANE_Y] = {
667 C2PlaneInfo::CHANNEL_Y, // channel
668 1, // colInc
669 (int32_t)ycbcrLayout.ystride, // rowInc
670 1, // mColSampling
671 1, // mRowSampling
672 8, // allocatedDepth
673 8, // bitDepth
674 0, // rightShift
675 C2PlaneInfo::NATIVE, // endianness
676 C2PlanarLayout::PLANE_Y, // rootIx
677 0, // offset
678 };
679 layout->planes[C2PlanarLayout::PLANE_U] = {
680 C2PlaneInfo::CHANNEL_CB, // channel
681 (int32_t)ycbcrLayout.chroma_step, // colInc
682 (int32_t)ycbcrLayout.cstride, // rowInc
683 2, // mColSampling
684 2, // mRowSampling
685 8, // allocatedDepth
686 8, // bitDepth
687 0, // rightShift
688 C2PlaneInfo::NATIVE, // endianness
689 C2PlanarLayout::PLANE_U, // rootIx
690 0, // offset
691 };
692 layout->planes[C2PlanarLayout::PLANE_V] = {
693 C2PlaneInfo::CHANNEL_CR, // 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_V, // rootIx
703 0, // offset
704 };
705 break;
706 }
707
708 case static_cast<uint32_t>(PixelFormat4::YCBCR_P010): {
709 // In Android T, P010 is relaxed to allow arbitrary stride for the Y and UV planes,
710 // try locking with the gralloc4 mapper first.
711 c2_status_t status = Gralloc4Mapper_lock(
712 const_cast<native_handle_t*>(buffer), grallocUsage, rect, layout, addr);
713 if (status == C2_OK) {
714 break;
715 }
716
717 void *pointer = nullptr;
718 status_t err = GraphicBufferMapper::get().lock(
719 const_cast<native_handle_t *>(buffer), grallocUsage, rect, &pointer);
720 if (err) {
721 ALOGE("failed transaction: lock(YCBCR_P010)");
722 return C2_CORRUPTED;
723 }
724 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)pointer;
725 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)pointer + stride * 2 * rect.height();
726 addr[C2PlanarLayout::PLANE_V] = addr[C2PlanarLayout::PLANE_U] + 2;
727 layout->type = C2PlanarLayout::TYPE_YUV;
728 layout->numPlanes = 3;
729 layout->rootPlanes = 2;
730 layout->planes[C2PlanarLayout::PLANE_Y] = {
731 C2PlaneInfo::CHANNEL_Y, // channel
732 2, // colInc
733 static_cast<int32_t>(2 * stride), // rowInc
734 1, // mColSampling
735 1, // mRowSampling
736 16, // allocatedDepth
737 10, // bitDepth
738 6, // rightShift
739 kEndianness, // endianness
740 C2PlanarLayout::PLANE_Y, // rootIx
741 0, // offset
742 };
743 layout->planes[C2PlanarLayout::PLANE_U] = {
744 C2PlaneInfo::CHANNEL_CB, // channel
745 4, // colInc
746 static_cast<int32_t>(2 * stride), // rowInc
747 2, // mColSampling
748 2, // mRowSampling
749 16, // allocatedDepth
750 10, // bitDepth
751 6, // rightShift
752 kEndianness, // endianness
753 C2PlanarLayout::PLANE_U, // rootIx
754 0, // offset
755 };
756 layout->planes[C2PlanarLayout::PLANE_V] = {
757 C2PlaneInfo::CHANNEL_CR, // 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 2, // offset
768 };
769 break;
770 }
771
772 default: {
773 // We don't know what it is, let's try to lock it with gralloc4
774 android_ycbcr ycbcrLayout;
775 if (isAtLeastT()) {
776 c2_status_t status = Gralloc4Mapper_lock(
777 const_cast<native_handle_t*>(buffer), grallocUsage, rect, layout, addr);
778 if (status == C2_OK) {
779 break;
780 }
781 }
782
783 // fallback to lockYCbCr
784 status_t err = GraphicBufferMapper::get().lockYCbCr(
785 const_cast<native_handle_t*>(buffer), grallocUsage, rect, &ycbcrLayout);
786 if (err == OK && ycbcrLayout.y && ycbcrLayout.cb && ycbcrLayout.cr
787 && ycbcrLayout.ystride > 0
788 && ycbcrLayout.cstride > 0
789 && ycbcrLayout.chroma_step > 0) {
790 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)ycbcrLayout.y;
791 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)ycbcrLayout.cb;
792 addr[C2PlanarLayout::PLANE_V] = (uint8_t *)ycbcrLayout.cr;
793 layout->type = C2PlanarLayout::TYPE_YUV;
794 layout->numPlanes = 3;
795 layout->rootPlanes = 3;
796 layout->planes[C2PlanarLayout::PLANE_Y] = {
797 C2PlaneInfo::CHANNEL_Y, // channel
798 1, // colInc
799 (int32_t)ycbcrLayout.ystride, // rowInc
800 1, // mColSampling
801 1, // mRowSampling
802 8, // allocatedDepth
803 8, // bitDepth
804 0, // rightShift
805 C2PlaneInfo::NATIVE, // endianness
806 C2PlanarLayout::PLANE_Y, // rootIx
807 0, // offset
808 };
809 layout->planes[C2PlanarLayout::PLANE_U] = {
810 C2PlaneInfo::CHANNEL_CB, // channel
811 (int32_t)ycbcrLayout.chroma_step, // colInc
812 (int32_t)ycbcrLayout.cstride, // rowInc
813 2, // mColSampling
814 2, // mRowSampling
815 8, // allocatedDepth
816 8, // bitDepth
817 0, // rightShift
818 C2PlaneInfo::NATIVE, // endianness
819 C2PlanarLayout::PLANE_U, // rootIx
820 0, // offset
821 };
822 layout->planes[C2PlanarLayout::PLANE_V] = {
823 C2PlaneInfo::CHANNEL_CR, // 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_V, // rootIx
833 0, // offset
834 };
835 break;
836 }
837
838 // We really don't know what this is; lock the buffer and pass it through ---
839 // the client may know how to interpret it.
840
841 // unlock previous allocation if it was successful
842 if (err == OK) {
843 err = GraphicBufferMapper::get().unlock(buffer);
844 if (err) {
845 ALOGE("failed transaction: unlock");
846 return C2_CORRUPTED;
847 }
848 }
849
850 void *pointer = nullptr;
851 err = GraphicBufferMapper::get().lock(
852 const_cast<native_handle_t *>(buffer), grallocUsage, rect, &pointer);
853 if (err) {
854 ALOGE("failed transaction: lock(??? %x)", format);
855 return C2_CORRUPTED;
856 }
857 addr[0] = (uint8_t *)pointer;
858 layout->type = C2PlanarLayout::TYPE_UNKNOWN;
859 layout->numPlanes = 1;
860 layout->rootPlanes = 1;
861 layout->planes[0] = {
862 // TODO: CHANNEL_UNKNOWN?
863 C2PlaneInfo::channel_t(0xFF), // channel
864 1, // colInc
865 int32_t(stride), // rowInc
866 1, // mColSampling
867 1, // mRowSampling
868 8, // allocatedDepth
869 8, // bitDepth
870 0, // rightShift
871 C2PlaneInfo::NATIVE, // endianness
872 0, // rootIx
873 0, // offset
874 };
875 break;
876 }
877 }
878 return C2_OK;
879}
880
881static void HandleInterleavedPlanes(
882 C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) {
883 if (layout->type == C2PlanarLayout::TYPE_YUV && layout->rootPlanes == 3) {
884 intptr_t uvOffset = addr[C2PlanarLayout::PLANE_V] - addr[C2PlanarLayout::PLANE_U];
885 intptr_t uvColInc = layout->planes[C2PlanarLayout::PLANE_U].colInc;
886 if (uvOffset > 0 && uvOffset < uvColInc) {
887 layout->rootPlanes = 2;
888 layout->planes[C2PlanarLayout::PLANE_V].rootIx = C2PlanarLayout::PLANE_U;
889 layout->planes[C2PlanarLayout::PLANE_V].offset = uvOffset;
890 } else if (uvOffset < 0 && uvOffset > -uvColInc) {
891 layout->rootPlanes = 2;
892 layout->planes[C2PlanarLayout::PLANE_U].rootIx = C2PlanarLayout::PLANE_V;
893 layout->planes[C2PlanarLayout::PLANE_U].offset = -uvOffset;
894 }
895 }
896}
897
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700898} // unnamed namespace
899
Praveen Chavan34493f12021-02-18 00:51:50 -0800900
Pawin Vongmasa36653902018-11-15 00:10:25 -0800901native_handle_t *UnwrapNativeCodec2GrallocHandle(const C2Handle *const handle) {
902 return C2HandleGralloc::UnwrapNativeHandle(handle);
903}
904
Pawin Vongmasa36653902018-11-15 00:10:25 -0800905C2Handle *WrapNativeCodec2GrallocHandle(
906 const native_handle_t *const handle,
907 uint32_t width, uint32_t height, uint32_t format, uint64_t usage, uint32_t stride,
908 uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
909 return C2HandleGralloc::WrapNativeHandle(handle, width, height, format, usage, stride,
910 generation, igbp_id, igbp_slot);
911}
912
Songyue Han1e6769b2023-08-30 18:09:27 +0000913uint32_t ExtractFormatFromCodec2GrallocHandle(const C2Handle *const handle) {
914 return C2HandleGralloc::getPixelFormat(handle);
915}
916
Sungtak Lee08515812019-06-05 11:16:32 -0700917bool MigrateNativeCodec2GrallocHandle(
918 native_handle_t *handle,
919 uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
920 return C2HandleGralloc::MigrateNativeHandle(handle, generation, igbp_id, igbp_slot);
921}
922
923
Sungtak Lee1a67c9d2023-09-14 19:41:00 +0000924
Pawin Vongmasa36653902018-11-15 00:10:25 -0800925class C2AllocationGralloc : public C2GraphicAllocation {
926public:
927 virtual ~C2AllocationGralloc() override;
928
929 virtual c2_status_t map(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900930 C2Rect c2Rect, C2MemoryUsage usage, C2Fence *fence,
Pawin Vongmasa36653902018-11-15 00:10:25 -0800931 C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) override;
932 virtual c2_status_t unmap(
933 uint8_t **addr /* nonnull */, C2Rect rect, C2Fence *fence /* nullable */) override;
934 virtual C2Allocator::id_t getAllocatorId() const override { return mAllocatorId; }
935 virtual const C2Handle *handle() const override { return mLockedHandle ? : mHandle; }
936 virtual bool equals(const std::shared_ptr<const C2GraphicAllocation> &other) const override;
937
938 // internal methods
939 // |handle| will be moved.
Marissa Wall2a24a302019-11-25 11:19:18 -0800940
Pawin Vongmasa36653902018-11-15 00:10:25 -0800941 C2AllocationGralloc(
Marissa Wall2a24a302019-11-25 11:19:18 -0800942 uint32_t width, uint32_t height,
943 uint32_t format, uint32_t layerCount,
944 uint64_t grallocUsage, uint32_t stride,
Marissa Wall8806edc2019-06-21 09:50:47 -0700945 hidl_handle &hidlHandle,
946 const C2HandleGralloc *const handle,
947 C2Allocator::id_t allocatorId);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800948 int dup() const;
949 c2_status_t status() const;
950
951private:
Marissa Wall2a24a302019-11-25 11:19:18 -0800952 const uint32_t mWidth;
953 const uint32_t mHeight;
954 const uint32_t mFormat;
955 const uint32_t mLayerCount;
956 const uint64_t mGrallocUsage;
957 const uint32_t mStride;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800958 const hidl_handle mHidlHandle;
959 const C2HandleGralloc *mHandle;
960 buffer_handle_t mBuffer;
961 const C2HandleGralloc *mLockedHandle;
962 bool mLocked;
963 C2Allocator::id_t mAllocatorId;
964 std::mutex mMappedLock;
965};
966
967C2AllocationGralloc::C2AllocationGralloc(
Marissa Wall2a24a302019-11-25 11:19:18 -0800968 uint32_t width, uint32_t height,
969 uint32_t format, uint32_t layerCount,
970 uint64_t grallocUsage, uint32_t stride,
Pawin Vongmasa36653902018-11-15 00:10:25 -0800971 hidl_handle &hidlHandle,
972 const C2HandleGralloc *const handle,
973 C2Allocator::id_t allocatorId)
Marissa Wall2a24a302019-11-25 11:19:18 -0800974 : C2GraphicAllocation(width, height),
975 mWidth(width),
976 mHeight(height),
977 mFormat(format),
978 mLayerCount(layerCount),
979 mGrallocUsage(grallocUsage),
980 mStride(stride),
Marissa Wall8806edc2019-06-21 09:50:47 -0700981 mHidlHandle(std::move(hidlHandle)),
982 mHandle(handle),
983 mBuffer(nullptr),
984 mLockedHandle(nullptr),
985 mLocked(false),
986 mAllocatorId(allocatorId) {
987}
988
Pawin Vongmasa36653902018-11-15 00:10:25 -0800989C2AllocationGralloc::~C2AllocationGralloc() {
Yichi Chenfa94a3b2018-12-08 00:06:25 +0800990 if (mBuffer && mLocked) {
Sungtak Lee1a67c9d2023-09-14 19:41:00 +0000991 // implementation ignores address and rect
Pawin Vongmasa36653902018-11-15 00:10:25 -0800992 uint8_t* addr[C2PlanarLayout::MAX_NUM_PLANES] = {};
993 unmap(addr, C2Rect(), nullptr);
994 }
Yichi Chenfa94a3b2018-12-08 00:06:25 +0800995 if (mBuffer) {
Marissa Wall2a24a302019-11-25 11:19:18 -0800996 status_t err = GraphicBufferMapper::get().freeBuffer(mBuffer);
997 if (err) {
998 ALOGE("failed transaction: freeBuffer");
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700999 }
Yichi Chenfa94a3b2018-12-08 00:06:25 +08001000 }
1001 if (mHandle) {
1002 native_handle_delete(
1003 const_cast<native_handle_t *>(reinterpret_cast<const native_handle_t *>(mHandle)));
1004 }
Sungtak Lee2729dcf2019-01-18 13:15:07 -08001005 if (mLockedHandle) {
1006 native_handle_delete(
1007 const_cast<native_handle_t *>(
1008 reinterpret_cast<const native_handle_t *>(mLockedHandle)));
1009 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001010}
1011
1012c2_status_t C2AllocationGralloc::map(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +09001013 C2Rect c2Rect, C2MemoryUsage usage, C2Fence *fence,
Pawin Vongmasa36653902018-11-15 00:10:25 -08001014 C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) {
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +09001015 const Rect rect{(int32_t)c2Rect.left, (int32_t)c2Rect.top,
1016 (int32_t)(c2Rect.left + c2Rect.width) /* right */,
1017 (int32_t)(c2Rect.top + c2Rect.height) /* bottom */};
1018
Pawin Vongmasa36653902018-11-15 00:10:25 -08001019 uint64_t grallocUsage = static_cast<C2AndroidMemoryUsage>(usage).asGrallocUsage();
1020 ALOGV("mapping buffer with usage %#llx => %#llx",
1021 (long long)usage.expected, (long long)grallocUsage);
1022
1023 // TODO
Marissa Wall2a24a302019-11-25 11:19:18 -08001024 (void)fence;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001025
1026 std::lock_guard<std::mutex> lock(mMappedLock);
1027 if (mBuffer && mLocked) {
1028 ALOGD("already mapped");
1029 return C2_DUPLICATE;
1030 }
1031 if (!layout || !addr) {
1032 ALOGD("wrong param");
1033 return C2_BAD_VALUE;
1034 }
1035
Pawin Vongmasa36653902018-11-15 00:10:25 -08001036 if (!mBuffer) {
Marissa Wall2a24a302019-11-25 11:19:18 -08001037 status_t err = GraphicBufferMapper::get().importBuffer(
1038 mHidlHandle.getNativeHandle(), mWidth, mHeight, mLayerCount,
1039 mFormat, mGrallocUsage, mStride, &mBuffer);
1040 if (err) {
1041 ALOGE("failed transaction: importBuffer");
1042 return C2_CORRUPTED;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001043 }
1044 if (mBuffer == nullptr) {
1045 ALOGD("importBuffer returned null buffer");
1046 return C2_CORRUPTED;
1047 }
1048 uint32_t generation = 0;
1049 uint64_t igbp_id = 0;
1050 uint32_t igbp_slot = 0;
1051 if (mHandle) {
1052 mHandle->getIgbpData(&generation, &igbp_id, &igbp_slot);
1053 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001054
Marissa Wall2a24a302019-11-25 11:19:18 -08001055 mLockedHandle = C2HandleGralloc::WrapAndMoveNativeHandle(
1056 mBuffer, mWidth, mHeight, mFormat, mGrallocUsage,
1057 mStride, generation, igbp_id, igbp_slot);
Marissa Wall8806edc2019-06-21 09:50:47 -07001058 }
Praveen Chavan34493f12021-02-18 00:51:50 -08001059
Sungtak Lee25e33ee2023-09-15 08:06:37 +00001060 c2_status_t ret = PopulatePlaneLayout(
1061 mBuffer, rect, mFormat, grallocUsage, mStride, layout, addr);
1062 if (ret != C2_OK) {
1063 return ret;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001064 }
1065 mLocked = true;
1066
Sungtak Lee25e33ee2023-09-15 08:06:37 +00001067 HandleInterleavedPlanes(layout, addr);
Wonsik Kimf12bebc2022-03-24 16:25:03 -07001068
1069 ALOGV("C2AllocationGralloc::map: layout: type=%d numPlanes=%d rootPlanes=%d",
1070 layout->type, layout->numPlanes, layout->rootPlanes);
1071 for (int i = 0; i < layout->numPlanes; ++i) {
1072 const C2PlaneInfo &plane = layout->planes[i];
1073 ALOGV("C2AllocationGralloc::map: plane[%d]: colInc=%d rowInc=%d rootIx=%u offset=%u",
1074 i, plane.colInc, plane.rowInc, plane.rootIx, plane.offset);
1075 }
1076
Pawin Vongmasa36653902018-11-15 00:10:25 -08001077 return C2_OK;
1078}
1079
1080c2_status_t C2AllocationGralloc::unmap(
1081 uint8_t **addr, C2Rect rect, C2Fence *fence /* nullable */) {
1082 // TODO: check addr and size, use fence
1083 (void)addr;
1084 (void)rect;
Marissa Wall2a24a302019-11-25 11:19:18 -08001085 (void)fence;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001086
1087 std::lock_guard<std::mutex> lock(mMappedLock);
Marissa Wall2a24a302019-11-25 11:19:18 -08001088 // TODO: fence
1089 status_t err = GraphicBufferMapper::get().unlock(mBuffer);
1090 if (err) {
1091 ALOGE("failed transaction: unlock");
1092 return C2_CORRUPTED;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001093 }
Marissa Wall2a24a302019-11-25 11:19:18 -08001094
1095 mLocked = false;
1096 return C2_OK;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001097}
1098
1099bool C2AllocationGralloc::equals(const std::shared_ptr<const C2GraphicAllocation> &other) const {
1100 return other && other->handle() == handle();
1101}
1102
1103/* ===================================== GRALLOC ALLOCATOR ==================================== */
1104class C2AllocatorGralloc::Impl {
1105public:
1106 Impl(id_t id, bool bufferQueue);
1107
1108 id_t getId() const {
1109 return mTraits->id;
1110 }
1111
1112 C2String getName() const {
1113 return mTraits->name;
1114 }
1115
1116 std::shared_ptr<const C2Allocator::Traits> getTraits() const {
1117 return mTraits;
1118 }
1119
1120 c2_status_t newGraphicAllocation(
1121 uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
1122 std::shared_ptr<C2GraphicAllocation> *allocation);
1123
1124 c2_status_t priorGraphicAllocation(
1125 const C2Handle *handle,
1126 std::shared_ptr<C2GraphicAllocation> *allocation);
1127
1128 c2_status_t status() const { return mInit; }
1129
1130private:
1131 std::shared_ptr<C2Allocator::Traits> mTraits;
1132 c2_status_t mInit;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001133 const bool mBufferQueue;
1134};
1135
1136void _UnwrapNativeCodec2GrallocMetadata(
1137 const C2Handle *const handle,
1138 uint32_t *width, uint32_t *height, uint32_t *format,uint64_t *usage, uint32_t *stride,
1139 uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) {
1140 (void)C2HandleGralloc::Import(handle, width, height, format, usage, stride,
1141 generation, igbp_id, igbp_slot);
1142}
1143
1144C2AllocatorGralloc::Impl::Impl(id_t id, bool bufferQueue)
1145 : mInit(C2_OK), mBufferQueue(bufferQueue) {
1146 // TODO: get this from allocator
1147 C2MemoryUsage minUsage = { 0, 0 }, maxUsage = { ~(uint64_t)0, ~(uint64_t)0 };
1148 Traits traits = { "android.allocator.gralloc", id, C2Allocator::GRAPHIC, minUsage, maxUsage };
1149 mTraits = std::make_shared<C2Allocator::Traits>(traits);
Pawin Vongmasa36653902018-11-15 00:10:25 -08001150}
1151
1152c2_status_t C2AllocatorGralloc::Impl::newGraphicAllocation(
1153 uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
1154 std::shared_ptr<C2GraphicAllocation> *allocation) {
1155 uint64_t grallocUsage = static_cast<C2AndroidMemoryUsage>(usage).asGrallocUsage();
1156 ALOGV("allocating buffer with usage %#llx => %#llx",
1157 (long long)usage.expected, (long long)grallocUsage);
1158
Marissa Wall2a24a302019-11-25 11:19:18 -08001159 buffer_handle_t buffer;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001160
Marissa Wall2a24a302019-11-25 11:19:18 -08001161 uint32_t stride = 0;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001162
Marissa Wall2a24a302019-11-25 11:19:18 -08001163 status_t err = GraphicBufferAllocator::get().allocateRawHandle(width, height, format,
1164 1u /* layer count */, grallocUsage, &buffer, &stride, "C2GrallocAllocation");
1165 if (err) {
1166 ALOGE("failed transaction: allocate");
1167 return C2_CORRUPTED;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001168 }
Marissa Wall2a24a302019-11-25 11:19:18 -08001169
1170 hidl_handle hidlHandle;
1171 hidlHandle.setTo(const_cast<native_handle_t*>(buffer), true);
1172
1173 allocation->reset(new C2AllocationGralloc(
1174 width, height, format, 1u /* layer count */, grallocUsage, stride, hidlHandle,
1175 C2HandleGralloc::WrapAndMoveNativeHandle(
1176 hidlHandle, width, height,
1177 format, grallocUsage, stride,
1178 0, 0, mBufferQueue ? ~0 : 0),
1179 mTraits->id));
1180 return C2_OK;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001181}
1182
1183c2_status_t C2AllocatorGralloc::Impl::priorGraphicAllocation(
1184 const C2Handle *handle,
1185 std::shared_ptr<C2GraphicAllocation> *allocation) {
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001186
Marissa Wall2a24a302019-11-25 11:19:18 -08001187 uint32_t generation;
1188 uint64_t igbp_id;
1189 uint32_t igbp_slot;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001190
Marissa Wall2a24a302019-11-25 11:19:18 -08001191 uint32_t width;
1192 uint32_t height;
1193 uint32_t format;
1194 uint32_t layerCount = 1;
1195 uint64_t grallocUsage;
1196 uint32_t stride;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001197
Marissa Wall2a24a302019-11-25 11:19:18 -08001198 const C2HandleGralloc *grallocHandle = C2HandleGralloc::Import(
1199 handle, &width, &height, &format, &grallocUsage, &stride,
1200 &generation, &igbp_id, &igbp_slot);
1201 if (grallocHandle == nullptr) {
1202 return C2_BAD_VALUE;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001203 }
Marissa Wall2a24a302019-11-25 11:19:18 -08001204
1205 hidl_handle hidlHandle;
1206 hidlHandle.setTo(C2HandleGralloc::UnwrapNativeHandle(grallocHandle), true);
1207
1208 allocation->reset(new C2AllocationGralloc(
1209 width, height, format, layerCount,
1210 grallocUsage, stride, hidlHandle, grallocHandle, mTraits->id));
1211 return C2_OK;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001212}
1213
1214C2AllocatorGralloc::C2AllocatorGralloc(id_t id, bool bufferQueue)
1215 : mImpl(new Impl(id, bufferQueue)) {}
1216
1217C2AllocatorGralloc::~C2AllocatorGralloc() { delete mImpl; }
1218
1219C2Allocator::id_t C2AllocatorGralloc::getId() const {
1220 return mImpl->getId();
1221}
1222
1223C2String C2AllocatorGralloc::getName() const {
1224 return mImpl->getName();
1225}
1226
1227std::shared_ptr<const C2Allocator::Traits> C2AllocatorGralloc::getTraits() const {
1228 return mImpl->getTraits();
1229}
1230
1231c2_status_t C2AllocatorGralloc::newGraphicAllocation(
1232 uint32_t width, uint32_t height, uint32_t format, C2MemoryUsage usage,
1233 std::shared_ptr<C2GraphicAllocation> *allocation) {
1234 return mImpl->newGraphicAllocation(width, height, format, usage, allocation);
1235}
1236
1237c2_status_t C2AllocatorGralloc::priorGraphicAllocation(
1238 const C2Handle *handle,
1239 std::shared_ptr<C2GraphicAllocation> *allocation) {
1240 return mImpl->priorGraphicAllocation(handle, allocation);
1241}
1242
1243c2_status_t C2AllocatorGralloc::status() const {
1244 return mImpl->status();
1245}
1246
John Stultz653ddd12020-09-19 05:26:24 +00001247// static
1248bool C2AllocatorGralloc::CheckHandle(const C2Handle* const o) {
1249 return C2HandleGralloc::IsValid(o);
Pawin Vongmasa36653902018-11-15 00:10:25 -08001250}
1251
Sungtak Lee1a67c9d2023-09-14 19:41:00 +00001252
1253native_handle_t *UnwrapNativeCodec2AhwbHandle(const C2Handle *const handle) {
1254 return C2HandleAhwb::UnwrapNativeHandle(handle);
1255}
1256
1257C2Handle *WrapNativeCodec2AhwbHandle(
1258 const native_handle_t *const handle,
1259 uint32_t width, uint32_t height, uint32_t format, uint64_t usage, uint32_t stride,
1260 uint64_t origId) {
1261 return C2HandleAhwb::WrapNativeHandle(handle, width, height, format, usage, stride,
1262 origId);
1263}
1264
1265class C2AllocationAhwb : public C2GraphicAllocation {
1266public:
1267 virtual ~C2AllocationAhwb() override;
1268
1269 virtual c2_status_t map(
1270 C2Rect c2Rect, C2MemoryUsage usage, C2Fence *fence,
1271 C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) override;
1272 virtual c2_status_t unmap(
1273 uint8_t **addr /* nonnull */, C2Rect rect, C2Fence *fence /* nullable */) override;
1274 virtual C2Allocator::id_t getAllocatorId() const override { return mAllocatorId; }
1275 virtual const C2Handle *handle() const override { return mLockedHandle ? : mHandle; }
1276 virtual bool equals(const std::shared_ptr<const C2GraphicAllocation> &other) const override;
1277
1278 // internal methods
1279 // |handle| will be moved.
1280
1281 C2AllocationAhwb(
1282 uint32_t width, uint32_t height,
1283 uint32_t format, uint32_t layerCount,
1284 uint64_t grallocUsage, uint32_t stride,
1285 const C2HandleAhwb *const handle,
1286 C2Allocator::id_t allocatorId);
1287 int dup() const;
1288 c2_status_t status() const;
1289
1290private:
1291 const uint32_t mWidth;
1292 const uint32_t mHeight;
1293 const uint32_t mFormat;
1294 const uint32_t mLayerCount;
1295 const uint64_t mGrallocUsage;
1296 const uint32_t mStride;
1297 const native_handle_t *mRawHandle;
1298 const C2HandleAhwb *mHandle;
1299 buffer_handle_t mBuffer;
1300 const C2HandleAhwb *mLockedHandle;
1301 bool mLocked;
1302 C2Allocator::id_t mAllocatorId;
1303 std::mutex mMappedLock;
1304};
1305
1306C2AllocationAhwb::C2AllocationAhwb(
1307 uint32_t width, uint32_t height,
1308 uint32_t format, uint32_t layerCount,
1309 uint64_t grallocUsage, uint32_t stride,
1310 const C2HandleAhwb *const handle,
1311 C2Allocator::id_t allocatorId)
1312 : C2GraphicAllocation(width, height),
1313 mWidth(width),
1314 mHeight(height),
1315 mFormat(format),
1316 mLayerCount(layerCount),
1317 mGrallocUsage(grallocUsage),
1318 mStride(stride),
1319 mRawHandle(C2HandleAhwb::UnwrapNativeHandle(handle)),
1320 mHandle(handle),
1321 mBuffer(nullptr),
1322 mLockedHandle(nullptr),
1323 mLocked(false),
1324 mAllocatorId(allocatorId) {
1325}
1326
1327C2AllocationAhwb::~C2AllocationAhwb() {
1328 if (mBuffer && mLocked) {
1329 // implementation ignores address and rect
1330 uint8_t* addr[C2PlanarLayout::MAX_NUM_PLANES] = {};
1331 unmap(addr, C2Rect(), nullptr);
1332 }
1333 if (mBuffer) {
1334 status_t err = GraphicBufferMapper::get().freeBuffer(mBuffer);
1335 if (err) {
1336 ALOGE("failed transaction: freeBuffer");
1337 }
1338 }
1339 if (mRawHandle) {
1340 native_handle_close(
1341 const_cast<native_handle_t *>(
1342 reinterpret_cast<const native_handle_t *>(mRawHandle)));
1343 native_handle_delete(
1344 const_cast<native_handle_t *>(
1345 reinterpret_cast<const native_handle_t *>(mRawHandle)));
1346 }
1347 if (mHandle) {
1348 native_handle_delete(
1349 const_cast<native_handle_t *>(reinterpret_cast<const native_handle_t *>(mHandle)));
1350 }
1351 if (mLockedHandle) {
1352 native_handle_delete(
1353 const_cast<native_handle_t *>(
1354 reinterpret_cast<const native_handle_t *>(mLockedHandle)));
1355 }
1356}
1357
1358c2_status_t C2AllocationAhwb::map(
1359 C2Rect c2Rect, C2MemoryUsage usage, C2Fence *fence,
1360 C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) {
1361 const Rect rect{(int32_t)c2Rect.left, (int32_t)c2Rect.top,
1362 (int32_t)(c2Rect.left + c2Rect.width) /* right */,
1363 (int32_t)(c2Rect.top + c2Rect.height) /* bottom */};
1364
1365 uint64_t grallocUsage = static_cast<C2AndroidMemoryUsage>(usage).asGrallocUsage();
1366 ALOGV("mapping buffer with usage %#llx => %#llx",
1367 (long long)usage.expected, (long long)grallocUsage);
1368
1369 // TODO
1370 (void)fence;
1371
1372 std::lock_guard<std::mutex> lock(mMappedLock);
1373 if (mBuffer && mLocked) {
1374 ALOGD("already mapped");
1375 return C2_DUPLICATE;
1376 }
1377 if (!layout || !addr) {
1378 ALOGD("wrong param");
1379 return C2_BAD_VALUE;
1380 }
1381
1382 if (!mBuffer) {
1383 // TODO: libui/libgui dependency removal (b/214400477)
1384 status_t err = GraphicBufferMapper::get().importBuffer(
1385 mRawHandle, mWidth, mHeight, mLayerCount,
1386 mFormat, mGrallocUsage, mStride, &mBuffer);
1387 if (err) {
1388 ALOGE("failed transaction: importBuffer");
1389 return C2_CORRUPTED;
1390 }
1391 if (mBuffer == nullptr) {
1392 ALOGD("importBuffer returned null buffer");
1393 return C2_CORRUPTED;
1394 }
1395 uint64_t origId = 0;
1396 if (mHandle) {
1397 mHandle->getOrigId(&origId);
1398 }
1399
1400 mLockedHandle = C2HandleAhwb::WrapAndMoveNativeHandle(
1401 mBuffer, mWidth, mHeight, mFormat, mGrallocUsage,
1402 mStride, origId);
1403 }
1404
1405 c2_status_t ret = PopulatePlaneLayout(
1406 mBuffer, rect, mFormat, grallocUsage, mStride, layout, addr);
1407 if (ret != C2_OK) {
1408 return ret;
1409 }
1410 mLocked = true;
1411
1412 HandleInterleavedPlanes(layout, addr);
1413
1414 ALOGV("C2AllocationGralloc::map: layout: type=%d numPlanes=%d rootPlanes=%d",
1415 layout->type, layout->numPlanes, layout->rootPlanes);
1416 for (int i = 0; i < layout->numPlanes; ++i) {
1417 const C2PlaneInfo &plane = layout->planes[i];
1418 ALOGV("C2AllocationGralloc::map: plane[%d]: colInc=%d rowInc=%d rootIx=%u offset=%u",
1419 i, plane.colInc, plane.rowInc, plane.rootIx, plane.offset);
1420 }
1421
1422 return C2_OK;
1423}
1424
1425c2_status_t C2AllocationAhwb::unmap(
1426 uint8_t **addr, C2Rect rect, C2Fence *fence /* nullable */) {
1427 // TODO: check addr and size, use fence
1428 (void)addr;
1429 (void)rect;
1430 (void)fence;
1431
1432 std::lock_guard<std::mutex> lock(mMappedLock);
1433 // TODO: fence
1434 status_t err = GraphicBufferMapper::get().unlock(mBuffer);
1435 if (err) {
1436 ALOGE("failed transaction: unlock");
1437 return C2_CORRUPTED;
1438 }
1439
1440 mLocked = false;
1441 return C2_OK;
1442}
1443
1444bool C2AllocationAhwb::equals(const std::shared_ptr<const C2GraphicAllocation> &other) const {
1445 return other && other->handle() == handle();
1446}
1447
1448/* ===================================== AHARDWAREBUFFER ALLOCATOR ============================= */
1449class C2AllocatorAhwb::Impl {
1450public:
1451 Impl(id_t id);
1452
1453 id_t getId() const {
1454 return mTraits->id;
1455 }
1456
1457 C2String getName() const {
1458 return mTraits->name;
1459 }
1460
1461 std::shared_ptr<const C2Allocator::Traits> getTraits() const {
1462 return mTraits;
1463 }
1464
1465 c2_status_t newGraphicAllocation(
1466 uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
1467 std::shared_ptr<C2GraphicAllocation> *allocation);
1468
1469 c2_status_t priorGraphicAllocation(
1470 const C2Handle *handle,
1471 std::shared_ptr<C2GraphicAllocation> *allocation);
1472
1473 c2_status_t status() const { return mInit; }
1474
1475private:
1476 std::shared_ptr<C2Allocator::Traits> mTraits;
1477 c2_status_t mInit;
1478};
1479
1480void _UnwrapNativeCodec2AhwbMetadata(
1481 const C2Handle *const handle,
1482 uint32_t *width, uint32_t *height, uint32_t *format,uint64_t *usage, uint32_t *stride,
1483 uint64_t *origId) {
1484 (void)C2HandleAhwb::Import(handle, width, height, format, usage, stride, origId);
1485}
1486
1487C2AllocatorAhwb::Impl::Impl(id_t id)
1488 : mInit(C2_OK) {
1489 // TODO: get this from allocator
1490 C2MemoryUsage minUsage = { 0, 0 }, maxUsage = { ~(uint64_t)0, ~(uint64_t)0 };
1491 Traits traits = { "android.allocator.ahwb", id, C2Allocator::GRAPHIC, minUsage, maxUsage };
1492 mTraits = std::make_shared<C2Allocator::Traits>(traits);
1493}
1494
1495c2_status_t C2AllocatorAhwb::Impl::newGraphicAllocation(
1496 uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
1497 std::shared_ptr<C2GraphicAllocation> *allocation) {
1498 // TODO: for client side usage
1499 // HAL side Ahwb allocation should be done via IGBA currently.
1500 (void) width;
1501 (void) height;
1502 (void) format;
1503 (void) usage;
1504 (void) allocation;
1505 return C2_OMITTED;
1506}
1507
1508c2_status_t C2AllocatorAhwb::Impl::priorGraphicAllocation(
1509 const C2Handle *handle,
1510 std::shared_ptr<C2GraphicAllocation> *allocation) {
1511
1512 uint32_t width;
1513 uint32_t height;
1514 uint32_t format;
1515 uint32_t layerCount = 1;
1516 uint64_t grallocUsage;
1517 uint32_t stride;
1518 uint64_t origId;
1519
1520 const C2HandleAhwb *ahwbHandle = C2HandleAhwb::Import(
1521 handle, &width, &height, &format, &grallocUsage, &stride, &origId);
1522 if (ahwbHandle == nullptr) {
1523 return C2_BAD_VALUE;
1524 }
1525
1526 allocation->reset(new C2AllocationAhwb(
1527 width, height, format, layerCount,
1528 grallocUsage, stride, ahwbHandle, mTraits->id));
1529 return C2_OK;
1530}
1531
1532C2AllocatorAhwb::C2AllocatorAhwb(id_t id)
1533 : mImpl(new Impl(id)) {}
1534
1535C2AllocatorAhwb::~C2AllocatorAhwb() { delete mImpl; }
1536
1537C2Allocator::id_t C2AllocatorAhwb::getId() const {
1538 return mImpl->getId();
1539}
1540
1541C2String C2AllocatorAhwb::getName() const {
1542 return mImpl->getName();
1543}
1544
1545std::shared_ptr<const C2Allocator::Traits> C2AllocatorAhwb::getTraits() const {
1546 return mImpl->getTraits();
1547}
1548
1549c2_status_t C2AllocatorAhwb::newGraphicAllocation(
1550 uint32_t width, uint32_t height, uint32_t format, C2MemoryUsage usage,
1551 std::shared_ptr<C2GraphicAllocation> *allocation) {
1552 return mImpl->newGraphicAllocation(width, height, format, usage, allocation);
1553}
1554
1555c2_status_t C2AllocatorAhwb::priorGraphicAllocation(
1556 const C2Handle *handle,
1557 std::shared_ptr<C2GraphicAllocation> *allocation) {
1558 return mImpl->priorGraphicAllocation(handle, allocation);
1559}
1560
1561c2_status_t C2AllocatorAhwb::status() const {
1562 return mImpl->status();
1563}
1564
1565// static
1566bool C2AllocatorAhwb::CheckHandle(const C2Handle* const o) {
1567 return C2HandleAhwb::IsValid(o);
1568}
Pawin Vongmasa36653902018-11-15 00:10:25 -08001569} // namespace android