blob: dab469770a8f71df555e04c0d55ddb0d33def74f [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
21#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
22#include <android/hardware/graphics/mapper/2.0/IMapper.h>
Pawin Vongmasa08384942019-05-15 08:42:44 -070023#include <android/hardware/graphics/allocator/3.0/IAllocator.h>
24#include <android/hardware/graphics/mapper/3.0/IMapper.h>
Pawin Vongmasa36653902018-11-15 00:10:25 -080025#include <cutils/native_handle.h>
26#include <hardware/gralloc.h>
27
28#include <C2AllocatorGralloc.h>
29#include <C2Buffer.h>
30#include <C2PlatformSupport.h>
31
32namespace android {
33
Pawin Vongmasa08384942019-05-15 08:42:44 -070034namespace /* unnamed */ {
Pawin Vongmasa36653902018-11-15 00:10:25 -080035 enum : uint64_t {
36 /**
37 * Usage mask that is passed through from gralloc to Codec 2.0 usage.
38 */
39 PASSTHROUGH_USAGE_MASK =
40 ~(GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK | GRALLOC_USAGE_PROTECTED)
41 };
42
43 // verify that passthrough mask is within the platform mask
44 static_assert((~C2MemoryUsage::PLATFORM_MASK & PASSTHROUGH_USAGE_MASK) == 0, "");
Pawin Vongmasa08384942019-05-15 08:42:44 -070045} // unnamed
Pawin Vongmasa36653902018-11-15 00:10:25 -080046
47C2MemoryUsage C2AndroidMemoryUsage::FromGrallocUsage(uint64_t usage) {
48 // gralloc does not support WRITE_PROTECTED
49 return C2MemoryUsage(
50 ((usage & GRALLOC_USAGE_SW_READ_MASK) ? C2MemoryUsage::CPU_READ : 0) |
51 ((usage & GRALLOC_USAGE_SW_WRITE_MASK) ? C2MemoryUsage::CPU_WRITE : 0) |
52 ((usage & GRALLOC_USAGE_PROTECTED) ? C2MemoryUsage::READ_PROTECTED : 0) |
53 (usage & PASSTHROUGH_USAGE_MASK));
54}
55
56uint64_t C2AndroidMemoryUsage::asGrallocUsage() const {
57 // gralloc does not support WRITE_PROTECTED
58 return (((expected & C2MemoryUsage::CPU_READ) ? GRALLOC_USAGE_SW_READ_OFTEN : 0) |
59 ((expected & C2MemoryUsage::CPU_WRITE) ? GRALLOC_USAGE_SW_WRITE_OFTEN : 0) |
60 ((expected & C2MemoryUsage::READ_PROTECTED) ? GRALLOC_USAGE_PROTECTED : 0) |
61 (expected & PASSTHROUGH_USAGE_MASK));
62}
63
Pawin Vongmasa36653902018-11-15 00:10:25 -080064using ::android::hardware::hidl_handle;
65using ::android::hardware::hidl_vec;
Pawin Vongmasa08384942019-05-15 08:42:44 -070066using ::android::hardware::graphics::common::V1_0::BufferUsage;
67using PixelFormat2 = ::android::hardware::graphics::common::V1_0::PixelFormat;
68using PixelFormat3 = ::android::hardware::graphics::common::V1_2::PixelFormat;
Pawin Vongmasa36653902018-11-15 00:10:25 -080069
Pawin Vongmasa08384942019-05-15 08:42:44 -070070using IAllocator2 = ::android::hardware::graphics::allocator::V2_0::IAllocator;
71using BufferDescriptor2 = ::android::hardware::graphics::mapper::V2_0::BufferDescriptor;
72using Error2 = ::android::hardware::graphics::mapper::V2_0::Error;
73using IMapper2 = ::android::hardware::graphics::mapper::V2_0::IMapper;
Pawin Vongmasa36653902018-11-15 00:10:25 -080074
Pawin Vongmasa08384942019-05-15 08:42:44 -070075using IAllocator3 = ::android::hardware::graphics::allocator::V3_0::IAllocator;
76using BufferDescriptor3 = ::android::hardware::graphics::mapper::V3_0::BufferDescriptor;
77using Error3 = ::android::hardware::graphics::mapper::V3_0::Error;
78using IMapper3 = ::android::hardware::graphics::mapper::V3_0::IMapper;
79
80namespace /* unnamed */ {
81
82struct BufferDescriptorInfo2 {
83 IMapper2::BufferDescriptorInfo mapperInfo;
Pawin Vongmasa36653902018-11-15 00:10:25 -080084 uint32_t stride;
85};
86
Pawin Vongmasa08384942019-05-15 08:42:44 -070087struct BufferDescriptorInfo3 {
88 IMapper3::BufferDescriptorInfo mapperInfo;
89 uint32_t stride;
90};
Pawin Vongmasa36653902018-11-15 00:10:25 -080091
92/* ===================================== GRALLOC ALLOCATION ==================================== */
Pawin Vongmasa08384942019-05-15 08:42:44 -070093c2_status_t maperr2error(Error2 maperr) {
Pawin Vongmasa36653902018-11-15 00:10:25 -080094 switch (maperr) {
Pawin Vongmasa08384942019-05-15 08:42:44 -070095 case Error2::NONE: return C2_OK;
96 case Error2::BAD_DESCRIPTOR: return C2_BAD_VALUE;
97 case Error2::BAD_BUFFER: return C2_BAD_VALUE;
98 case Error2::BAD_VALUE: return C2_BAD_VALUE;
99 case Error2::NO_RESOURCES: return C2_NO_MEMORY;
100 case Error2::UNSUPPORTED: return C2_CANNOT_DO;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800101 }
102 return C2_CORRUPTED;
103}
104
Pawin Vongmasa08384942019-05-15 08:42:44 -0700105c2_status_t maperr2error(Error3 maperr) {
106 switch (maperr) {
107 case Error3::NONE: return C2_OK;
108 case Error3::BAD_DESCRIPTOR: return C2_BAD_VALUE;
109 case Error3::BAD_BUFFER: return C2_BAD_VALUE;
110 case Error3::BAD_VALUE: return C2_BAD_VALUE;
111 case Error3::NO_RESOURCES: return C2_NO_MEMORY;
112 case Error3::UNSUPPORTED: return C2_CANNOT_DO;
113 }
114 return C2_CORRUPTED;
115}
116
Pawin Vongmasa36653902018-11-15 00:10:25 -0800117bool native_handle_is_invalid(const native_handle_t *const handle) {
118 // perform basic validation of a native handle
119 if (handle == nullptr) {
120 // null handle is considered valid
121 return false;
122 }
123 return ((size_t)handle->version != sizeof(native_handle_t) ||
124 handle->numFds < 0 ||
125 handle->numInts < 0 ||
126 // for sanity assume handles must occupy less memory than INT_MAX bytes
127 handle->numFds > int((INT_MAX - handle->version) / sizeof(int)) - handle->numInts);
128}
129
130class C2HandleGralloc : public C2Handle {
131private:
132 struct ExtraData {
133 uint32_t width;
134 uint32_t height;
135 uint32_t format;
136 uint32_t usage_lo;
137 uint32_t usage_hi;
138 uint32_t stride;
139 uint32_t generation;
140 uint32_t igbp_id_lo;
141 uint32_t igbp_id_hi;
142 uint32_t igbp_slot;
143 uint32_t magic;
144 };
145
146 enum {
147 NUM_INTS = sizeof(ExtraData) / sizeof(int),
148 };
149 const static uint32_t MAGIC = '\xc2gr\x00';
150
151 static
152 const ExtraData* getExtraData(const C2Handle *const handle) {
153 if (handle == nullptr
154 || native_handle_is_invalid(handle)
155 || handle->numInts < NUM_INTS) {
156 return nullptr;
157 }
158 return reinterpret_cast<const ExtraData*>(
159 &handle->data[handle->numFds + handle->numInts - NUM_INTS]);
160 }
161
162 static
163 ExtraData *getExtraData(C2Handle *const handle) {
164 return const_cast<ExtraData *>(getExtraData(const_cast<const C2Handle *const>(handle)));
165 }
166
167public:
168 void getIgbpData(uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) const {
169 const ExtraData *ed = getExtraData(this);
170 *generation = ed->generation;
171 *igbp_id = unsigned(ed->igbp_id_lo) | uint64_t(unsigned(ed->igbp_id_hi)) << 32;
172 *igbp_slot = ed->igbp_slot;
173 }
174
175 static bool isValid(const C2Handle *const o) {
176 if (o == nullptr) { // null handle is always valid
177 return true;
178 }
179 const ExtraData *xd = getExtraData(o);
180 // we cannot validate width/height/format/usage without accessing gralloc driver
181 return xd != nullptr && xd->magic == MAGIC;
182 }
183
Sungtak Leea4d13be2019-01-23 15:24:46 -0800184 static C2HandleGralloc* WrapAndMoveNativeHandle(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800185 const native_handle_t *const handle,
186 uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
187 uint32_t stride, uint32_t generation, uint64_t igbp_id = 0, uint32_t igbp_slot = 0) {
188 //CHECK(handle != nullptr);
189 if (native_handle_is_invalid(handle) ||
190 handle->numInts > int((INT_MAX - handle->version) / sizeof(int)) - NUM_INTS - handle->numFds) {
191 return nullptr;
192 }
193 ExtraData xd = {
194 width, height, format, uint32_t(usage & 0xFFFFFFFF), uint32_t(usage >> 32),
195 stride, generation, uint32_t(igbp_id & 0xFFFFFFFF), uint32_t(igbp_id >> 32),
196 igbp_slot, MAGIC
197 };
198 native_handle_t *res = native_handle_create(handle->numFds, handle->numInts + NUM_INTS);
199 if (res != nullptr) {
200 memcpy(&res->data, &handle->data, sizeof(int) * (handle->numFds + handle->numInts));
201 *getExtraData(res) = xd;
202 }
203 return reinterpret_cast<C2HandleGralloc *>(res);
204 }
205
Sungtak Leea4d13be2019-01-23 15:24:46 -0800206 static C2HandleGralloc* WrapNativeHandle(
207 const native_handle_t *const handle,
208 uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
209 uint32_t stride, uint32_t generation, uint64_t igbp_id = 0, uint32_t igbp_slot = 0) {
210 if (handle == nullptr) {
211 return nullptr;
212 }
213 native_handle_t *clone = native_handle_clone(handle);
214 if (clone == nullptr) {
215 return nullptr;
216 }
217 C2HandleGralloc *res = WrapAndMoveNativeHandle(
218 clone, width, height, format, usage, stride, generation, igbp_id, igbp_slot);
219 if (res == nullptr) {
220 native_handle_close(clone);
221 }
222 native_handle_delete(clone);
223 return res;
224 }
225
Pawin Vongmasa36653902018-11-15 00:10:25 -0800226 static native_handle_t* UnwrapNativeHandle(
227 const C2Handle *const handle) {
228 const ExtraData *xd = getExtraData(handle);
229 if (xd == nullptr || xd->magic != MAGIC) {
230 return nullptr;
231 }
232 native_handle_t *res = native_handle_create(handle->numFds, handle->numInts - NUM_INTS);
233 if (res != nullptr) {
234 memcpy(&res->data, &handle->data, sizeof(int) * (res->numFds + res->numInts));
235 }
236 return res;
237 }
238
Pawin Vongmasa36653902018-11-15 00:10:25 -0800239 static const C2HandleGralloc* Import(
240 const C2Handle *const handle,
241 uint32_t *width, uint32_t *height, uint32_t *format,
242 uint64_t *usage, uint32_t *stride,
243 uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) {
244 const ExtraData *xd = getExtraData(handle);
245 if (xd == nullptr) {
246 return nullptr;
247 }
248 *width = xd->width;
249 *height = xd->height;
250 *format = xd->format;
251 *usage = xd->usage_lo | (uint64_t(xd->usage_hi) << 32);
252 *stride = xd->stride;
253 *generation = xd->generation;
254 *igbp_id = xd->igbp_id_lo | (uint64_t(xd->igbp_id_hi) << 32);
255 *igbp_slot = xd->igbp_slot;
256 return reinterpret_cast<const C2HandleGralloc *>(handle);
257 }
258};
259
Pawin Vongmasa08384942019-05-15 08:42:44 -0700260} // unnamed namespace
261
Pawin Vongmasa36653902018-11-15 00:10:25 -0800262native_handle_t *UnwrapNativeCodec2GrallocHandle(const C2Handle *const handle) {
263 return C2HandleGralloc::UnwrapNativeHandle(handle);
264}
265
Pawin Vongmasa36653902018-11-15 00:10:25 -0800266C2Handle *WrapNativeCodec2GrallocHandle(
267 const native_handle_t *const handle,
268 uint32_t width, uint32_t height, uint32_t format, uint64_t usage, uint32_t stride,
269 uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
270 return C2HandleGralloc::WrapNativeHandle(handle, width, height, format, usage, stride,
271 generation, igbp_id, igbp_slot);
272}
273
274class C2AllocationGralloc : public C2GraphicAllocation {
275public:
276 virtual ~C2AllocationGralloc() override;
277
278 virtual c2_status_t map(
279 C2Rect rect, C2MemoryUsage usage, C2Fence *fence,
280 C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) override;
281 virtual c2_status_t unmap(
282 uint8_t **addr /* nonnull */, C2Rect rect, C2Fence *fence /* nullable */) override;
283 virtual C2Allocator::id_t getAllocatorId() const override { return mAllocatorId; }
284 virtual const C2Handle *handle() const override { return mLockedHandle ? : mHandle; }
285 virtual bool equals(const std::shared_ptr<const C2GraphicAllocation> &other) const override;
286
287 // internal methods
288 // |handle| will be moved.
289 C2AllocationGralloc(
Pawin Vongmasa08384942019-05-15 08:42:44 -0700290 const BufferDescriptorInfo2 &info,
291 const sp<IMapper2> &mapper,
292 hidl_handle &hidlHandle,
293 const C2HandleGralloc *const handle,
294 C2Allocator::id_t allocatorId);
295 C2AllocationGralloc(
296 const BufferDescriptorInfo3 &info,
297 const sp<IMapper3> &mapper,
Pawin Vongmasa36653902018-11-15 00:10:25 -0800298 hidl_handle &hidlHandle,
299 const C2HandleGralloc *const handle,
300 C2Allocator::id_t allocatorId);
301 int dup() const;
302 c2_status_t status() const;
303
304private:
Pawin Vongmasa08384942019-05-15 08:42:44 -0700305 const BufferDescriptorInfo2 mInfo2{};
306 const sp<IMapper2> mMapper2{nullptr};
307 const BufferDescriptorInfo3 mInfo3{};
308 const sp<IMapper3> mMapper3{nullptr};
Pawin Vongmasa36653902018-11-15 00:10:25 -0800309 const hidl_handle mHidlHandle;
310 const C2HandleGralloc *mHandle;
311 buffer_handle_t mBuffer;
312 const C2HandleGralloc *mLockedHandle;
313 bool mLocked;
314 C2Allocator::id_t mAllocatorId;
315 std::mutex mMappedLock;
316};
317
318C2AllocationGralloc::C2AllocationGralloc(
Pawin Vongmasa08384942019-05-15 08:42:44 -0700319 const BufferDescriptorInfo2 &info,
320 const sp<IMapper2> &mapper,
Pawin Vongmasa36653902018-11-15 00:10:25 -0800321 hidl_handle &hidlHandle,
322 const C2HandleGralloc *const handle,
323 C2Allocator::id_t allocatorId)
324 : C2GraphicAllocation(info.mapperInfo.width, info.mapperInfo.height),
Pawin Vongmasa08384942019-05-15 08:42:44 -0700325 mInfo2(info),
326 mMapper2(mapper),
327 mHidlHandle(std::move(hidlHandle)),
328 mHandle(handle),
329 mBuffer(nullptr),
330 mLockedHandle(nullptr),
331 mLocked(false),
332 mAllocatorId(allocatorId) {
333}
334
335C2AllocationGralloc::C2AllocationGralloc(
336 const BufferDescriptorInfo3 &info,
337 const sp<IMapper3> &mapper,
338 hidl_handle &hidlHandle,
339 const C2HandleGralloc *const handle,
340 C2Allocator::id_t allocatorId)
341 : C2GraphicAllocation(info.mapperInfo.width, info.mapperInfo.height),
342 mInfo3(info),
343 mMapper3(mapper),
Pawin Vongmasa36653902018-11-15 00:10:25 -0800344 mHidlHandle(std::move(hidlHandle)),
345 mHandle(handle),
346 mBuffer(nullptr),
347 mLockedHandle(nullptr),
348 mLocked(false),
349 mAllocatorId(allocatorId) {
350}
351
352C2AllocationGralloc::~C2AllocationGralloc() {
Yichi Chenfa94a3b2018-12-08 00:06:25 +0800353 if (mBuffer && mLocked) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800354 // implementation ignores addresss and rect
355 uint8_t* addr[C2PlanarLayout::MAX_NUM_PLANES] = {};
356 unmap(addr, C2Rect(), nullptr);
357 }
Yichi Chenfa94a3b2018-12-08 00:06:25 +0800358 if (mBuffer) {
Pawin Vongmasa08384942019-05-15 08:42:44 -0700359 if (mMapper2) {
360 if (!mMapper2->freeBuffer(const_cast<native_handle_t *>(
361 mBuffer)).isOk()) {
362 ALOGE("failed transaction: freeBuffer");
363 }
364 } else {
365 if (!mMapper3->freeBuffer(const_cast<native_handle_t *>(
366 mBuffer)).isOk()) {
367 ALOGE("failed transaction: freeBuffer");
368 }
369 }
Yichi Chenfa94a3b2018-12-08 00:06:25 +0800370 }
371 if (mHandle) {
372 native_handle_delete(
373 const_cast<native_handle_t *>(reinterpret_cast<const native_handle_t *>(mHandle)));
374 }
Sungtak Lee2729dcf2019-01-18 13:15:07 -0800375 if (mLockedHandle) {
376 native_handle_delete(
377 const_cast<native_handle_t *>(
378 reinterpret_cast<const native_handle_t *>(mLockedHandle)));
379 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800380}
381
382c2_status_t C2AllocationGralloc::map(
383 C2Rect rect, C2MemoryUsage usage, C2Fence *fence,
384 C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) {
385 uint64_t grallocUsage = static_cast<C2AndroidMemoryUsage>(usage).asGrallocUsage();
386 ALOGV("mapping buffer with usage %#llx => %#llx",
387 (long long)usage.expected, (long long)grallocUsage);
388
389 // TODO
390 (void) fence;
391
392 std::lock_guard<std::mutex> lock(mMappedLock);
393 if (mBuffer && mLocked) {
394 ALOGD("already mapped");
395 return C2_DUPLICATE;
396 }
397 if (!layout || !addr) {
398 ALOGD("wrong param");
399 return C2_BAD_VALUE;
400 }
401
402 c2_status_t err = C2_OK;
403 if (!mBuffer) {
Pawin Vongmasa08384942019-05-15 08:42:44 -0700404 if (mMapper2) {
405 if (!mMapper2->importBuffer(
406 mHidlHandle, [&err, this](const auto &maperr, const auto &buffer) {
407 err = maperr2error(maperr);
408 if (err == C2_OK) {
409 mBuffer = static_cast<buffer_handle_t>(buffer);
410 }
411 }).isOk()) {
412 ALOGE("failed transaction: importBuffer");
413 return C2_CORRUPTED;
414 }
415 } else {
416 if (!mMapper3->importBuffer(
417 mHidlHandle, [&err, this](const auto &maperr, const auto &buffer) {
418 err = maperr2error(maperr);
419 if (err == C2_OK) {
420 mBuffer = static_cast<buffer_handle_t>(buffer);
421 }
422 }).isOk()) {
423 ALOGE("failed transaction: importBuffer (@3.0)");
424 return C2_CORRUPTED;
425 }
426 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800427 if (err != C2_OK) {
428 ALOGD("importBuffer failed: %d", err);
429 return err;
430 }
431 if (mBuffer == nullptr) {
432 ALOGD("importBuffer returned null buffer");
433 return C2_CORRUPTED;
434 }
435 uint32_t generation = 0;
436 uint64_t igbp_id = 0;
437 uint32_t igbp_slot = 0;
438 if (mHandle) {
439 mHandle->getIgbpData(&generation, &igbp_id, &igbp_slot);
440 }
Pawin Vongmasa08384942019-05-15 08:42:44 -0700441 if (mMapper2) {
442 mLockedHandle = C2HandleGralloc::WrapAndMoveNativeHandle(
443 mBuffer, mInfo2.mapperInfo.width, mInfo2.mapperInfo.height,
444 (uint32_t)mInfo2.mapperInfo.format, mInfo2.mapperInfo.usage,
445 mInfo2.stride, generation, igbp_id, igbp_slot);
446 } else {
447 mLockedHandle = C2HandleGralloc::WrapAndMoveNativeHandle(
448 mBuffer, mInfo3.mapperInfo.width, mInfo3.mapperInfo.height,
449 (uint32_t)mInfo3.mapperInfo.format, mInfo3.mapperInfo.usage,
450 mInfo3.stride, generation, igbp_id, igbp_slot);
451 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800452 }
453
Pawin Vongmasa08384942019-05-15 08:42:44 -0700454 PixelFormat3 format = mMapper2 ?
455 PixelFormat3(mInfo2.mapperInfo.format) :
456 PixelFormat3(mInfo3.mapperInfo.format);
457 switch (format) {
458 case PixelFormat3::RGBA_1010102: {
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700459 // TRICKY: this is used for media as YUV444 in the case when it is queued directly to a
460 // Surface. In all other cases it is RGBA. We don't know which case it is here, so
461 // default to YUV for now.
462 void *pointer = nullptr;
Pawin Vongmasa08384942019-05-15 08:42:44 -0700463 if (mMapper2) {
464 if (!mMapper2->lock(
465 const_cast<native_handle_t *>(mBuffer),
466 grallocUsage,
467 { (int32_t)rect.left, (int32_t)rect.top,
468 (int32_t)rect.width, (int32_t)rect.height },
469 // TODO: fence
470 hidl_handle(),
471 [&err, &pointer](const auto &maperr, const auto &mapPointer) {
472 err = maperr2error(maperr);
473 if (err == C2_OK) {
474 pointer = mapPointer;
475 }
476 }).isOk()) {
477 ALOGE("failed transaction: lock(RGBA_1010102)");
478 return C2_CORRUPTED;
479 }
480 } else {
481 if (!mMapper3->lock(
482 const_cast<native_handle_t *>(mBuffer),
483 grallocUsage,
484 { (int32_t)rect.left, (int32_t)rect.top,
485 (int32_t)rect.width, (int32_t)rect.height },
486 // TODO: fence
487 hidl_handle(),
488 [&err, &pointer](const auto &maperr, const auto &mapPointer,
489 int32_t bytesPerPixel, int32_t bytesPerStride) {
490 err = maperr2error(maperr);
491 if (err == C2_OK) {
492 pointer = mapPointer;
493 }
494 (void)bytesPerPixel;
495 (void)bytesPerStride;
496 }).isOk()) {
497 ALOGE("failed transaction: lock(RGBA_1010102) (@3.0)");
498 return C2_CORRUPTED;
499 }
500 }
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700501 if (err != C2_OK) {
502 ALOGD("lock failed: %d", err);
503 return err;
504 }
505 // treat as 32-bit values
506 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)pointer;
507 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)pointer;
508 addr[C2PlanarLayout::PLANE_V] = (uint8_t *)pointer;
509 addr[C2PlanarLayout::PLANE_A] = (uint8_t *)pointer;
510 layout->type = C2PlanarLayout::TYPE_YUVA;
511 layout->numPlanes = 4;
512 layout->rootPlanes = 1;
Pawin Vongmasa08384942019-05-15 08:42:44 -0700513 int32_t stride = mMapper2 ?
514 int32_t(mInfo2.stride) :
515 int32_t(mInfo3.stride);
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700516 layout->planes[C2PlanarLayout::PLANE_Y] = {
517 C2PlaneInfo::CHANNEL_Y, // channel
518 4, // colInc
Pawin Vongmasa08384942019-05-15 08:42:44 -0700519 4 * stride, // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700520 1, // mColSampling
521 1, // mRowSampling
522 32, // allocatedDepth
523 10, // bitDepth
524 10, // rightShift
525 C2PlaneInfo::LITTLE_END, // endianness
526 C2PlanarLayout::PLANE_Y, // rootIx
527 0, // offset
528 };
529 layout->planes[C2PlanarLayout::PLANE_U] = {
530 C2PlaneInfo::CHANNEL_CB, // channel
531 4, // colInc
Pawin Vongmasa08384942019-05-15 08:42:44 -0700532 4 * stride, // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700533 1, // mColSampling
534 1, // mRowSampling
535 32, // allocatedDepth
536 10, // bitDepth
537 0, // rightShift
538 C2PlaneInfo::LITTLE_END, // endianness
539 C2PlanarLayout::PLANE_Y, // rootIx
540 0, // offset
541 };
542 layout->planes[C2PlanarLayout::PLANE_V] = {
543 C2PlaneInfo::CHANNEL_CR, // channel
544 4, // colInc
Pawin Vongmasa08384942019-05-15 08:42:44 -0700545 4 * stride, // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700546 1, // mColSampling
547 1, // mRowSampling
548 32, // allocatedDepth
549 10, // bitDepth
550 20, // rightShift
551 C2PlaneInfo::LITTLE_END, // endianness
552 C2PlanarLayout::PLANE_Y, // rootIx
553 0, // offset
554 };
555 layout->planes[C2PlanarLayout::PLANE_A] = {
556 C2PlaneInfo::CHANNEL_A, // channel
557 4, // colInc
Pawin Vongmasa08384942019-05-15 08:42:44 -0700558 4 * stride, // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700559 1, // mColSampling
560 1, // mRowSampling
561 32, // allocatedDepth
562 2, // bitDepth
563 30, // rightShift
564 C2PlaneInfo::LITTLE_END, // endianness
565 C2PlanarLayout::PLANE_Y, // rootIx
566 0, // offset
567 };
568 break;
569 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800570
Pawin Vongmasa08384942019-05-15 08:42:44 -0700571 case PixelFormat3::RGBA_8888:
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700572 // TODO: alpha channel
573 // fall-through
Pawin Vongmasa08384942019-05-15 08:42:44 -0700574 case PixelFormat3::RGBX_8888: {
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700575 void *pointer = nullptr;
Pawin Vongmasa08384942019-05-15 08:42:44 -0700576 if (mMapper2) {
577 if (!mMapper2->lock(
578 const_cast<native_handle_t *>(mBuffer),
579 grallocUsage,
580 { (int32_t)rect.left, (int32_t)rect.top,
581 (int32_t)rect.width, (int32_t)rect.height },
582 // TODO: fence
583 hidl_handle(),
584 [&err, &pointer](const auto &maperr, const auto &mapPointer) {
585 err = maperr2error(maperr);
586 if (err == C2_OK) {
587 pointer = mapPointer;
588 }
589 }).isOk()) {
590 ALOGE("failed transaction: lock(RGBA_8888)");
591 return C2_CORRUPTED;
592 }
593 } else {
594 if (!mMapper3->lock(
595 const_cast<native_handle_t *>(mBuffer),
596 grallocUsage,
597 { (int32_t)rect.left, (int32_t)rect.top,
598 (int32_t)rect.width, (int32_t)rect.height },
599 // TODO: fence
600 hidl_handle(),
601 [&err, &pointer](const auto &maperr, const auto &mapPointer,
602 int32_t bytesPerPixel, int32_t bytesPerStride) {
603 err = maperr2error(maperr);
604 if (err == C2_OK) {
605 pointer = mapPointer;
606 }
607 (void)bytesPerPixel;
608 (void)bytesPerStride;
609 }).isOk()) {
610 ALOGE("failed transaction: lock(RGBA_8888) (@3.0)");
611 return C2_CORRUPTED;
612 }
613 }
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700614 if (err != C2_OK) {
615 ALOGD("lock failed: %d", err);
616 return err;
617 }
618 addr[C2PlanarLayout::PLANE_R] = (uint8_t *)pointer;
619 addr[C2PlanarLayout::PLANE_G] = (uint8_t *)pointer + 1;
620 addr[C2PlanarLayout::PLANE_B] = (uint8_t *)pointer + 2;
621 layout->type = C2PlanarLayout::TYPE_RGB;
622 layout->numPlanes = 3;
623 layout->rootPlanes = 1;
Pawin Vongmasa08384942019-05-15 08:42:44 -0700624 int32_t stride = mMapper2 ?
625 int32_t(mInfo2.stride) :
626 int32_t(mInfo3.stride);
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700627 layout->planes[C2PlanarLayout::PLANE_R] = {
628 C2PlaneInfo::CHANNEL_R, // channel
629 4, // colInc
Pawin Vongmasa08384942019-05-15 08:42:44 -0700630 4 * stride, // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700631 1, // mColSampling
632 1, // mRowSampling
633 8, // allocatedDepth
634 8, // bitDepth
635 0, // rightShift
636 C2PlaneInfo::NATIVE, // endianness
637 C2PlanarLayout::PLANE_R, // rootIx
638 0, // offset
639 };
640 layout->planes[C2PlanarLayout::PLANE_G] = {
641 C2PlaneInfo::CHANNEL_G, // channel
642 4, // colInc
Pawin Vongmasa08384942019-05-15 08:42:44 -0700643 4 * stride, // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700644 1, // mColSampling
645 1, // mRowSampling
646 8, // allocatedDepth
647 8, // bitDepth
648 0, // rightShift
649 C2PlaneInfo::NATIVE, // endianness
650 C2PlanarLayout::PLANE_R, // rootIx
651 1, // offset
652 };
653 layout->planes[C2PlanarLayout::PLANE_B] = {
654 C2PlaneInfo::CHANNEL_B, // channel
655 4, // colInc
Pawin Vongmasa08384942019-05-15 08:42:44 -0700656 4 * stride, // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700657 1, // mColSampling
658 1, // mRowSampling
659 8, // allocatedDepth
660 8, // bitDepth
661 0, // rightShift
662 C2PlaneInfo::NATIVE, // endianness
663 C2PlanarLayout::PLANE_R, // rootIx
664 2, // offset
665 };
666 break;
667 }
668
Pawin Vongmasa08384942019-05-15 08:42:44 -0700669 case PixelFormat3::YCBCR_420_888:
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700670 // fall-through
Pawin Vongmasa08384942019-05-15 08:42:44 -0700671 case PixelFormat3::YV12:
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700672 // fall-through
673 default: {
Pawin Vongmasa08384942019-05-15 08:42:44 -0700674 struct YCbCrLayout {
675 void* y;
676 void* cb;
677 void* cr;
678 uint32_t yStride;
679 uint32_t cStride;
680 uint32_t chromaStep;
681 };
Pawin Vongmasa36653902018-11-15 00:10:25 -0800682 YCbCrLayout ycbcrLayout;
Pawin Vongmasa08384942019-05-15 08:42:44 -0700683 if (mMapper2) {
684 if (!mMapper2->lockYCbCr(
685 const_cast<native_handle_t *>(mBuffer), grallocUsage,
686 { (int32_t)rect.left, (int32_t)rect.top,
687 (int32_t)rect.width, (int32_t)rect.height },
688 // TODO: fence
689 hidl_handle(),
690 [&err, &ycbcrLayout](const auto &maperr, const auto &mapLayout) {
691 err = maperr2error(maperr);
692 if (err == C2_OK) {
693 ycbcrLayout = YCbCrLayout{
694 mapLayout.y,
695 mapLayout.cb,
696 mapLayout.cr,
697 mapLayout.yStride,
698 mapLayout.cStride,
699 mapLayout.chromaStep};
700 }
701 }).isOk()) {
702 ALOGE("failed transaction: lockYCbCr");
703 return C2_CORRUPTED;
704 }
705 } else {
706 if (!mMapper3->lockYCbCr(
707 const_cast<native_handle_t *>(mBuffer), grallocUsage,
708 { (int32_t)rect.left, (int32_t)rect.top,
709 (int32_t)rect.width, (int32_t)rect.height },
710 // TODO: fence
711 hidl_handle(),
712 [&err, &ycbcrLayout](const auto &maperr, const auto &mapLayout) {
713 err = maperr2error(maperr);
714 if (err == C2_OK) {
715 ycbcrLayout = YCbCrLayout{
716 mapLayout.y,
717 mapLayout.cb,
718 mapLayout.cr,
719 mapLayout.yStride,
720 mapLayout.cStride,
721 mapLayout.chromaStep};
722 }
723 }).isOk()) {
724 ALOGE("failed transaction: lockYCbCr (@3.0)");
725 return C2_CORRUPTED;
726 }
727 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800728 if (err != C2_OK) {
729 ALOGD("lockYCbCr failed: %d", err);
730 return err;
731 }
732 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)ycbcrLayout.y;
733 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)ycbcrLayout.cb;
734 addr[C2PlanarLayout::PLANE_V] = (uint8_t *)ycbcrLayout.cr;
735 layout->type = C2PlanarLayout::TYPE_YUV;
736 layout->numPlanes = 3;
737 layout->rootPlanes = 3;
738 layout->planes[C2PlanarLayout::PLANE_Y] = {
739 C2PlaneInfo::CHANNEL_Y, // channel
740 1, // colInc
741 (int32_t)ycbcrLayout.yStride, // rowInc
742 1, // mColSampling
743 1, // mRowSampling
744 8, // allocatedDepth
745 8, // bitDepth
746 0, // rightShift
747 C2PlaneInfo::NATIVE, // endianness
748 C2PlanarLayout::PLANE_Y, // rootIx
749 0, // offset
750 };
751 layout->planes[C2PlanarLayout::PLANE_U] = {
752 C2PlaneInfo::CHANNEL_CB, // channel
753 (int32_t)ycbcrLayout.chromaStep, // colInc
754 (int32_t)ycbcrLayout.cStride, // rowInc
755 2, // mColSampling
756 2, // mRowSampling
757 8, // allocatedDepth
758 8, // bitDepth
759 0, // rightShift
760 C2PlaneInfo::NATIVE, // endianness
761 C2PlanarLayout::PLANE_U, // rootIx
762 0, // offset
763 };
764 layout->planes[C2PlanarLayout::PLANE_V] = {
765 C2PlaneInfo::CHANNEL_CR, // channel
766 (int32_t)ycbcrLayout.chromaStep, // colInc
767 (int32_t)ycbcrLayout.cStride, // rowInc
768 2, // mColSampling
769 2, // mRowSampling
770 8, // allocatedDepth
771 8, // bitDepth
772 0, // rightShift
773 C2PlaneInfo::NATIVE, // endianness
774 C2PlanarLayout::PLANE_V, // rootIx
775 0, // offset
776 };
777 // handle interleaved formats
778 intptr_t uvOffset = addr[C2PlanarLayout::PLANE_V] - addr[C2PlanarLayout::PLANE_U];
779 if (uvOffset > 0 && uvOffset < (intptr_t)ycbcrLayout.chromaStep) {
780 layout->rootPlanes = 2;
781 layout->planes[C2PlanarLayout::PLANE_V].rootIx = C2PlanarLayout::PLANE_U;
782 layout->planes[C2PlanarLayout::PLANE_V].offset = uvOffset;
783 } else if (uvOffset < 0 && uvOffset > -(intptr_t)ycbcrLayout.chromaStep) {
784 layout->rootPlanes = 2;
785 layout->planes[C2PlanarLayout::PLANE_U].rootIx = C2PlanarLayout::PLANE_V;
786 layout->planes[C2PlanarLayout::PLANE_U].offset = -uvOffset;
787 }
788 break;
789 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800790 }
791 mLocked = true;
792
793 return C2_OK;
794}
795
796c2_status_t C2AllocationGralloc::unmap(
797 uint8_t **addr, C2Rect rect, C2Fence *fence /* nullable */) {
798 // TODO: check addr and size, use fence
799 (void)addr;
800 (void)rect;
801
802 std::lock_guard<std::mutex> lock(mMappedLock);
803 c2_status_t err = C2_OK;
Pawin Vongmasa08384942019-05-15 08:42:44 -0700804 if (mMapper2) {
805 if (!mMapper2->unlock(
806 const_cast<native_handle_t *>(mBuffer),
807 [&err, &fence](const auto &maperr, const auto &releaseFence) {
808 // TODO
809 (void) fence;
810 (void) releaseFence;
811 err = maperr2error(maperr);
812 if (err == C2_OK) {
813 // TODO: fence
814 }
815 }).isOk()) {
816 ALOGE("failed transaction: unlock");
817 return C2_CORRUPTED;
818 }
819 } else {
820 if (!mMapper3->unlock(
821 const_cast<native_handle_t *>(mBuffer),
822 [&err, &fence](const auto &maperr, const auto &releaseFence) {
823 // TODO
824 (void) fence;
825 (void) releaseFence;
826 err = maperr2error(maperr);
827 if (err == C2_OK) {
828 // TODO: fence
829 }
830 }).isOk()) {
831 ALOGE("failed transaction: unlock (@3.0)");
832 return C2_CORRUPTED;
833 }
834 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800835 if (err == C2_OK) {
836 mLocked = false;
837 }
838 return err;
839}
840
841bool C2AllocationGralloc::equals(const std::shared_ptr<const C2GraphicAllocation> &other) const {
842 return other && other->handle() == handle();
843}
844
845/* ===================================== GRALLOC ALLOCATOR ==================================== */
846class C2AllocatorGralloc::Impl {
847public:
848 Impl(id_t id, bool bufferQueue);
849
850 id_t getId() const {
851 return mTraits->id;
852 }
853
854 C2String getName() const {
855 return mTraits->name;
856 }
857
858 std::shared_ptr<const C2Allocator::Traits> getTraits() const {
859 return mTraits;
860 }
861
862 c2_status_t newGraphicAllocation(
863 uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
864 std::shared_ptr<C2GraphicAllocation> *allocation);
865
866 c2_status_t priorGraphicAllocation(
867 const C2Handle *handle,
868 std::shared_ptr<C2GraphicAllocation> *allocation);
869
870 c2_status_t status() const { return mInit; }
871
872private:
873 std::shared_ptr<C2Allocator::Traits> mTraits;
874 c2_status_t mInit;
Pawin Vongmasa08384942019-05-15 08:42:44 -0700875 sp<IAllocator2> mAllocator2;
876 sp<IMapper2> mMapper2;
877 sp<IAllocator3> mAllocator3;
878 sp<IMapper3> mMapper3;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800879 const bool mBufferQueue;
880};
881
882void _UnwrapNativeCodec2GrallocMetadata(
883 const C2Handle *const handle,
884 uint32_t *width, uint32_t *height, uint32_t *format,uint64_t *usage, uint32_t *stride,
885 uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) {
886 (void)C2HandleGralloc::Import(handle, width, height, format, usage, stride,
887 generation, igbp_id, igbp_slot);
888}
889
890C2AllocatorGralloc::Impl::Impl(id_t id, bool bufferQueue)
891 : mInit(C2_OK), mBufferQueue(bufferQueue) {
892 // TODO: get this from allocator
893 C2MemoryUsage minUsage = { 0, 0 }, maxUsage = { ~(uint64_t)0, ~(uint64_t)0 };
894 Traits traits = { "android.allocator.gralloc", id, C2Allocator::GRAPHIC, minUsage, maxUsage };
895 mTraits = std::make_shared<C2Allocator::Traits>(traits);
896
897 // gralloc allocator is a singleton, so all objects share a global service
Pawin Vongmasa08384942019-05-15 08:42:44 -0700898 mAllocator3 = IAllocator3::getService();
899 mMapper3 = IMapper3::getService();
900 if (!mAllocator3 || !mMapper3) {
901 mAllocator3 = nullptr;
902 mMapper3 = nullptr;
903 mAllocator2 = IAllocator2::getService();
904 mMapper2 = IMapper2::getService();
905 if (!mAllocator2 || !mMapper2) {
906 mAllocator2 = nullptr;
907 mMapper2 = nullptr;
908 mInit = C2_CORRUPTED;
909 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800910 }
911}
912
913c2_status_t C2AllocatorGralloc::Impl::newGraphicAllocation(
914 uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
915 std::shared_ptr<C2GraphicAllocation> *allocation) {
916 uint64_t grallocUsage = static_cast<C2AndroidMemoryUsage>(usage).asGrallocUsage();
917 ALOGV("allocating buffer with usage %#llx => %#llx",
918 (long long)usage.expected, (long long)grallocUsage);
919
Pawin Vongmasa36653902018-11-15 00:10:25 -0800920 c2_status_t err = C2_OK;
Pawin Vongmasa08384942019-05-15 08:42:44 -0700921 hidl_handle buffer{};
922
923 if (mMapper2) {
924 BufferDescriptorInfo2 info = {
925 {
926 width,
927 height,
928 1u, // layerCount
929 PixelFormat2(format),
930 grallocUsage,
931 },
932 0u, // stride placeholder
933 };
934 BufferDescriptor2 desc;
935 if (!mMapper2->createDescriptor(
936 info.mapperInfo, [&err, &desc](const auto &maperr, const auto &descriptor) {
937 err = maperr2error(maperr);
938 if (err == C2_OK) {
939 desc = descriptor;
940 }
941 }).isOk()) {
942 ALOGE("failed transaction: createDescriptor");
943 return C2_CORRUPTED;
944 }
945 if (err != C2_OK) {
946 return err;
947 }
948
949 // IAllocator shares IMapper error codes.
950 if (!mAllocator2->allocate(
951 desc,
952 1u,
953 [&err, &buffer, &info](const auto &maperr, const auto &stride, auto &buffers) {
954 err = maperr2error(maperr);
955 if (err != C2_OK) {
956 return;
957 }
958 if (buffers.size() != 1u) {
959 err = C2_CORRUPTED;
960 return;
961 }
962 info.stride = stride;
963 buffer = buffers[0];
964 }).isOk()) {
965 ALOGE("failed transaction: allocate");
966 return C2_CORRUPTED;
967 }
968 if (err != C2_OK) {
969 return err;
970 }
971 allocation->reset(new C2AllocationGralloc(
972 info, mMapper2, buffer,
973 C2HandleGralloc::WrapAndMoveNativeHandle(
974 buffer.getNativeHandle(),
975 width, height,
976 format, grallocUsage, info.stride,
977 0, 0, mBufferQueue ? ~0 : 0),
978 mTraits->id));
979 return C2_OK;
980 } else {
981 BufferDescriptorInfo3 info = {
982 {
983 width,
984 height,
985 1u, // layerCount
986 PixelFormat3(format),
987 grallocUsage,
988 },
989 0u, // stride placeholder
990 };
991 BufferDescriptor3 desc;
992 if (!mMapper3->createDescriptor(
993 info.mapperInfo, [&err, &desc](const auto &maperr, const auto &descriptor) {
994 err = maperr2error(maperr);
995 if (err == C2_OK) {
996 desc = descriptor;
997 }
998 }).isOk()) {
999 ALOGE("failed transaction: createDescriptor");
1000 return C2_CORRUPTED;
1001 }
1002 if (err != C2_OK) {
1003 return err;
1004 }
1005
1006 // IAllocator shares IMapper error codes.
1007 if (!mAllocator3->allocate(
1008 desc,
1009 1u,
1010 [&err, &buffer, &info](const auto &maperr, const auto &stride, auto &buffers) {
1011 err = maperr2error(maperr);
1012 if (err != C2_OK) {
1013 return;
1014 }
1015 if (buffers.size() != 1u) {
1016 err = C2_CORRUPTED;
1017 return;
1018 }
1019 info.stride = stride;
1020 buffer = buffers[0];
1021 }).isOk()) {
1022 ALOGE("failed transaction: allocate");
1023 return C2_CORRUPTED;
1024 }
1025 if (err != C2_OK) {
1026 return err;
1027 }
1028 allocation->reset(new C2AllocationGralloc(
1029 info, mMapper3, buffer,
1030 C2HandleGralloc::WrapAndMoveNativeHandle(
1031 buffer.getNativeHandle(),
1032 width, height,
1033 format, grallocUsage, info.stride,
1034 0, 0, mBufferQueue ? ~0 : 0),
1035 mTraits->id));
1036 return C2_OK;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001037 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001038}
1039
1040c2_status_t C2AllocatorGralloc::Impl::priorGraphicAllocation(
1041 const C2Handle *handle,
1042 std::shared_ptr<C2GraphicAllocation> *allocation) {
Pawin Vongmasa08384942019-05-15 08:42:44 -07001043 if (mMapper2) {
1044 BufferDescriptorInfo2 info;
1045 info.mapperInfo.layerCount = 1u;
1046 uint32_t generation;
1047 uint64_t igbp_id;
1048 uint32_t igbp_slot;
1049 const C2HandleGralloc *grallocHandle = C2HandleGralloc::Import(
1050 handle,
1051 &info.mapperInfo.width, &info.mapperInfo.height,
1052 (uint32_t *)&info.mapperInfo.format,
1053 (uint64_t *)&info.mapperInfo.usage,
1054 &info.stride,
1055 &generation, &igbp_id, &igbp_slot);
1056 if (grallocHandle == nullptr) {
1057 return C2_BAD_VALUE;
1058 }
1059
1060 hidl_handle hidlHandle;
1061 hidlHandle.setTo(C2HandleGralloc::UnwrapNativeHandle(grallocHandle), true);
1062
1063 allocation->reset(new C2AllocationGralloc(
1064 info, mMapper2, hidlHandle, grallocHandle, mTraits->id));
1065 return C2_OK;
1066 } else {
1067 BufferDescriptorInfo3 info;
1068 info.mapperInfo.layerCount = 1u;
1069 uint32_t generation;
1070 uint64_t igbp_id;
1071 uint32_t igbp_slot;
1072 const C2HandleGralloc *grallocHandle = C2HandleGralloc::Import(
1073 handle,
1074 &info.mapperInfo.width, &info.mapperInfo.height,
1075 (uint32_t *)&info.mapperInfo.format,
1076 (uint64_t *)&info.mapperInfo.usage,
1077 &info.stride,
1078 &generation, &igbp_id, &igbp_slot);
1079 if (grallocHandle == nullptr) {
1080 return C2_BAD_VALUE;
1081 }
1082
1083 hidl_handle hidlHandle;
1084 hidlHandle.setTo(C2HandleGralloc::UnwrapNativeHandle(grallocHandle), true);
1085
1086 allocation->reset(new C2AllocationGralloc(
1087 info, mMapper3, hidlHandle, grallocHandle, mTraits->id));
1088 return C2_OK;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001089 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001090}
1091
1092C2AllocatorGralloc::C2AllocatorGralloc(id_t id, bool bufferQueue)
1093 : mImpl(new Impl(id, bufferQueue)) {}
1094
1095C2AllocatorGralloc::~C2AllocatorGralloc() { delete mImpl; }
1096
1097C2Allocator::id_t C2AllocatorGralloc::getId() const {
1098 return mImpl->getId();
1099}
1100
1101C2String C2AllocatorGralloc::getName() const {
1102 return mImpl->getName();
1103}
1104
1105std::shared_ptr<const C2Allocator::Traits> C2AllocatorGralloc::getTraits() const {
1106 return mImpl->getTraits();
1107}
1108
1109c2_status_t C2AllocatorGralloc::newGraphicAllocation(
1110 uint32_t width, uint32_t height, uint32_t format, C2MemoryUsage usage,
1111 std::shared_ptr<C2GraphicAllocation> *allocation) {
1112 return mImpl->newGraphicAllocation(width, height, format, usage, allocation);
1113}
1114
1115c2_status_t C2AllocatorGralloc::priorGraphicAllocation(
1116 const C2Handle *handle,
1117 std::shared_ptr<C2GraphicAllocation> *allocation) {
1118 return mImpl->priorGraphicAllocation(handle, allocation);
1119}
1120
1121c2_status_t C2AllocatorGralloc::status() const {
1122 return mImpl->status();
1123}
1124
1125bool C2AllocatorGralloc::isValid(const C2Handle* const o) {
1126 return C2HandleGralloc::isValid(o);
1127}
1128
1129} // namespace android