blob: bee6b7f35d62250c8f018ff3f3140cdce4d93894 [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
23#include <android/hardware/graphics/common/1.2/types.h>
Pawin Vongmasa36653902018-11-15 00:10:25 -080024#include <cutils/native_handle.h>
25#include <hardware/gralloc.h>
Marissa Wall2a24a302019-11-25 11:19:18 -080026#include <ui/GraphicBufferAllocator.h>
27#include <ui/GraphicBufferMapper.h>
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +090028#include <ui/Rect.h>
Pawin Vongmasa36653902018-11-15 00:10:25 -080029
30#include <C2AllocatorGralloc.h>
31#include <C2Buffer.h>
32#include <C2PlatformSupport.h>
33
Marissa Wall2a24a302019-11-25 11:19:18 -080034using ::android::hardware::hidl_handle;
35using PixelFormat4 = ::android::hardware::graphics::common::V1_2::PixelFormat;
36
Pawin Vongmasa36653902018-11-15 00:10:25 -080037namespace android {
38
Pawin Vongmasad032f2d2019-05-15 08:42:44 -070039namespace /* unnamed */ {
Pawin Vongmasa36653902018-11-15 00:10:25 -080040 enum : uint64_t {
41 /**
42 * Usage mask that is passed through from gralloc to Codec 2.0 usage.
43 */
44 PASSTHROUGH_USAGE_MASK =
45 ~(GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK | GRALLOC_USAGE_PROTECTED)
46 };
47
48 // verify that passthrough mask is within the platform mask
49 static_assert((~C2MemoryUsage::PLATFORM_MASK & PASSTHROUGH_USAGE_MASK) == 0, "");
Pawin Vongmasad032f2d2019-05-15 08:42:44 -070050} // unnamed
Pawin Vongmasa36653902018-11-15 00:10:25 -080051
52C2MemoryUsage C2AndroidMemoryUsage::FromGrallocUsage(uint64_t usage) {
53 // gralloc does not support WRITE_PROTECTED
54 return C2MemoryUsage(
55 ((usage & GRALLOC_USAGE_SW_READ_MASK) ? C2MemoryUsage::CPU_READ : 0) |
56 ((usage & GRALLOC_USAGE_SW_WRITE_MASK) ? C2MemoryUsage::CPU_WRITE : 0) |
57 ((usage & GRALLOC_USAGE_PROTECTED) ? C2MemoryUsage::READ_PROTECTED : 0) |
58 (usage & PASSTHROUGH_USAGE_MASK));
59}
60
61uint64_t C2AndroidMemoryUsage::asGrallocUsage() const {
62 // gralloc does not support WRITE_PROTECTED
63 return (((expected & C2MemoryUsage::CPU_READ) ? GRALLOC_USAGE_SW_READ_OFTEN : 0) |
64 ((expected & C2MemoryUsage::CPU_WRITE) ? GRALLOC_USAGE_SW_WRITE_OFTEN : 0) |
65 ((expected & C2MemoryUsage::READ_PROTECTED) ? GRALLOC_USAGE_PROTECTED : 0) |
66 (expected & PASSTHROUGH_USAGE_MASK));
67}
68
Pawin Vongmasad032f2d2019-05-15 08:42:44 -070069namespace /* unnamed */ {
70
Pawin Vongmasa36653902018-11-15 00:10:25 -080071/* ===================================== GRALLOC ALLOCATION ==================================== */
Pawin Vongmasa36653902018-11-15 00:10:25 -080072bool native_handle_is_invalid(const native_handle_t *const handle) {
73 // perform basic validation of a native handle
74 if (handle == nullptr) {
75 // null handle is considered valid
76 return false;
77 }
78 return ((size_t)handle->version != sizeof(native_handle_t) ||
79 handle->numFds < 0 ||
80 handle->numInts < 0 ||
81 // for sanity assume handles must occupy less memory than INT_MAX bytes
82 handle->numFds > int((INT_MAX - handle->version) / sizeof(int)) - handle->numInts);
83}
84
85class C2HandleGralloc : public C2Handle {
86private:
87 struct ExtraData {
88 uint32_t width;
89 uint32_t height;
90 uint32_t format;
91 uint32_t usage_lo;
92 uint32_t usage_hi;
93 uint32_t stride;
94 uint32_t generation;
95 uint32_t igbp_id_lo;
96 uint32_t igbp_id_hi;
97 uint32_t igbp_slot;
98 uint32_t magic;
99 };
100
101 enum {
102 NUM_INTS = sizeof(ExtraData) / sizeof(int),
103 };
104 const static uint32_t MAGIC = '\xc2gr\x00';
105
106 static
John Stultz653ddd12020-09-19 05:26:24 +0000107 const ExtraData* GetExtraData(const C2Handle *const handle) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800108 if (handle == nullptr
109 || native_handle_is_invalid(handle)
110 || handle->numInts < NUM_INTS) {
111 return nullptr;
112 }
113 return reinterpret_cast<const ExtraData*>(
114 &handle->data[handle->numFds + handle->numInts - NUM_INTS]);
115 }
116
117 static
John Stultz653ddd12020-09-19 05:26:24 +0000118 ExtraData *GetExtraData(C2Handle *const handle) {
119 return const_cast<ExtraData *>(GetExtraData(const_cast<const C2Handle *const>(handle)));
Pawin Vongmasa36653902018-11-15 00:10:25 -0800120 }
121
122public:
123 void getIgbpData(uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) const {
John Stultz653ddd12020-09-19 05:26:24 +0000124 const ExtraData *ed = GetExtraData(this);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800125 *generation = ed->generation;
126 *igbp_id = unsigned(ed->igbp_id_lo) | uint64_t(unsigned(ed->igbp_id_hi)) << 32;
127 *igbp_slot = ed->igbp_slot;
128 }
129
John Stultz653ddd12020-09-19 05:26:24 +0000130 static bool IsValid(const C2Handle *const o) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800131 if (o == nullptr) { // null handle is always valid
132 return true;
133 }
John Stultz653ddd12020-09-19 05:26:24 +0000134 const ExtraData *xd = GetExtraData(o);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800135 // we cannot validate width/height/format/usage without accessing gralloc driver
136 return xd != nullptr && xd->magic == MAGIC;
137 }
138
Sungtak Leea4d13be2019-01-23 15:24:46 -0800139 static C2HandleGralloc* WrapAndMoveNativeHandle(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800140 const native_handle_t *const handle,
141 uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
142 uint32_t stride, uint32_t generation, uint64_t igbp_id = 0, uint32_t igbp_slot = 0) {
143 //CHECK(handle != nullptr);
144 if (native_handle_is_invalid(handle) ||
145 handle->numInts > int((INT_MAX - handle->version) / sizeof(int)) - NUM_INTS - handle->numFds) {
146 return nullptr;
147 }
148 ExtraData xd = {
149 width, height, format, uint32_t(usage & 0xFFFFFFFF), uint32_t(usage >> 32),
150 stride, generation, uint32_t(igbp_id & 0xFFFFFFFF), uint32_t(igbp_id >> 32),
151 igbp_slot, MAGIC
152 };
153 native_handle_t *res = native_handle_create(handle->numFds, handle->numInts + NUM_INTS);
154 if (res != nullptr) {
155 memcpy(&res->data, &handle->data, sizeof(int) * (handle->numFds + handle->numInts));
John Stultz653ddd12020-09-19 05:26:24 +0000156 *GetExtraData(res) = xd;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800157 }
158 return reinterpret_cast<C2HandleGralloc *>(res);
159 }
160
Sungtak Leea4d13be2019-01-23 15:24:46 -0800161 static C2HandleGralloc* WrapNativeHandle(
162 const native_handle_t *const handle,
163 uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
164 uint32_t stride, uint32_t generation, uint64_t igbp_id = 0, uint32_t igbp_slot = 0) {
165 if (handle == nullptr) {
166 return nullptr;
167 }
168 native_handle_t *clone = native_handle_clone(handle);
169 if (clone == nullptr) {
170 return nullptr;
171 }
172 C2HandleGralloc *res = WrapAndMoveNativeHandle(
173 clone, width, height, format, usage, stride, generation, igbp_id, igbp_slot);
174 if (res == nullptr) {
175 native_handle_close(clone);
176 }
177 native_handle_delete(clone);
178 return res;
179 }
180
Sungtak Lee08515812019-06-05 11:16:32 -0700181 static bool MigrateNativeHandle(
182 native_handle_t *handle,
183 uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
John Stultz653ddd12020-09-19 05:26:24 +0000184 if (handle == nullptr || !IsValid(handle)) {
Sungtak Lee08515812019-06-05 11:16:32 -0700185 return false;
186 }
John Stultz653ddd12020-09-19 05:26:24 +0000187 ExtraData *ed = GetExtraData(handle);
Sungtak Lee08515812019-06-05 11:16:32 -0700188 if (!ed) return false;
189 ed->generation = generation;
190 ed->igbp_id_lo = uint32_t(igbp_id & 0xFFFFFFFF);
191 ed->igbp_id_hi = uint32_t(igbp_id >> 32);
192 ed->igbp_slot = igbp_slot;
193 return true;
194 }
195
196
Pawin Vongmasa36653902018-11-15 00:10:25 -0800197 static native_handle_t* UnwrapNativeHandle(
198 const C2Handle *const handle) {
John Stultz653ddd12020-09-19 05:26:24 +0000199 const ExtraData *xd = GetExtraData(handle);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800200 if (xd == nullptr || xd->magic != MAGIC) {
201 return nullptr;
202 }
203 native_handle_t *res = native_handle_create(handle->numFds, handle->numInts - NUM_INTS);
204 if (res != nullptr) {
205 memcpy(&res->data, &handle->data, sizeof(int) * (res->numFds + res->numInts));
206 }
207 return res;
208 }
209
Pawin Vongmasa36653902018-11-15 00:10:25 -0800210 static const C2HandleGralloc* Import(
211 const C2Handle *const handle,
212 uint32_t *width, uint32_t *height, uint32_t *format,
213 uint64_t *usage, uint32_t *stride,
214 uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) {
John Stultz653ddd12020-09-19 05:26:24 +0000215 const ExtraData *xd = GetExtraData(handle);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800216 if (xd == nullptr) {
217 return nullptr;
218 }
219 *width = xd->width;
220 *height = xd->height;
221 *format = xd->format;
222 *usage = xd->usage_lo | (uint64_t(xd->usage_hi) << 32);
223 *stride = xd->stride;
224 *generation = xd->generation;
225 *igbp_id = xd->igbp_id_lo | (uint64_t(xd->igbp_id_hi) << 32);
226 *igbp_slot = xd->igbp_slot;
227 return reinterpret_cast<const C2HandleGralloc *>(handle);
228 }
229};
230
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700231} // unnamed namespace
232
Pawin Vongmasa36653902018-11-15 00:10:25 -0800233native_handle_t *UnwrapNativeCodec2GrallocHandle(const C2Handle *const handle) {
234 return C2HandleGralloc::UnwrapNativeHandle(handle);
235}
236
Pawin Vongmasa36653902018-11-15 00:10:25 -0800237C2Handle *WrapNativeCodec2GrallocHandle(
238 const native_handle_t *const handle,
239 uint32_t width, uint32_t height, uint32_t format, uint64_t usage, uint32_t stride,
240 uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
241 return C2HandleGralloc::WrapNativeHandle(handle, width, height, format, usage, stride,
242 generation, igbp_id, igbp_slot);
243}
244
Sungtak Lee08515812019-06-05 11:16:32 -0700245bool MigrateNativeCodec2GrallocHandle(
246 native_handle_t *handle,
247 uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
248 return C2HandleGralloc::MigrateNativeHandle(handle, generation, igbp_id, igbp_slot);
249}
250
251
Pawin Vongmasa36653902018-11-15 00:10:25 -0800252class C2AllocationGralloc : public C2GraphicAllocation {
253public:
254 virtual ~C2AllocationGralloc() override;
255
256 virtual c2_status_t map(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900257 C2Rect c2Rect, C2MemoryUsage usage, C2Fence *fence,
Pawin Vongmasa36653902018-11-15 00:10:25 -0800258 C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) override;
259 virtual c2_status_t unmap(
260 uint8_t **addr /* nonnull */, C2Rect rect, C2Fence *fence /* nullable */) override;
261 virtual C2Allocator::id_t getAllocatorId() const override { return mAllocatorId; }
262 virtual const C2Handle *handle() const override { return mLockedHandle ? : mHandle; }
263 virtual bool equals(const std::shared_ptr<const C2GraphicAllocation> &other) const override;
264
265 // internal methods
266 // |handle| will be moved.
Marissa Wall2a24a302019-11-25 11:19:18 -0800267
Pawin Vongmasa36653902018-11-15 00:10:25 -0800268 C2AllocationGralloc(
Marissa Wall2a24a302019-11-25 11:19:18 -0800269 uint32_t width, uint32_t height,
270 uint32_t format, uint32_t layerCount,
271 uint64_t grallocUsage, uint32_t stride,
Marissa Wall8806edc2019-06-21 09:50:47 -0700272 hidl_handle &hidlHandle,
273 const C2HandleGralloc *const handle,
274 C2Allocator::id_t allocatorId);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800275 int dup() const;
276 c2_status_t status() const;
277
278private:
Marissa Wall2a24a302019-11-25 11:19:18 -0800279 const uint32_t mWidth;
280 const uint32_t mHeight;
281 const uint32_t mFormat;
282 const uint32_t mLayerCount;
283 const uint64_t mGrallocUsage;
284 const uint32_t mStride;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800285 const hidl_handle mHidlHandle;
286 const C2HandleGralloc *mHandle;
287 buffer_handle_t mBuffer;
288 const C2HandleGralloc *mLockedHandle;
289 bool mLocked;
290 C2Allocator::id_t mAllocatorId;
291 std::mutex mMappedLock;
292};
293
294C2AllocationGralloc::C2AllocationGralloc(
Marissa Wall2a24a302019-11-25 11:19:18 -0800295 uint32_t width, uint32_t height,
296 uint32_t format, uint32_t layerCount,
297 uint64_t grallocUsage, uint32_t stride,
Pawin Vongmasa36653902018-11-15 00:10:25 -0800298 hidl_handle &hidlHandle,
299 const C2HandleGralloc *const handle,
300 C2Allocator::id_t allocatorId)
Marissa Wall2a24a302019-11-25 11:19:18 -0800301 : C2GraphicAllocation(width, height),
302 mWidth(width),
303 mHeight(height),
304 mFormat(format),
305 mLayerCount(layerCount),
306 mGrallocUsage(grallocUsage),
307 mStride(stride),
Marissa Wall8806edc2019-06-21 09:50:47 -0700308 mHidlHandle(std::move(hidlHandle)),
309 mHandle(handle),
310 mBuffer(nullptr),
311 mLockedHandle(nullptr),
312 mLocked(false),
313 mAllocatorId(allocatorId) {
314}
315
Pawin Vongmasa36653902018-11-15 00:10:25 -0800316C2AllocationGralloc::~C2AllocationGralloc() {
Yichi Chenfa94a3b2018-12-08 00:06:25 +0800317 if (mBuffer && mLocked) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800318 // implementation ignores addresss and rect
319 uint8_t* addr[C2PlanarLayout::MAX_NUM_PLANES] = {};
320 unmap(addr, C2Rect(), nullptr);
321 }
Yichi Chenfa94a3b2018-12-08 00:06:25 +0800322 if (mBuffer) {
Marissa Wall2a24a302019-11-25 11:19:18 -0800323 status_t err = GraphicBufferMapper::get().freeBuffer(mBuffer);
324 if (err) {
325 ALOGE("failed transaction: freeBuffer");
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700326 }
Yichi Chenfa94a3b2018-12-08 00:06:25 +0800327 }
328 if (mHandle) {
329 native_handle_delete(
330 const_cast<native_handle_t *>(reinterpret_cast<const native_handle_t *>(mHandle)));
331 }
Sungtak Lee2729dcf2019-01-18 13:15:07 -0800332 if (mLockedHandle) {
333 native_handle_delete(
334 const_cast<native_handle_t *>(
335 reinterpret_cast<const native_handle_t *>(mLockedHandle)));
336 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800337}
338
339c2_status_t C2AllocationGralloc::map(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900340 C2Rect c2Rect, C2MemoryUsage usage, C2Fence *fence,
Pawin Vongmasa36653902018-11-15 00:10:25 -0800341 C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) {
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900342 const Rect rect{(int32_t)c2Rect.left, (int32_t)c2Rect.top,
343 (int32_t)(c2Rect.left + c2Rect.width) /* right */,
344 (int32_t)(c2Rect.top + c2Rect.height) /* bottom */};
345
Pawin Vongmasa36653902018-11-15 00:10:25 -0800346 uint64_t grallocUsage = static_cast<C2AndroidMemoryUsage>(usage).asGrallocUsage();
347 ALOGV("mapping buffer with usage %#llx => %#llx",
348 (long long)usage.expected, (long long)grallocUsage);
349
350 // TODO
Marissa Wall2a24a302019-11-25 11:19:18 -0800351 (void)fence;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800352
353 std::lock_guard<std::mutex> lock(mMappedLock);
354 if (mBuffer && mLocked) {
355 ALOGD("already mapped");
356 return C2_DUPLICATE;
357 }
358 if (!layout || !addr) {
359 ALOGD("wrong param");
360 return C2_BAD_VALUE;
361 }
362
Pawin Vongmasa36653902018-11-15 00:10:25 -0800363 if (!mBuffer) {
Marissa Wall2a24a302019-11-25 11:19:18 -0800364 status_t err = GraphicBufferMapper::get().importBuffer(
365 mHidlHandle.getNativeHandle(), mWidth, mHeight, mLayerCount,
366 mFormat, mGrallocUsage, mStride, &mBuffer);
367 if (err) {
368 ALOGE("failed transaction: importBuffer");
369 return C2_CORRUPTED;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800370 }
371 if (mBuffer == nullptr) {
372 ALOGD("importBuffer returned null buffer");
373 return C2_CORRUPTED;
374 }
375 uint32_t generation = 0;
376 uint64_t igbp_id = 0;
377 uint32_t igbp_slot = 0;
378 if (mHandle) {
379 mHandle->getIgbpData(&generation, &igbp_id, &igbp_slot);
380 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800381
Marissa Wall2a24a302019-11-25 11:19:18 -0800382 mLockedHandle = C2HandleGralloc::WrapAndMoveNativeHandle(
383 mBuffer, mWidth, mHeight, mFormat, mGrallocUsage,
384 mStride, generation, igbp_id, igbp_slot);
Marissa Wall8806edc2019-06-21 09:50:47 -0700385 }
Marissa Wall2a24a302019-11-25 11:19:18 -0800386 switch (mFormat) {
387 case static_cast<uint32_t>(PixelFormat4::RGBA_1010102): {
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700388 // TRICKY: this is used for media as YUV444 in the case when it is queued directly to a
389 // Surface. In all other cases it is RGBA. We don't know which case it is here, so
390 // default to YUV for now.
391 void *pointer = nullptr;
Marissa Wall2a24a302019-11-25 11:19:18 -0800392 // TODO: fence
393 status_t err = GraphicBufferMapper::get().lock(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900394 const_cast<native_handle_t *>(mBuffer), grallocUsage, rect, &pointer);
Marissa Wall2a24a302019-11-25 11:19:18 -0800395 if (err) {
396 ALOGE("failed transaction: lock(RGBA_1010102)");
397 return C2_CORRUPTED;
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700398 }
399 // treat as 32-bit values
400 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)pointer;
401 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)pointer;
402 addr[C2PlanarLayout::PLANE_V] = (uint8_t *)pointer;
403 addr[C2PlanarLayout::PLANE_A] = (uint8_t *)pointer;
404 layout->type = C2PlanarLayout::TYPE_YUVA;
405 layout->numPlanes = 4;
406 layout->rootPlanes = 1;
407 layout->planes[C2PlanarLayout::PLANE_Y] = {
408 C2PlaneInfo::CHANNEL_Y, // channel
409 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800410 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700411 1, // mColSampling
412 1, // mRowSampling
413 32, // allocatedDepth
414 10, // bitDepth
415 10, // rightShift
416 C2PlaneInfo::LITTLE_END, // endianness
417 C2PlanarLayout::PLANE_Y, // rootIx
418 0, // offset
419 };
420 layout->planes[C2PlanarLayout::PLANE_U] = {
421 C2PlaneInfo::CHANNEL_CB, // channel
422 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800423 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700424 1, // mColSampling
425 1, // mRowSampling
426 32, // allocatedDepth
427 10, // bitDepth
428 0, // rightShift
429 C2PlaneInfo::LITTLE_END, // endianness
430 C2PlanarLayout::PLANE_Y, // rootIx
431 0, // offset
432 };
433 layout->planes[C2PlanarLayout::PLANE_V] = {
434 C2PlaneInfo::CHANNEL_CR, // channel
435 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800436 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700437 1, // mColSampling
438 1, // mRowSampling
439 32, // allocatedDepth
440 10, // bitDepth
441 20, // rightShift
442 C2PlaneInfo::LITTLE_END, // endianness
443 C2PlanarLayout::PLANE_Y, // rootIx
444 0, // offset
445 };
446 layout->planes[C2PlanarLayout::PLANE_A] = {
447 C2PlaneInfo::CHANNEL_A, // channel
448 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800449 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700450 1, // mColSampling
451 1, // mRowSampling
452 32, // allocatedDepth
453 2, // bitDepth
454 30, // rightShift
455 C2PlaneInfo::LITTLE_END, // endianness
456 C2PlanarLayout::PLANE_Y, // rootIx
457 0, // offset
458 };
459 break;
460 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800461
Marissa Wall2a24a302019-11-25 11:19:18 -0800462 case static_cast<uint32_t>(PixelFormat4::RGBA_8888):
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700463 // TODO: alpha channel
464 // fall-through
Marissa Wall2a24a302019-11-25 11:19:18 -0800465 case static_cast<uint32_t>(PixelFormat4::RGBX_8888): {
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700466 void *pointer = nullptr;
Marissa Wall2a24a302019-11-25 11:19:18 -0800467 // TODO: fence
468 status_t err = GraphicBufferMapper::get().lock(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900469 const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &pointer);
Marissa Wall2a24a302019-11-25 11:19:18 -0800470 if (err) {
471 ALOGE("failed transaction: lock(RGBA_8888)");
472 return C2_CORRUPTED;
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700473 }
474 addr[C2PlanarLayout::PLANE_R] = (uint8_t *)pointer;
475 addr[C2PlanarLayout::PLANE_G] = (uint8_t *)pointer + 1;
476 addr[C2PlanarLayout::PLANE_B] = (uint8_t *)pointer + 2;
477 layout->type = C2PlanarLayout::TYPE_RGB;
478 layout->numPlanes = 3;
479 layout->rootPlanes = 1;
480 layout->planes[C2PlanarLayout::PLANE_R] = {
481 C2PlaneInfo::CHANNEL_R, // channel
482 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800483 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700484 1, // mColSampling
485 1, // mRowSampling
486 8, // allocatedDepth
487 8, // bitDepth
488 0, // rightShift
489 C2PlaneInfo::NATIVE, // endianness
490 C2PlanarLayout::PLANE_R, // rootIx
491 0, // offset
492 };
493 layout->planes[C2PlanarLayout::PLANE_G] = {
494 C2PlaneInfo::CHANNEL_G, // channel
495 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800496 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700497 1, // mColSampling
498 1, // mRowSampling
499 8, // allocatedDepth
500 8, // bitDepth
501 0, // rightShift
502 C2PlaneInfo::NATIVE, // endianness
503 C2PlanarLayout::PLANE_R, // rootIx
504 1, // offset
505 };
506 layout->planes[C2PlanarLayout::PLANE_B] = {
507 C2PlaneInfo::CHANNEL_B, // channel
508 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800509 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700510 1, // mColSampling
511 1, // mRowSampling
512 8, // allocatedDepth
513 8, // bitDepth
514 0, // rightShift
515 C2PlaneInfo::NATIVE, // endianness
516 C2PlanarLayout::PLANE_R, // rootIx
517 2, // offset
518 };
519 break;
520 }
521
David Stevens1cadc75d2020-04-03 10:50:51 +0900522 case static_cast<uint32_t>(PixelFormat4::BLOB): {
523 void *pointer = nullptr;
524 // TODO: fence
525 status_t err = GraphicBufferMapper::get().lock(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900526 const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &pointer);
David Stevens1cadc75d2020-04-03 10:50:51 +0900527 if (err) {
528 ALOGE("failed transaction: lock(BLOB)");
529 return C2_CORRUPTED;
530 }
531 *addr = (uint8_t *)pointer;
532 break;
533 }
534
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700535 case static_cast<uint32_t>(PixelFormat4::YCBCR_422_SP):
536 // fall-through
537 case static_cast<uint32_t>(PixelFormat4::YCRCB_420_SP):
538 // fall-through
539 case static_cast<uint32_t>(PixelFormat4::YCBCR_422_I):
540 // fall-through
Marissa Wall2a24a302019-11-25 11:19:18 -0800541 case static_cast<uint32_t>(PixelFormat4::YCBCR_420_888):
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700542 // fall-through
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700543 case static_cast<uint32_t>(PixelFormat4::YV12): {
Marissa Wall2a24a302019-11-25 11:19:18 -0800544 android_ycbcr ycbcrLayout;
545
546 status_t err = GraphicBufferMapper::get().lockYCbCr(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900547 const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &ycbcrLayout);
Marissa Wall2a24a302019-11-25 11:19:18 -0800548 if (err) {
Wonsik Kimd91f3fb2021-02-24 12:35:31 -0800549 ALOGE("failed transaction: lockYCbCr (err=%d)", err);
550 return C2_CORRUPTED;
551 }
552 if (!ycbcrLayout.y || !ycbcrLayout.cb || !ycbcrLayout.cr
553 || ycbcrLayout.ystride == 0
554 || ycbcrLayout.cstride == 0
555 || ycbcrLayout.chroma_step == 0) {
556 ALOGE("invalid layout: lockYCbCr (y=%s cb=%s cr=%s "
557 "ystride=%zu cstride=%zu chroma_step=%zu)",
558 ycbcrLayout.y ? "(non-null)" : "(null)",
559 ycbcrLayout.cb ? "(non-null)" : "(null)",
560 ycbcrLayout.cr ? "(non-null)" : "(null)",
561 ycbcrLayout.ystride, ycbcrLayout.cstride, ycbcrLayout.chroma_step);
Marissa Wall469b90a2019-11-06 10:12:43 -0800562 return C2_CORRUPTED;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700563 }
Marissa Wall2a24a302019-11-25 11:19:18 -0800564
Pawin Vongmasa36653902018-11-15 00:10:25 -0800565 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)ycbcrLayout.y;
566 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)ycbcrLayout.cb;
567 addr[C2PlanarLayout::PLANE_V] = (uint8_t *)ycbcrLayout.cr;
568 layout->type = C2PlanarLayout::TYPE_YUV;
569 layout->numPlanes = 3;
570 layout->rootPlanes = 3;
571 layout->planes[C2PlanarLayout::PLANE_Y] = {
572 C2PlaneInfo::CHANNEL_Y, // channel
573 1, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800574 (int32_t)ycbcrLayout.ystride, // rowInc
Pawin Vongmasa36653902018-11-15 00:10:25 -0800575 1, // mColSampling
576 1, // mRowSampling
577 8, // allocatedDepth
578 8, // bitDepth
579 0, // rightShift
580 C2PlaneInfo::NATIVE, // endianness
581 C2PlanarLayout::PLANE_Y, // rootIx
582 0, // offset
583 };
584 layout->planes[C2PlanarLayout::PLANE_U] = {
585 C2PlaneInfo::CHANNEL_CB, // channel
Marissa Wall2a24a302019-11-25 11:19:18 -0800586 (int32_t)ycbcrLayout.chroma_step, // colInc
587 (int32_t)ycbcrLayout.cstride, // rowInc
Pawin Vongmasa36653902018-11-15 00:10:25 -0800588 2, // mColSampling
589 2, // mRowSampling
590 8, // allocatedDepth
591 8, // bitDepth
592 0, // rightShift
593 C2PlaneInfo::NATIVE, // endianness
594 C2PlanarLayout::PLANE_U, // rootIx
595 0, // offset
596 };
597 layout->planes[C2PlanarLayout::PLANE_V] = {
598 C2PlaneInfo::CHANNEL_CR, // channel
Marissa Wall2a24a302019-11-25 11:19:18 -0800599 (int32_t)ycbcrLayout.chroma_step, // colInc
600 (int32_t)ycbcrLayout.cstride, // rowInc
Pawin Vongmasa36653902018-11-15 00:10:25 -0800601 2, // mColSampling
602 2, // mRowSampling
603 8, // allocatedDepth
604 8, // bitDepth
605 0, // rightShift
606 C2PlaneInfo::NATIVE, // endianness
607 C2PlanarLayout::PLANE_V, // rootIx
608 0, // offset
609 };
610 // handle interleaved formats
611 intptr_t uvOffset = addr[C2PlanarLayout::PLANE_V] - addr[C2PlanarLayout::PLANE_U];
Marissa Wall2a24a302019-11-25 11:19:18 -0800612 if (uvOffset > 0 && uvOffset < (intptr_t)ycbcrLayout.chroma_step) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800613 layout->rootPlanes = 2;
614 layout->planes[C2PlanarLayout::PLANE_V].rootIx = C2PlanarLayout::PLANE_U;
615 layout->planes[C2PlanarLayout::PLANE_V].offset = uvOffset;
Marissa Wall2a24a302019-11-25 11:19:18 -0800616 } else if (uvOffset < 0 && uvOffset > -(intptr_t)ycbcrLayout.chroma_step) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800617 layout->rootPlanes = 2;
618 layout->planes[C2PlanarLayout::PLANE_U].rootIx = C2PlanarLayout::PLANE_V;
619 layout->planes[C2PlanarLayout::PLANE_U].offset = -uvOffset;
620 }
621 break;
622 }
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700623
624 case static_cast<uint32_t>(PixelFormat4::YCBCR_P010): {
625 void *pointer = nullptr;
626 status_t err = GraphicBufferMapper::get().lock(
627 const_cast<native_handle_t *>(mBuffer), grallocUsage, rect, &pointer);
628 if (err) {
629 ALOGE("failed transaction: lock(YCBCR_P010)");
630 return C2_CORRUPTED;
631 }
632 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)pointer;
633 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)pointer + mStride * 2 * rect.height();
634 addr[C2PlanarLayout::PLANE_V] = addr[C2PlanarLayout::PLANE_U] + 2;
635 layout->type = C2PlanarLayout::TYPE_YUV;
636 layout->numPlanes = 3;
637 layout->rootPlanes = 2;
638 layout->planes[C2PlanarLayout::PLANE_Y] = {
639 C2PlaneInfo::CHANNEL_Y, // channel
640 2, // colInc
641 static_cast<int32_t>(2 * mStride), // rowInc
642 1, // mColSampling
643 1, // mRowSampling
644 16, // allocatedDepth
645 10, // bitDepth
646 6, // rightShift
647 C2PlaneInfo::LITTLE_END, // endianness
648 C2PlanarLayout::PLANE_Y, // rootIx
649 0, // offset
650 };
651 layout->planes[C2PlanarLayout::PLANE_U] = {
652 C2PlaneInfo::CHANNEL_CB, // channel
653 4, // colInc
654 static_cast<int32_t>(2 * mStride), // rowInc
655 2, // mColSampling
656 2, // mRowSampling
657 16, // allocatedDepth
658 10, // bitDepth
659 6, // rightShift
660 C2PlaneInfo::LITTLE_END, // endianness
661 C2PlanarLayout::PLANE_U, // rootIx
662 0, // offset
663 };
664 layout->planes[C2PlanarLayout::PLANE_V] = {
665 C2PlaneInfo::CHANNEL_CR, // channel
666 4, // colInc
667 static_cast<int32_t>(2 * mStride), // rowInc
668 2, // mColSampling
669 2, // mRowSampling
670 16, // allocatedDepth
671 10, // bitDepth
672 6, // rightShift
673 C2PlaneInfo::LITTLE_END, // endianness
674 C2PlanarLayout::PLANE_U, // rootIx
675 2, // offset
676 };
677 break;
678 }
679
680 default: {
681 // We don't know what it is, but let's try to lock it.
682 android_ycbcr ycbcrLayout;
683
684 status_t err = GraphicBufferMapper::get().lockYCbCr(
685 const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &ycbcrLayout);
Wonsik Kimd91f3fb2021-02-24 12:35:31 -0800686 if (err == OK && ycbcrLayout.y && ycbcrLayout.cb && ycbcrLayout.cr
687 && ycbcrLayout.ystride > 0
688 && ycbcrLayout.cstride > 0
689 && ycbcrLayout.chroma_step > 0) {
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700690 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)ycbcrLayout.y;
691 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)ycbcrLayout.cb;
692 addr[C2PlanarLayout::PLANE_V] = (uint8_t *)ycbcrLayout.cr;
693 layout->type = C2PlanarLayout::TYPE_YUV;
694 layout->numPlanes = 3;
695 layout->rootPlanes = 3;
696 layout->planes[C2PlanarLayout::PLANE_Y] = {
697 C2PlaneInfo::CHANNEL_Y, // channel
698 1, // colInc
699 (int32_t)ycbcrLayout.ystride, // rowInc
700 1, // mColSampling
701 1, // mRowSampling
702 8, // allocatedDepth
703 8, // bitDepth
704 0, // rightShift
705 C2PlaneInfo::NATIVE, // endianness
706 C2PlanarLayout::PLANE_Y, // rootIx
707 0, // offset
708 };
709 layout->planes[C2PlanarLayout::PLANE_U] = {
710 C2PlaneInfo::CHANNEL_CB, // channel
711 (int32_t)ycbcrLayout.chroma_step, // colInc
712 (int32_t)ycbcrLayout.cstride, // rowInc
713 2, // mColSampling
714 2, // mRowSampling
715 8, // allocatedDepth
716 8, // bitDepth
717 0, // rightShift
718 C2PlaneInfo::NATIVE, // endianness
719 C2PlanarLayout::PLANE_U, // rootIx
720 0, // offset
721 };
722 layout->planes[C2PlanarLayout::PLANE_V] = {
723 C2PlaneInfo::CHANNEL_CR, // channel
724 (int32_t)ycbcrLayout.chroma_step, // colInc
725 (int32_t)ycbcrLayout.cstride, // rowInc
726 2, // mColSampling
727 2, // mRowSampling
728 8, // allocatedDepth
729 8, // bitDepth
730 0, // rightShift
731 C2PlaneInfo::NATIVE, // endianness
732 C2PlanarLayout::PLANE_V, // rootIx
733 0, // offset
734 };
735 // handle interleaved formats
736 intptr_t uvOffset = addr[C2PlanarLayout::PLANE_V] - addr[C2PlanarLayout::PLANE_U];
737 if (uvOffset > 0 && uvOffset < (intptr_t)ycbcrLayout.chroma_step) {
738 layout->rootPlanes = 2;
739 layout->planes[C2PlanarLayout::PLANE_V].rootIx = C2PlanarLayout::PLANE_U;
740 layout->planes[C2PlanarLayout::PLANE_V].offset = uvOffset;
741 } else if (uvOffset < 0 && uvOffset > -(intptr_t)ycbcrLayout.chroma_step) {
742 layout->rootPlanes = 2;
743 layout->planes[C2PlanarLayout::PLANE_U].rootIx = C2PlanarLayout::PLANE_V;
744 layout->planes[C2PlanarLayout::PLANE_U].offset = -uvOffset;
745 }
746 break;
747 }
748
749 // We really don't know what this is; lock the buffer and pass it through ---
750 // the client may know how to interpret it.
751 void *pointer = nullptr;
752 err = GraphicBufferMapper::get().lock(
753 const_cast<native_handle_t *>(mBuffer), grallocUsage, rect, &pointer);
754 if (err) {
755 ALOGE("failed transaction: lock(??? %x)", mFormat);
756 return C2_CORRUPTED;
757 }
758 addr[0] = (uint8_t *)pointer;
759 layout->type = C2PlanarLayout::TYPE_UNKNOWN;
760 layout->numPlanes = 1;
761 layout->rootPlanes = 1;
762 layout->planes[0] = {
763 // TODO: CHANNEL_UNKNOWN?
764 C2PlaneInfo::channel_t(0xFF), // channel
765 1, // colInc
766 int32_t(mStride), // rowInc
767 1, // mColSampling
768 1, // mRowSampling
769 8, // allocatedDepth
770 8, // bitDepth
771 0, // rightShift
772 C2PlaneInfo::NATIVE, // endianness
773 0, // rootIx
774 0, // offset
775 };
776 break;
777 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800778 }
779 mLocked = true;
780
781 return C2_OK;
782}
783
784c2_status_t C2AllocationGralloc::unmap(
785 uint8_t **addr, C2Rect rect, C2Fence *fence /* nullable */) {
786 // TODO: check addr and size, use fence
787 (void)addr;
788 (void)rect;
Marissa Wall2a24a302019-11-25 11:19:18 -0800789 (void)fence;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800790
791 std::lock_guard<std::mutex> lock(mMappedLock);
Marissa Wall2a24a302019-11-25 11:19:18 -0800792 // TODO: fence
793 status_t err = GraphicBufferMapper::get().unlock(mBuffer);
794 if (err) {
795 ALOGE("failed transaction: unlock");
796 return C2_CORRUPTED;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700797 }
Marissa Wall2a24a302019-11-25 11:19:18 -0800798
799 mLocked = false;
800 return C2_OK;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800801}
802
803bool C2AllocationGralloc::equals(const std::shared_ptr<const C2GraphicAllocation> &other) const {
804 return other && other->handle() == handle();
805}
806
807/* ===================================== GRALLOC ALLOCATOR ==================================== */
808class C2AllocatorGralloc::Impl {
809public:
810 Impl(id_t id, bool bufferQueue);
811
812 id_t getId() const {
813 return mTraits->id;
814 }
815
816 C2String getName() const {
817 return mTraits->name;
818 }
819
820 std::shared_ptr<const C2Allocator::Traits> getTraits() const {
821 return mTraits;
822 }
823
824 c2_status_t newGraphicAllocation(
825 uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
826 std::shared_ptr<C2GraphicAllocation> *allocation);
827
828 c2_status_t priorGraphicAllocation(
829 const C2Handle *handle,
830 std::shared_ptr<C2GraphicAllocation> *allocation);
831
832 c2_status_t status() const { return mInit; }
833
834private:
835 std::shared_ptr<C2Allocator::Traits> mTraits;
836 c2_status_t mInit;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800837 const bool mBufferQueue;
838};
839
840void _UnwrapNativeCodec2GrallocMetadata(
841 const C2Handle *const handle,
842 uint32_t *width, uint32_t *height, uint32_t *format,uint64_t *usage, uint32_t *stride,
843 uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) {
844 (void)C2HandleGralloc::Import(handle, width, height, format, usage, stride,
845 generation, igbp_id, igbp_slot);
846}
847
848C2AllocatorGralloc::Impl::Impl(id_t id, bool bufferQueue)
849 : mInit(C2_OK), mBufferQueue(bufferQueue) {
850 // TODO: get this from allocator
851 C2MemoryUsage minUsage = { 0, 0 }, maxUsage = { ~(uint64_t)0, ~(uint64_t)0 };
852 Traits traits = { "android.allocator.gralloc", id, C2Allocator::GRAPHIC, minUsage, maxUsage };
853 mTraits = std::make_shared<C2Allocator::Traits>(traits);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800854}
855
856c2_status_t C2AllocatorGralloc::Impl::newGraphicAllocation(
857 uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
858 std::shared_ptr<C2GraphicAllocation> *allocation) {
859 uint64_t grallocUsage = static_cast<C2AndroidMemoryUsage>(usage).asGrallocUsage();
860 ALOGV("allocating buffer with usage %#llx => %#llx",
861 (long long)usage.expected, (long long)grallocUsage);
862
Marissa Wall2a24a302019-11-25 11:19:18 -0800863 buffer_handle_t buffer;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700864
Marissa Wall2a24a302019-11-25 11:19:18 -0800865 uint32_t stride = 0;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700866
Marissa Wall2a24a302019-11-25 11:19:18 -0800867 status_t err = GraphicBufferAllocator::get().allocateRawHandle(width, height, format,
868 1u /* layer count */, grallocUsage, &buffer, &stride, "C2GrallocAllocation");
869 if (err) {
870 ALOGE("failed transaction: allocate");
871 return C2_CORRUPTED;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800872 }
Marissa Wall2a24a302019-11-25 11:19:18 -0800873
874 hidl_handle hidlHandle;
875 hidlHandle.setTo(const_cast<native_handle_t*>(buffer), true);
876
877 allocation->reset(new C2AllocationGralloc(
878 width, height, format, 1u /* layer count */, grallocUsage, stride, hidlHandle,
879 C2HandleGralloc::WrapAndMoveNativeHandle(
880 hidlHandle, width, height,
881 format, grallocUsage, stride,
882 0, 0, mBufferQueue ? ~0 : 0),
883 mTraits->id));
884 return C2_OK;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800885}
886
887c2_status_t C2AllocatorGralloc::Impl::priorGraphicAllocation(
888 const C2Handle *handle,
889 std::shared_ptr<C2GraphicAllocation> *allocation) {
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700890
Marissa Wall2a24a302019-11-25 11:19:18 -0800891 uint32_t generation;
892 uint64_t igbp_id;
893 uint32_t igbp_slot;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700894
Marissa Wall2a24a302019-11-25 11:19:18 -0800895 uint32_t width;
896 uint32_t height;
897 uint32_t format;
898 uint32_t layerCount = 1;
899 uint64_t grallocUsage;
900 uint32_t stride;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700901
Marissa Wall2a24a302019-11-25 11:19:18 -0800902 const C2HandleGralloc *grallocHandle = C2HandleGralloc::Import(
903 handle, &width, &height, &format, &grallocUsage, &stride,
904 &generation, &igbp_id, &igbp_slot);
905 if (grallocHandle == nullptr) {
906 return C2_BAD_VALUE;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800907 }
Marissa Wall2a24a302019-11-25 11:19:18 -0800908
909 hidl_handle hidlHandle;
910 hidlHandle.setTo(C2HandleGralloc::UnwrapNativeHandle(grallocHandle), true);
911
912 allocation->reset(new C2AllocationGralloc(
913 width, height, format, layerCount,
914 grallocUsage, stride, hidlHandle, grallocHandle, mTraits->id));
915 return C2_OK;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800916}
917
918C2AllocatorGralloc::C2AllocatorGralloc(id_t id, bool bufferQueue)
919 : mImpl(new Impl(id, bufferQueue)) {}
920
921C2AllocatorGralloc::~C2AllocatorGralloc() { delete mImpl; }
922
923C2Allocator::id_t C2AllocatorGralloc::getId() const {
924 return mImpl->getId();
925}
926
927C2String C2AllocatorGralloc::getName() const {
928 return mImpl->getName();
929}
930
931std::shared_ptr<const C2Allocator::Traits> C2AllocatorGralloc::getTraits() const {
932 return mImpl->getTraits();
933}
934
935c2_status_t C2AllocatorGralloc::newGraphicAllocation(
936 uint32_t width, uint32_t height, uint32_t format, C2MemoryUsage usage,
937 std::shared_ptr<C2GraphicAllocation> *allocation) {
938 return mImpl->newGraphicAllocation(width, height, format, usage, allocation);
939}
940
941c2_status_t C2AllocatorGralloc::priorGraphicAllocation(
942 const C2Handle *handle,
943 std::shared_ptr<C2GraphicAllocation> *allocation) {
944 return mImpl->priorGraphicAllocation(handle, allocation);
945}
946
947c2_status_t C2AllocatorGralloc::status() const {
948 return mImpl->status();
949}
950
John Stultz653ddd12020-09-19 05:26:24 +0000951// static
952bool C2AllocatorGralloc::CheckHandle(const C2Handle* const o) {
953 return C2HandleGralloc::IsValid(o);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800954}
955
956} // namespace android