blob: 4ffa3f13482b19a3310a14bb108f139116860eea [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 =
Charlie Chen49d3fe72021-03-25 20:02:37 +080045 ~static_cast<uint64_t>(GRALLOC_USAGE_SW_READ_MASK |
46 GRALLOC_USAGE_SW_WRITE_MASK |
47 GRALLOC_USAGE_PROTECTED)
Pawin Vongmasa36653902018-11-15 00:10:25 -080048 };
49
50 // verify that passthrough mask is within the platform mask
51 static_assert((~C2MemoryUsage::PLATFORM_MASK & PASSTHROUGH_USAGE_MASK) == 0, "");
Pawin Vongmasad032f2d2019-05-15 08:42:44 -070052} // unnamed
Pawin Vongmasa36653902018-11-15 00:10:25 -080053
54C2MemoryUsage C2AndroidMemoryUsage::FromGrallocUsage(uint64_t usage) {
55 // gralloc does not support WRITE_PROTECTED
56 return C2MemoryUsage(
57 ((usage & GRALLOC_USAGE_SW_READ_MASK) ? C2MemoryUsage::CPU_READ : 0) |
58 ((usage & GRALLOC_USAGE_SW_WRITE_MASK) ? C2MemoryUsage::CPU_WRITE : 0) |
59 ((usage & GRALLOC_USAGE_PROTECTED) ? C2MemoryUsage::READ_PROTECTED : 0) |
60 (usage & PASSTHROUGH_USAGE_MASK));
61}
62
63uint64_t C2AndroidMemoryUsage::asGrallocUsage() const {
64 // gralloc does not support WRITE_PROTECTED
65 return (((expected & C2MemoryUsage::CPU_READ) ? GRALLOC_USAGE_SW_READ_OFTEN : 0) |
66 ((expected & C2MemoryUsage::CPU_WRITE) ? GRALLOC_USAGE_SW_WRITE_OFTEN : 0) |
67 ((expected & C2MemoryUsage::READ_PROTECTED) ? GRALLOC_USAGE_PROTECTED : 0) |
68 (expected & PASSTHROUGH_USAGE_MASK));
69}
70
Pawin Vongmasad032f2d2019-05-15 08:42:44 -070071namespace /* unnamed */ {
72
Pawin Vongmasa36653902018-11-15 00:10:25 -080073/* ===================================== GRALLOC ALLOCATION ==================================== */
Pawin Vongmasa36653902018-11-15 00:10:25 -080074bool native_handle_is_invalid(const native_handle_t *const handle) {
75 // perform basic validation of a native handle
76 if (handle == nullptr) {
77 // null handle is considered valid
78 return false;
79 }
80 return ((size_t)handle->version != sizeof(native_handle_t) ||
81 handle->numFds < 0 ||
82 handle->numInts < 0 ||
83 // for sanity assume handles must occupy less memory than INT_MAX bytes
84 handle->numFds > int((INT_MAX - handle->version) / sizeof(int)) - handle->numInts);
85}
86
87class C2HandleGralloc : public C2Handle {
88private:
89 struct ExtraData {
90 uint32_t width;
91 uint32_t height;
92 uint32_t format;
93 uint32_t usage_lo;
94 uint32_t usage_hi;
95 uint32_t stride;
96 uint32_t generation;
97 uint32_t igbp_id_lo;
98 uint32_t igbp_id_hi;
99 uint32_t igbp_slot;
100 uint32_t magic;
101 };
102
103 enum {
104 NUM_INTS = sizeof(ExtraData) / sizeof(int),
105 };
106 const static uint32_t MAGIC = '\xc2gr\x00';
107
108 static
John Stultz653ddd12020-09-19 05:26:24 +0000109 const ExtraData* GetExtraData(const C2Handle *const handle) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800110 if (handle == nullptr
111 || native_handle_is_invalid(handle)
112 || handle->numInts < NUM_INTS) {
113 return nullptr;
114 }
115 return reinterpret_cast<const ExtraData*>(
116 &handle->data[handle->numFds + handle->numInts - NUM_INTS]);
117 }
118
119 static
John Stultz653ddd12020-09-19 05:26:24 +0000120 ExtraData *GetExtraData(C2Handle *const handle) {
121 return const_cast<ExtraData *>(GetExtraData(const_cast<const C2Handle *const>(handle)));
Pawin Vongmasa36653902018-11-15 00:10:25 -0800122 }
123
124public:
125 void getIgbpData(uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) const {
John Stultz653ddd12020-09-19 05:26:24 +0000126 const ExtraData *ed = GetExtraData(this);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800127 *generation = ed->generation;
128 *igbp_id = unsigned(ed->igbp_id_lo) | uint64_t(unsigned(ed->igbp_id_hi)) << 32;
129 *igbp_slot = ed->igbp_slot;
130 }
131
John Stultz653ddd12020-09-19 05:26:24 +0000132 static bool IsValid(const C2Handle *const o) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800133 if (o == nullptr) { // null handle is always valid
134 return true;
135 }
John Stultz653ddd12020-09-19 05:26:24 +0000136 const ExtraData *xd = GetExtraData(o);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800137 // we cannot validate width/height/format/usage without accessing gralloc driver
138 return xd != nullptr && xd->magic == MAGIC;
139 }
140
Sungtak Leea4d13be2019-01-23 15:24:46 -0800141 static C2HandleGralloc* WrapAndMoveNativeHandle(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800142 const native_handle_t *const handle,
143 uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
144 uint32_t stride, uint32_t generation, uint64_t igbp_id = 0, uint32_t igbp_slot = 0) {
145 //CHECK(handle != nullptr);
146 if (native_handle_is_invalid(handle) ||
147 handle->numInts > int((INT_MAX - handle->version) / sizeof(int)) - NUM_INTS - handle->numFds) {
148 return nullptr;
149 }
150 ExtraData xd = {
151 width, height, format, uint32_t(usage & 0xFFFFFFFF), uint32_t(usage >> 32),
152 stride, generation, uint32_t(igbp_id & 0xFFFFFFFF), uint32_t(igbp_id >> 32),
153 igbp_slot, MAGIC
154 };
155 native_handle_t *res = native_handle_create(handle->numFds, handle->numInts + NUM_INTS);
156 if (res != nullptr) {
157 memcpy(&res->data, &handle->data, sizeof(int) * (handle->numFds + handle->numInts));
John Stultz653ddd12020-09-19 05:26:24 +0000158 *GetExtraData(res) = xd;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800159 }
160 return reinterpret_cast<C2HandleGralloc *>(res);
161 }
162
Sungtak Leea4d13be2019-01-23 15:24:46 -0800163 static C2HandleGralloc* WrapNativeHandle(
164 const native_handle_t *const handle,
165 uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
166 uint32_t stride, uint32_t generation, uint64_t igbp_id = 0, uint32_t igbp_slot = 0) {
167 if (handle == nullptr) {
168 return nullptr;
169 }
170 native_handle_t *clone = native_handle_clone(handle);
171 if (clone == nullptr) {
172 return nullptr;
173 }
174 C2HandleGralloc *res = WrapAndMoveNativeHandle(
175 clone, width, height, format, usage, stride, generation, igbp_id, igbp_slot);
176 if (res == nullptr) {
177 native_handle_close(clone);
178 }
179 native_handle_delete(clone);
180 return res;
181 }
182
Sungtak Lee08515812019-06-05 11:16:32 -0700183 static bool MigrateNativeHandle(
184 native_handle_t *handle,
185 uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
John Stultz653ddd12020-09-19 05:26:24 +0000186 if (handle == nullptr || !IsValid(handle)) {
Sungtak Lee08515812019-06-05 11:16:32 -0700187 return false;
188 }
John Stultz653ddd12020-09-19 05:26:24 +0000189 ExtraData *ed = GetExtraData(handle);
Sungtak Lee08515812019-06-05 11:16:32 -0700190 if (!ed) return false;
191 ed->generation = generation;
192 ed->igbp_id_lo = uint32_t(igbp_id & 0xFFFFFFFF);
193 ed->igbp_id_hi = uint32_t(igbp_id >> 32);
194 ed->igbp_slot = igbp_slot;
195 return true;
196 }
197
198
Pawin Vongmasa36653902018-11-15 00:10:25 -0800199 static native_handle_t* UnwrapNativeHandle(
200 const C2Handle *const handle) {
John Stultz653ddd12020-09-19 05:26:24 +0000201 const ExtraData *xd = GetExtraData(handle);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800202 if (xd == nullptr || xd->magic != MAGIC) {
203 return nullptr;
204 }
205 native_handle_t *res = native_handle_create(handle->numFds, handle->numInts - NUM_INTS);
206 if (res != nullptr) {
207 memcpy(&res->data, &handle->data, sizeof(int) * (res->numFds + res->numInts));
208 }
209 return res;
210 }
211
Pawin Vongmasa36653902018-11-15 00:10:25 -0800212 static const C2HandleGralloc* Import(
213 const C2Handle *const handle,
214 uint32_t *width, uint32_t *height, uint32_t *format,
215 uint64_t *usage, uint32_t *stride,
216 uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) {
John Stultz653ddd12020-09-19 05:26:24 +0000217 const ExtraData *xd = GetExtraData(handle);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800218 if (xd == nullptr) {
219 return nullptr;
220 }
221 *width = xd->width;
222 *height = xd->height;
223 *format = xd->format;
224 *usage = xd->usage_lo | (uint64_t(xd->usage_hi) << 32);
225 *stride = xd->stride;
226 *generation = xd->generation;
227 *igbp_id = xd->igbp_id_lo | (uint64_t(xd->igbp_id_hi) << 32);
228 *igbp_slot = xd->igbp_slot;
229 return reinterpret_cast<const C2HandleGralloc *>(handle);
230 }
231};
232
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700233} // unnamed namespace
234
Pawin Vongmasa36653902018-11-15 00:10:25 -0800235native_handle_t *UnwrapNativeCodec2GrallocHandle(const C2Handle *const handle) {
236 return C2HandleGralloc::UnwrapNativeHandle(handle);
237}
238
Pawin Vongmasa36653902018-11-15 00:10:25 -0800239C2Handle *WrapNativeCodec2GrallocHandle(
240 const native_handle_t *const handle,
241 uint32_t width, uint32_t height, uint32_t format, uint64_t usage, uint32_t stride,
242 uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
243 return C2HandleGralloc::WrapNativeHandle(handle, width, height, format, usage, stride,
244 generation, igbp_id, igbp_slot);
245}
246
Sungtak Lee08515812019-06-05 11:16:32 -0700247bool MigrateNativeCodec2GrallocHandle(
248 native_handle_t *handle,
249 uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
250 return C2HandleGralloc::MigrateNativeHandle(handle, generation, igbp_id, igbp_slot);
251}
252
253
Pawin Vongmasa36653902018-11-15 00:10:25 -0800254class C2AllocationGralloc : public C2GraphicAllocation {
255public:
256 virtual ~C2AllocationGralloc() override;
257
258 virtual c2_status_t map(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900259 C2Rect c2Rect, C2MemoryUsage usage, C2Fence *fence,
Pawin Vongmasa36653902018-11-15 00:10:25 -0800260 C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) override;
261 virtual c2_status_t unmap(
262 uint8_t **addr /* nonnull */, C2Rect rect, C2Fence *fence /* nullable */) override;
263 virtual C2Allocator::id_t getAllocatorId() const override { return mAllocatorId; }
264 virtual const C2Handle *handle() const override { return mLockedHandle ? : mHandle; }
265 virtual bool equals(const std::shared_ptr<const C2GraphicAllocation> &other) const override;
266
267 // internal methods
268 // |handle| will be moved.
Marissa Wall2a24a302019-11-25 11:19:18 -0800269
Pawin Vongmasa36653902018-11-15 00:10:25 -0800270 C2AllocationGralloc(
Marissa Wall2a24a302019-11-25 11:19:18 -0800271 uint32_t width, uint32_t height,
272 uint32_t format, uint32_t layerCount,
273 uint64_t grallocUsage, uint32_t stride,
Marissa Wall8806edc2019-06-21 09:50:47 -0700274 hidl_handle &hidlHandle,
275 const C2HandleGralloc *const handle,
276 C2Allocator::id_t allocatorId);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800277 int dup() const;
278 c2_status_t status() const;
279
280private:
Marissa Wall2a24a302019-11-25 11:19:18 -0800281 const uint32_t mWidth;
282 const uint32_t mHeight;
283 const uint32_t mFormat;
284 const uint32_t mLayerCount;
285 const uint64_t mGrallocUsage;
286 const uint32_t mStride;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800287 const hidl_handle mHidlHandle;
288 const C2HandleGralloc *mHandle;
289 buffer_handle_t mBuffer;
290 const C2HandleGralloc *mLockedHandle;
291 bool mLocked;
292 C2Allocator::id_t mAllocatorId;
293 std::mutex mMappedLock;
294};
295
296C2AllocationGralloc::C2AllocationGralloc(
Marissa Wall2a24a302019-11-25 11:19:18 -0800297 uint32_t width, uint32_t height,
298 uint32_t format, uint32_t layerCount,
299 uint64_t grallocUsage, uint32_t stride,
Pawin Vongmasa36653902018-11-15 00:10:25 -0800300 hidl_handle &hidlHandle,
301 const C2HandleGralloc *const handle,
302 C2Allocator::id_t allocatorId)
Marissa Wall2a24a302019-11-25 11:19:18 -0800303 : C2GraphicAllocation(width, height),
304 mWidth(width),
305 mHeight(height),
306 mFormat(format),
307 mLayerCount(layerCount),
308 mGrallocUsage(grallocUsage),
309 mStride(stride),
Marissa Wall8806edc2019-06-21 09:50:47 -0700310 mHidlHandle(std::move(hidlHandle)),
311 mHandle(handle),
312 mBuffer(nullptr),
313 mLockedHandle(nullptr),
314 mLocked(false),
315 mAllocatorId(allocatorId) {
316}
317
Pawin Vongmasa36653902018-11-15 00:10:25 -0800318C2AllocationGralloc::~C2AllocationGralloc() {
Yichi Chenfa94a3b2018-12-08 00:06:25 +0800319 if (mBuffer && mLocked) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800320 // implementation ignores addresss and rect
321 uint8_t* addr[C2PlanarLayout::MAX_NUM_PLANES] = {};
322 unmap(addr, C2Rect(), nullptr);
323 }
Yichi Chenfa94a3b2018-12-08 00:06:25 +0800324 if (mBuffer) {
Marissa Wall2a24a302019-11-25 11:19:18 -0800325 status_t err = GraphicBufferMapper::get().freeBuffer(mBuffer);
326 if (err) {
327 ALOGE("failed transaction: freeBuffer");
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700328 }
Yichi Chenfa94a3b2018-12-08 00:06:25 +0800329 }
330 if (mHandle) {
331 native_handle_delete(
332 const_cast<native_handle_t *>(reinterpret_cast<const native_handle_t *>(mHandle)));
333 }
Sungtak Lee2729dcf2019-01-18 13:15:07 -0800334 if (mLockedHandle) {
335 native_handle_delete(
336 const_cast<native_handle_t *>(
337 reinterpret_cast<const native_handle_t *>(mLockedHandle)));
338 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800339}
340
341c2_status_t C2AllocationGralloc::map(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900342 C2Rect c2Rect, C2MemoryUsage usage, C2Fence *fence,
Pawin Vongmasa36653902018-11-15 00:10:25 -0800343 C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) {
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900344 const Rect rect{(int32_t)c2Rect.left, (int32_t)c2Rect.top,
345 (int32_t)(c2Rect.left + c2Rect.width) /* right */,
346 (int32_t)(c2Rect.top + c2Rect.height) /* bottom */};
347
Pawin Vongmasa36653902018-11-15 00:10:25 -0800348 uint64_t grallocUsage = static_cast<C2AndroidMemoryUsage>(usage).asGrallocUsage();
349 ALOGV("mapping buffer with usage %#llx => %#llx",
350 (long long)usage.expected, (long long)grallocUsage);
351
352 // TODO
Marissa Wall2a24a302019-11-25 11:19:18 -0800353 (void)fence;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800354
355 std::lock_guard<std::mutex> lock(mMappedLock);
356 if (mBuffer && mLocked) {
357 ALOGD("already mapped");
358 return C2_DUPLICATE;
359 }
360 if (!layout || !addr) {
361 ALOGD("wrong param");
362 return C2_BAD_VALUE;
363 }
364
Pawin Vongmasa36653902018-11-15 00:10:25 -0800365 if (!mBuffer) {
Marissa Wall2a24a302019-11-25 11:19:18 -0800366 status_t err = GraphicBufferMapper::get().importBuffer(
367 mHidlHandle.getNativeHandle(), mWidth, mHeight, mLayerCount,
368 mFormat, mGrallocUsage, mStride, &mBuffer);
369 if (err) {
370 ALOGE("failed transaction: importBuffer");
371 return C2_CORRUPTED;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800372 }
373 if (mBuffer == nullptr) {
374 ALOGD("importBuffer returned null buffer");
375 return C2_CORRUPTED;
376 }
377 uint32_t generation = 0;
378 uint64_t igbp_id = 0;
379 uint32_t igbp_slot = 0;
380 if (mHandle) {
381 mHandle->getIgbpData(&generation, &igbp_id, &igbp_slot);
382 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800383
Marissa Wall2a24a302019-11-25 11:19:18 -0800384 mLockedHandle = C2HandleGralloc::WrapAndMoveNativeHandle(
385 mBuffer, mWidth, mHeight, mFormat, mGrallocUsage,
386 mStride, generation, igbp_id, igbp_slot);
Marissa Wall8806edc2019-06-21 09:50:47 -0700387 }
Marissa Wall2a24a302019-11-25 11:19:18 -0800388 switch (mFormat) {
389 case static_cast<uint32_t>(PixelFormat4::RGBA_1010102): {
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700390 // TRICKY: this is used for media as YUV444 in the case when it is queued directly to a
391 // Surface. In all other cases it is RGBA. We don't know which case it is here, so
392 // default to YUV for now.
393 void *pointer = nullptr;
Marissa Wall2a24a302019-11-25 11:19:18 -0800394 // TODO: fence
395 status_t err = GraphicBufferMapper::get().lock(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900396 const_cast<native_handle_t *>(mBuffer), grallocUsage, rect, &pointer);
Marissa Wall2a24a302019-11-25 11:19:18 -0800397 if (err) {
398 ALOGE("failed transaction: lock(RGBA_1010102)");
399 return C2_CORRUPTED;
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700400 }
401 // treat as 32-bit values
402 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)pointer;
403 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)pointer;
404 addr[C2PlanarLayout::PLANE_V] = (uint8_t *)pointer;
405 addr[C2PlanarLayout::PLANE_A] = (uint8_t *)pointer;
406 layout->type = C2PlanarLayout::TYPE_YUVA;
407 layout->numPlanes = 4;
408 layout->rootPlanes = 1;
409 layout->planes[C2PlanarLayout::PLANE_Y] = {
410 C2PlaneInfo::CHANNEL_Y, // channel
411 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800412 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700413 1, // mColSampling
414 1, // mRowSampling
415 32, // allocatedDepth
416 10, // bitDepth
417 10, // rightShift
418 C2PlaneInfo::LITTLE_END, // endianness
419 C2PlanarLayout::PLANE_Y, // rootIx
420 0, // offset
421 };
422 layout->planes[C2PlanarLayout::PLANE_U] = {
423 C2PlaneInfo::CHANNEL_CB, // channel
424 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800425 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700426 1, // mColSampling
427 1, // mRowSampling
428 32, // allocatedDepth
429 10, // bitDepth
430 0, // rightShift
431 C2PlaneInfo::LITTLE_END, // endianness
432 C2PlanarLayout::PLANE_Y, // rootIx
433 0, // offset
434 };
435 layout->planes[C2PlanarLayout::PLANE_V] = {
436 C2PlaneInfo::CHANNEL_CR, // channel
437 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800438 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700439 1, // mColSampling
440 1, // mRowSampling
441 32, // allocatedDepth
442 10, // bitDepth
443 20, // rightShift
444 C2PlaneInfo::LITTLE_END, // endianness
445 C2PlanarLayout::PLANE_Y, // rootIx
446 0, // offset
447 };
448 layout->planes[C2PlanarLayout::PLANE_A] = {
449 C2PlaneInfo::CHANNEL_A, // channel
450 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800451 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700452 1, // mColSampling
453 1, // mRowSampling
454 32, // allocatedDepth
455 2, // bitDepth
456 30, // rightShift
457 C2PlaneInfo::LITTLE_END, // endianness
458 C2PlanarLayout::PLANE_Y, // rootIx
459 0, // offset
460 };
461 break;
462 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800463
Marissa Wall2a24a302019-11-25 11:19:18 -0800464 case static_cast<uint32_t>(PixelFormat4::RGBA_8888):
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700465 // TODO: alpha channel
466 // fall-through
Marissa Wall2a24a302019-11-25 11:19:18 -0800467 case static_cast<uint32_t>(PixelFormat4::RGBX_8888): {
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700468 void *pointer = nullptr;
Marissa Wall2a24a302019-11-25 11:19:18 -0800469 // TODO: fence
470 status_t err = GraphicBufferMapper::get().lock(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900471 const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &pointer);
Marissa Wall2a24a302019-11-25 11:19:18 -0800472 if (err) {
473 ALOGE("failed transaction: lock(RGBA_8888)");
474 return C2_CORRUPTED;
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700475 }
476 addr[C2PlanarLayout::PLANE_R] = (uint8_t *)pointer;
477 addr[C2PlanarLayout::PLANE_G] = (uint8_t *)pointer + 1;
478 addr[C2PlanarLayout::PLANE_B] = (uint8_t *)pointer + 2;
479 layout->type = C2PlanarLayout::TYPE_RGB;
480 layout->numPlanes = 3;
481 layout->rootPlanes = 1;
482 layout->planes[C2PlanarLayout::PLANE_R] = {
483 C2PlaneInfo::CHANNEL_R, // channel
484 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800485 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700486 1, // mColSampling
487 1, // mRowSampling
488 8, // allocatedDepth
489 8, // bitDepth
490 0, // rightShift
491 C2PlaneInfo::NATIVE, // endianness
492 C2PlanarLayout::PLANE_R, // rootIx
493 0, // offset
494 };
495 layout->planes[C2PlanarLayout::PLANE_G] = {
496 C2PlaneInfo::CHANNEL_G, // channel
497 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800498 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700499 1, // mColSampling
500 1, // mRowSampling
501 8, // allocatedDepth
502 8, // bitDepth
503 0, // rightShift
504 C2PlaneInfo::NATIVE, // endianness
505 C2PlanarLayout::PLANE_R, // rootIx
506 1, // offset
507 };
508 layout->planes[C2PlanarLayout::PLANE_B] = {
509 C2PlaneInfo::CHANNEL_B, // channel
510 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800511 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700512 1, // mColSampling
513 1, // mRowSampling
514 8, // allocatedDepth
515 8, // bitDepth
516 0, // rightShift
517 C2PlaneInfo::NATIVE, // endianness
518 C2PlanarLayout::PLANE_R, // rootIx
519 2, // offset
520 };
521 break;
522 }
523
David Stevens1cadc75d2020-04-03 10:50:51 +0900524 case static_cast<uint32_t>(PixelFormat4::BLOB): {
525 void *pointer = nullptr;
526 // TODO: fence
527 status_t err = GraphicBufferMapper::get().lock(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900528 const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &pointer);
David Stevens1cadc75d2020-04-03 10:50:51 +0900529 if (err) {
530 ALOGE("failed transaction: lock(BLOB)");
531 return C2_CORRUPTED;
532 }
533 *addr = (uint8_t *)pointer;
534 break;
535 }
536
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700537 case static_cast<uint32_t>(PixelFormat4::YCBCR_422_SP):
538 // fall-through
539 case static_cast<uint32_t>(PixelFormat4::YCRCB_420_SP):
540 // fall-through
541 case static_cast<uint32_t>(PixelFormat4::YCBCR_422_I):
542 // fall-through
Marissa Wall2a24a302019-11-25 11:19:18 -0800543 case static_cast<uint32_t>(PixelFormat4::YCBCR_420_888):
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700544 // fall-through
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700545 case static_cast<uint32_t>(PixelFormat4::YV12): {
Marissa Wall2a24a302019-11-25 11:19:18 -0800546 android_ycbcr ycbcrLayout;
547
548 status_t err = GraphicBufferMapper::get().lockYCbCr(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900549 const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &ycbcrLayout);
Marissa Wall2a24a302019-11-25 11:19:18 -0800550 if (err) {
Wonsik Kimd91f3fb2021-02-24 12:35:31 -0800551 ALOGE("failed transaction: lockYCbCr (err=%d)", err);
552 return C2_CORRUPTED;
553 }
554 if (!ycbcrLayout.y || !ycbcrLayout.cb || !ycbcrLayout.cr
555 || ycbcrLayout.ystride == 0
556 || ycbcrLayout.cstride == 0
557 || ycbcrLayout.chroma_step == 0) {
558 ALOGE("invalid layout: lockYCbCr (y=%s cb=%s cr=%s "
559 "ystride=%zu cstride=%zu chroma_step=%zu)",
560 ycbcrLayout.y ? "(non-null)" : "(null)",
561 ycbcrLayout.cb ? "(non-null)" : "(null)",
562 ycbcrLayout.cr ? "(non-null)" : "(null)",
563 ycbcrLayout.ystride, ycbcrLayout.cstride, ycbcrLayout.chroma_step);
Marissa Wall469b90a2019-11-06 10:12:43 -0800564 return C2_CORRUPTED;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700565 }
Marissa Wall2a24a302019-11-25 11:19:18 -0800566
Pawin Vongmasa36653902018-11-15 00:10:25 -0800567 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)ycbcrLayout.y;
568 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)ycbcrLayout.cb;
569 addr[C2PlanarLayout::PLANE_V] = (uint8_t *)ycbcrLayout.cr;
570 layout->type = C2PlanarLayout::TYPE_YUV;
571 layout->numPlanes = 3;
572 layout->rootPlanes = 3;
573 layout->planes[C2PlanarLayout::PLANE_Y] = {
574 C2PlaneInfo::CHANNEL_Y, // channel
575 1, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800576 (int32_t)ycbcrLayout.ystride, // rowInc
Pawin Vongmasa36653902018-11-15 00:10:25 -0800577 1, // mColSampling
578 1, // mRowSampling
579 8, // allocatedDepth
580 8, // bitDepth
581 0, // rightShift
582 C2PlaneInfo::NATIVE, // endianness
583 C2PlanarLayout::PLANE_Y, // rootIx
584 0, // offset
585 };
586 layout->planes[C2PlanarLayout::PLANE_U] = {
587 C2PlaneInfo::CHANNEL_CB, // channel
Marissa Wall2a24a302019-11-25 11:19:18 -0800588 (int32_t)ycbcrLayout.chroma_step, // colInc
589 (int32_t)ycbcrLayout.cstride, // rowInc
Pawin Vongmasa36653902018-11-15 00:10:25 -0800590 2, // mColSampling
591 2, // mRowSampling
592 8, // allocatedDepth
593 8, // bitDepth
594 0, // rightShift
595 C2PlaneInfo::NATIVE, // endianness
596 C2PlanarLayout::PLANE_U, // rootIx
597 0, // offset
598 };
599 layout->planes[C2PlanarLayout::PLANE_V] = {
600 C2PlaneInfo::CHANNEL_CR, // channel
Marissa Wall2a24a302019-11-25 11:19:18 -0800601 (int32_t)ycbcrLayout.chroma_step, // colInc
602 (int32_t)ycbcrLayout.cstride, // rowInc
Pawin Vongmasa36653902018-11-15 00:10:25 -0800603 2, // mColSampling
604 2, // mRowSampling
605 8, // allocatedDepth
606 8, // bitDepth
607 0, // rightShift
608 C2PlaneInfo::NATIVE, // endianness
609 C2PlanarLayout::PLANE_V, // rootIx
610 0, // offset
611 };
612 // handle interleaved formats
613 intptr_t uvOffset = addr[C2PlanarLayout::PLANE_V] - addr[C2PlanarLayout::PLANE_U];
Marissa Wall2a24a302019-11-25 11:19:18 -0800614 if (uvOffset > 0 && uvOffset < (intptr_t)ycbcrLayout.chroma_step) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800615 layout->rootPlanes = 2;
616 layout->planes[C2PlanarLayout::PLANE_V].rootIx = C2PlanarLayout::PLANE_U;
617 layout->planes[C2PlanarLayout::PLANE_V].offset = uvOffset;
Marissa Wall2a24a302019-11-25 11:19:18 -0800618 } else if (uvOffset < 0 && uvOffset > -(intptr_t)ycbcrLayout.chroma_step) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800619 layout->rootPlanes = 2;
620 layout->planes[C2PlanarLayout::PLANE_U].rootIx = C2PlanarLayout::PLANE_V;
621 layout->planes[C2PlanarLayout::PLANE_U].offset = -uvOffset;
622 }
623 break;
624 }
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700625
626 case static_cast<uint32_t>(PixelFormat4::YCBCR_P010): {
627 void *pointer = nullptr;
628 status_t err = GraphicBufferMapper::get().lock(
629 const_cast<native_handle_t *>(mBuffer), grallocUsage, rect, &pointer);
630 if (err) {
631 ALOGE("failed transaction: lock(YCBCR_P010)");
632 return C2_CORRUPTED;
633 }
634 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)pointer;
635 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)pointer + mStride * 2 * rect.height();
636 addr[C2PlanarLayout::PLANE_V] = addr[C2PlanarLayout::PLANE_U] + 2;
637 layout->type = C2PlanarLayout::TYPE_YUV;
638 layout->numPlanes = 3;
639 layout->rootPlanes = 2;
640 layout->planes[C2PlanarLayout::PLANE_Y] = {
641 C2PlaneInfo::CHANNEL_Y, // channel
642 2, // colInc
643 static_cast<int32_t>(2 * mStride), // rowInc
644 1, // mColSampling
645 1, // mRowSampling
646 16, // allocatedDepth
647 10, // bitDepth
648 6, // rightShift
649 C2PlaneInfo::LITTLE_END, // endianness
650 C2PlanarLayout::PLANE_Y, // rootIx
651 0, // offset
652 };
653 layout->planes[C2PlanarLayout::PLANE_U] = {
654 C2PlaneInfo::CHANNEL_CB, // channel
655 4, // colInc
656 static_cast<int32_t>(2 * mStride), // rowInc
657 2, // mColSampling
658 2, // mRowSampling
659 16, // allocatedDepth
660 10, // bitDepth
661 6, // rightShift
662 C2PlaneInfo::LITTLE_END, // endianness
663 C2PlanarLayout::PLANE_U, // rootIx
664 0, // offset
665 };
666 layout->planes[C2PlanarLayout::PLANE_V] = {
667 C2PlaneInfo::CHANNEL_CR, // channel
668 4, // colInc
669 static_cast<int32_t>(2 * mStride), // rowInc
670 2, // mColSampling
671 2, // mRowSampling
672 16, // allocatedDepth
673 10, // bitDepth
674 6, // rightShift
675 C2PlaneInfo::LITTLE_END, // endianness
676 C2PlanarLayout::PLANE_U, // rootIx
677 2, // offset
678 };
679 break;
680 }
681
682 default: {
683 // We don't know what it is, but let's try to lock it.
684 android_ycbcr ycbcrLayout;
685
686 status_t err = GraphicBufferMapper::get().lockYCbCr(
687 const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &ycbcrLayout);
Wonsik Kimd91f3fb2021-02-24 12:35:31 -0800688 if (err == OK && ycbcrLayout.y && ycbcrLayout.cb && ycbcrLayout.cr
689 && ycbcrLayout.ystride > 0
690 && ycbcrLayout.cstride > 0
691 && ycbcrLayout.chroma_step > 0) {
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700692 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)ycbcrLayout.y;
693 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)ycbcrLayout.cb;
694 addr[C2PlanarLayout::PLANE_V] = (uint8_t *)ycbcrLayout.cr;
695 layout->type = C2PlanarLayout::TYPE_YUV;
696 layout->numPlanes = 3;
697 layout->rootPlanes = 3;
698 layout->planes[C2PlanarLayout::PLANE_Y] = {
699 C2PlaneInfo::CHANNEL_Y, // channel
700 1, // colInc
701 (int32_t)ycbcrLayout.ystride, // rowInc
702 1, // mColSampling
703 1, // mRowSampling
704 8, // allocatedDepth
705 8, // bitDepth
706 0, // rightShift
707 C2PlaneInfo::NATIVE, // endianness
708 C2PlanarLayout::PLANE_Y, // rootIx
709 0, // offset
710 };
711 layout->planes[C2PlanarLayout::PLANE_U] = {
712 C2PlaneInfo::CHANNEL_CB, // channel
713 (int32_t)ycbcrLayout.chroma_step, // colInc
714 (int32_t)ycbcrLayout.cstride, // rowInc
715 2, // mColSampling
716 2, // mRowSampling
717 8, // allocatedDepth
718 8, // bitDepth
719 0, // rightShift
720 C2PlaneInfo::NATIVE, // endianness
721 C2PlanarLayout::PLANE_U, // rootIx
722 0, // offset
723 };
724 layout->planes[C2PlanarLayout::PLANE_V] = {
725 C2PlaneInfo::CHANNEL_CR, // channel
726 (int32_t)ycbcrLayout.chroma_step, // colInc
727 (int32_t)ycbcrLayout.cstride, // rowInc
728 2, // mColSampling
729 2, // mRowSampling
730 8, // allocatedDepth
731 8, // bitDepth
732 0, // rightShift
733 C2PlaneInfo::NATIVE, // endianness
734 C2PlanarLayout::PLANE_V, // rootIx
735 0, // offset
736 };
737 // handle interleaved formats
738 intptr_t uvOffset = addr[C2PlanarLayout::PLANE_V] - addr[C2PlanarLayout::PLANE_U];
739 if (uvOffset > 0 && uvOffset < (intptr_t)ycbcrLayout.chroma_step) {
740 layout->rootPlanes = 2;
741 layout->planes[C2PlanarLayout::PLANE_V].rootIx = C2PlanarLayout::PLANE_U;
742 layout->planes[C2PlanarLayout::PLANE_V].offset = uvOffset;
743 } else if (uvOffset < 0 && uvOffset > -(intptr_t)ycbcrLayout.chroma_step) {
744 layout->rootPlanes = 2;
745 layout->planes[C2PlanarLayout::PLANE_U].rootIx = C2PlanarLayout::PLANE_V;
746 layout->planes[C2PlanarLayout::PLANE_U].offset = -uvOffset;
747 }
748 break;
749 }
750
751 // We really don't know what this is; lock the buffer and pass it through ---
752 // the client may know how to interpret it.
753 void *pointer = nullptr;
754 err = GraphicBufferMapper::get().lock(
755 const_cast<native_handle_t *>(mBuffer), grallocUsage, rect, &pointer);
756 if (err) {
757 ALOGE("failed transaction: lock(??? %x)", mFormat);
758 return C2_CORRUPTED;
759 }
760 addr[0] = (uint8_t *)pointer;
761 layout->type = C2PlanarLayout::TYPE_UNKNOWN;
762 layout->numPlanes = 1;
763 layout->rootPlanes = 1;
764 layout->planes[0] = {
765 // TODO: CHANNEL_UNKNOWN?
766 C2PlaneInfo::channel_t(0xFF), // channel
767 1, // colInc
768 int32_t(mStride), // rowInc
769 1, // mColSampling
770 1, // mRowSampling
771 8, // allocatedDepth
772 8, // bitDepth
773 0, // rightShift
774 C2PlaneInfo::NATIVE, // endianness
775 0, // rootIx
776 0, // offset
777 };
778 break;
779 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800780 }
781 mLocked = true;
782
783 return C2_OK;
784}
785
786c2_status_t C2AllocationGralloc::unmap(
787 uint8_t **addr, C2Rect rect, C2Fence *fence /* nullable */) {
788 // TODO: check addr and size, use fence
789 (void)addr;
790 (void)rect;
Marissa Wall2a24a302019-11-25 11:19:18 -0800791 (void)fence;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800792
793 std::lock_guard<std::mutex> lock(mMappedLock);
Marissa Wall2a24a302019-11-25 11:19:18 -0800794 // TODO: fence
795 status_t err = GraphicBufferMapper::get().unlock(mBuffer);
796 if (err) {
797 ALOGE("failed transaction: unlock");
798 return C2_CORRUPTED;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700799 }
Marissa Wall2a24a302019-11-25 11:19:18 -0800800
801 mLocked = false;
802 return C2_OK;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800803}
804
805bool C2AllocationGralloc::equals(const std::shared_ptr<const C2GraphicAllocation> &other) const {
806 return other && other->handle() == handle();
807}
808
809/* ===================================== GRALLOC ALLOCATOR ==================================== */
810class C2AllocatorGralloc::Impl {
811public:
812 Impl(id_t id, bool bufferQueue);
813
814 id_t getId() const {
815 return mTraits->id;
816 }
817
818 C2String getName() const {
819 return mTraits->name;
820 }
821
822 std::shared_ptr<const C2Allocator::Traits> getTraits() const {
823 return mTraits;
824 }
825
826 c2_status_t newGraphicAllocation(
827 uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
828 std::shared_ptr<C2GraphicAllocation> *allocation);
829
830 c2_status_t priorGraphicAllocation(
831 const C2Handle *handle,
832 std::shared_ptr<C2GraphicAllocation> *allocation);
833
834 c2_status_t status() const { return mInit; }
835
836private:
837 std::shared_ptr<C2Allocator::Traits> mTraits;
838 c2_status_t mInit;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800839 const bool mBufferQueue;
840};
841
842void _UnwrapNativeCodec2GrallocMetadata(
843 const C2Handle *const handle,
844 uint32_t *width, uint32_t *height, uint32_t *format,uint64_t *usage, uint32_t *stride,
845 uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) {
846 (void)C2HandleGralloc::Import(handle, width, height, format, usage, stride,
847 generation, igbp_id, igbp_slot);
848}
849
850C2AllocatorGralloc::Impl::Impl(id_t id, bool bufferQueue)
851 : mInit(C2_OK), mBufferQueue(bufferQueue) {
852 // TODO: get this from allocator
853 C2MemoryUsage minUsage = { 0, 0 }, maxUsage = { ~(uint64_t)0, ~(uint64_t)0 };
854 Traits traits = { "android.allocator.gralloc", id, C2Allocator::GRAPHIC, minUsage, maxUsage };
855 mTraits = std::make_shared<C2Allocator::Traits>(traits);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800856}
857
858c2_status_t C2AllocatorGralloc::Impl::newGraphicAllocation(
859 uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
860 std::shared_ptr<C2GraphicAllocation> *allocation) {
861 uint64_t grallocUsage = static_cast<C2AndroidMemoryUsage>(usage).asGrallocUsage();
862 ALOGV("allocating buffer with usage %#llx => %#llx",
863 (long long)usage.expected, (long long)grallocUsage);
864
Marissa Wall2a24a302019-11-25 11:19:18 -0800865 buffer_handle_t buffer;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700866
Marissa Wall2a24a302019-11-25 11:19:18 -0800867 uint32_t stride = 0;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700868
Marissa Wall2a24a302019-11-25 11:19:18 -0800869 status_t err = GraphicBufferAllocator::get().allocateRawHandle(width, height, format,
870 1u /* layer count */, grallocUsage, &buffer, &stride, "C2GrallocAllocation");
871 if (err) {
872 ALOGE("failed transaction: allocate");
873 return C2_CORRUPTED;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800874 }
Marissa Wall2a24a302019-11-25 11:19:18 -0800875
876 hidl_handle hidlHandle;
877 hidlHandle.setTo(const_cast<native_handle_t*>(buffer), true);
878
879 allocation->reset(new C2AllocationGralloc(
880 width, height, format, 1u /* layer count */, grallocUsage, stride, hidlHandle,
881 C2HandleGralloc::WrapAndMoveNativeHandle(
882 hidlHandle, width, height,
883 format, grallocUsage, stride,
884 0, 0, mBufferQueue ? ~0 : 0),
885 mTraits->id));
886 return C2_OK;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800887}
888
889c2_status_t C2AllocatorGralloc::Impl::priorGraphicAllocation(
890 const C2Handle *handle,
891 std::shared_ptr<C2GraphicAllocation> *allocation) {
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700892
Marissa Wall2a24a302019-11-25 11:19:18 -0800893 uint32_t generation;
894 uint64_t igbp_id;
895 uint32_t igbp_slot;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700896
Marissa Wall2a24a302019-11-25 11:19:18 -0800897 uint32_t width;
898 uint32_t height;
899 uint32_t format;
900 uint32_t layerCount = 1;
901 uint64_t grallocUsage;
902 uint32_t stride;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700903
Marissa Wall2a24a302019-11-25 11:19:18 -0800904 const C2HandleGralloc *grallocHandle = C2HandleGralloc::Import(
905 handle, &width, &height, &format, &grallocUsage, &stride,
906 &generation, &igbp_id, &igbp_slot);
907 if (grallocHandle == nullptr) {
908 return C2_BAD_VALUE;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800909 }
Marissa Wall2a24a302019-11-25 11:19:18 -0800910
911 hidl_handle hidlHandle;
912 hidlHandle.setTo(C2HandleGralloc::UnwrapNativeHandle(grallocHandle), true);
913
914 allocation->reset(new C2AllocationGralloc(
915 width, height, format, layerCount,
916 grallocUsage, stride, hidlHandle, grallocHandle, mTraits->id));
917 return C2_OK;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800918}
919
920C2AllocatorGralloc::C2AllocatorGralloc(id_t id, bool bufferQueue)
921 : mImpl(new Impl(id, bufferQueue)) {}
922
923C2AllocatorGralloc::~C2AllocatorGralloc() { delete mImpl; }
924
925C2Allocator::id_t C2AllocatorGralloc::getId() const {
926 return mImpl->getId();
927}
928
929C2String C2AllocatorGralloc::getName() const {
930 return mImpl->getName();
931}
932
933std::shared_ptr<const C2Allocator::Traits> C2AllocatorGralloc::getTraits() const {
934 return mImpl->getTraits();
935}
936
937c2_status_t C2AllocatorGralloc::newGraphicAllocation(
938 uint32_t width, uint32_t height, uint32_t format, C2MemoryUsage usage,
939 std::shared_ptr<C2GraphicAllocation> *allocation) {
940 return mImpl->newGraphicAllocation(width, height, format, usage, allocation);
941}
942
943c2_status_t C2AllocatorGralloc::priorGraphicAllocation(
944 const C2Handle *handle,
945 std::shared_ptr<C2GraphicAllocation> *allocation) {
946 return mImpl->priorGraphicAllocation(handle, allocation);
947}
948
949c2_status_t C2AllocatorGralloc::status() const {
950 return mImpl->status();
951}
952
John Stultz653ddd12020-09-19 05:26:24 +0000953// static
954bool C2AllocatorGralloc::CheckHandle(const C2Handle* const o) {
955 return C2HandleGralloc::IsValid(o);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800956}
957
958} // namespace android