blob: a4a9b3ab1e48a92b48d1ac576215f195162fc936 [file] [log] [blame]
Pawin Vongmasa36653902018-11-15 00:10:25 -08001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "C2AllocatorGralloc"
19#include <utils/Log.h>
20
Marissa Wall2a24a302019-11-25 11:19:18 -080021#include <mutex>
22
Praveen Chavan34493f12021-02-18 00:51:50 -080023#include <aidl/android/hardware/graphics/common/PlaneLayoutComponentType.h>
Marissa Wall2a24a302019-11-25 11:19:18 -080024#include <android/hardware/graphics/common/1.2/types.h>
Pawin Vongmasa36653902018-11-15 00:10:25 -080025#include <cutils/native_handle.h>
Praveen Chavan34493f12021-02-18 00:51:50 -080026#include <gralloctypes/Gralloc4.h>
Pawin Vongmasa36653902018-11-15 00:10:25 -080027#include <hardware/gralloc.h>
Marissa Wall2a24a302019-11-25 11:19:18 -080028#include <ui/GraphicBufferAllocator.h>
29#include <ui/GraphicBufferMapper.h>
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +090030#include <ui/Rect.h>
Pawin Vongmasa36653902018-11-15 00:10:25 -080031
32#include <C2AllocatorGralloc.h>
33#include <C2Buffer.h>
Praveen Chavan34493f12021-02-18 00:51:50 -080034#include <C2Debug.h>
Pawin Vongmasa36653902018-11-15 00:10:25 -080035#include <C2PlatformSupport.h>
36
Marissa Wall2a24a302019-11-25 11:19:18 -080037using ::android::hardware::hidl_handle;
38using PixelFormat4 = ::android::hardware::graphics::common::V1_2::PixelFormat;
39
Pawin Vongmasa36653902018-11-15 00:10:25 -080040namespace android {
41
Pawin Vongmasad032f2d2019-05-15 08:42:44 -070042namespace /* unnamed */ {
Pawin Vongmasa36653902018-11-15 00:10:25 -080043 enum : uint64_t {
44 /**
45 * Usage mask that is passed through from gralloc to Codec 2.0 usage.
46 */
47 PASSTHROUGH_USAGE_MASK =
Charlie Chen49d3fe72021-03-25 20:02:37 +080048 ~static_cast<uint64_t>(GRALLOC_USAGE_SW_READ_MASK |
49 GRALLOC_USAGE_SW_WRITE_MASK |
50 GRALLOC_USAGE_PROTECTED)
Pawin Vongmasa36653902018-11-15 00:10:25 -080051 };
52
53 // verify that passthrough mask is within the platform mask
54 static_assert((~C2MemoryUsage::PLATFORM_MASK & PASSTHROUGH_USAGE_MASK) == 0, "");
Pawin Vongmasad032f2d2019-05-15 08:42:44 -070055} // unnamed
Pawin Vongmasa36653902018-11-15 00:10:25 -080056
Harish Mahendrakar7dc54f92022-06-30 20:36:23 -070057static bool isAtLeastT() {
58 return android_get_device_api_level() >= __ANDROID_API_T__;
59}
60
Pawin Vongmasa36653902018-11-15 00:10:25 -080061C2MemoryUsage C2AndroidMemoryUsage::FromGrallocUsage(uint64_t usage) {
62 // gralloc does not support WRITE_PROTECTED
63 return C2MemoryUsage(
64 ((usage & GRALLOC_USAGE_SW_READ_MASK) ? C2MemoryUsage::CPU_READ : 0) |
65 ((usage & GRALLOC_USAGE_SW_WRITE_MASK) ? C2MemoryUsage::CPU_WRITE : 0) |
66 ((usage & GRALLOC_USAGE_PROTECTED) ? C2MemoryUsage::READ_PROTECTED : 0) |
67 (usage & PASSTHROUGH_USAGE_MASK));
68}
69
70uint64_t C2AndroidMemoryUsage::asGrallocUsage() const {
71 // gralloc does not support WRITE_PROTECTED
72 return (((expected & C2MemoryUsage::CPU_READ) ? GRALLOC_USAGE_SW_READ_OFTEN : 0) |
73 ((expected & C2MemoryUsage::CPU_WRITE) ? GRALLOC_USAGE_SW_WRITE_OFTEN : 0) |
74 ((expected & C2MemoryUsage::READ_PROTECTED) ? GRALLOC_USAGE_PROTECTED : 0) |
75 (expected & PASSTHROUGH_USAGE_MASK));
76}
77
Pawin Vongmasad032f2d2019-05-15 08:42:44 -070078namespace /* unnamed */ {
79
Pawin Vongmasa36653902018-11-15 00:10:25 -080080/* ===================================== GRALLOC ALLOCATION ==================================== */
Pawin Vongmasa36653902018-11-15 00:10:25 -080081bool native_handle_is_invalid(const native_handle_t *const handle) {
82 // perform basic validation of a native handle
83 if (handle == nullptr) {
84 // null handle is considered valid
85 return false;
86 }
87 return ((size_t)handle->version != sizeof(native_handle_t) ||
88 handle->numFds < 0 ||
89 handle->numInts < 0 ||
90 // for sanity assume handles must occupy less memory than INT_MAX bytes
91 handle->numFds > int((INT_MAX - handle->version) / sizeof(int)) - handle->numInts);
92}
93
94class C2HandleGralloc : public C2Handle {
95private:
96 struct ExtraData {
97 uint32_t width;
98 uint32_t height;
99 uint32_t format;
100 uint32_t usage_lo;
101 uint32_t usage_hi;
102 uint32_t stride;
103 uint32_t generation;
104 uint32_t igbp_id_lo;
105 uint32_t igbp_id_hi;
106 uint32_t igbp_slot;
107 uint32_t magic;
108 };
109
110 enum {
111 NUM_INTS = sizeof(ExtraData) / sizeof(int),
112 };
113 const static uint32_t MAGIC = '\xc2gr\x00';
114
115 static
John Stultz653ddd12020-09-19 05:26:24 +0000116 const ExtraData* GetExtraData(const C2Handle *const handle) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800117 if (handle == nullptr
118 || native_handle_is_invalid(handle)
119 || handle->numInts < NUM_INTS) {
120 return nullptr;
121 }
122 return reinterpret_cast<const ExtraData*>(
123 &handle->data[handle->numFds + handle->numInts - NUM_INTS]);
124 }
125
126 static
John Stultz653ddd12020-09-19 05:26:24 +0000127 ExtraData *GetExtraData(C2Handle *const handle) {
128 return const_cast<ExtraData *>(GetExtraData(const_cast<const C2Handle *const>(handle)));
Pawin Vongmasa36653902018-11-15 00:10:25 -0800129 }
130
131public:
132 void getIgbpData(uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) const {
John Stultz653ddd12020-09-19 05:26:24 +0000133 const ExtraData *ed = GetExtraData(this);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800134 *generation = ed->generation;
135 *igbp_id = unsigned(ed->igbp_id_lo) | uint64_t(unsigned(ed->igbp_id_hi)) << 32;
136 *igbp_slot = ed->igbp_slot;
137 }
138
John Stultz653ddd12020-09-19 05:26:24 +0000139 static bool IsValid(const C2Handle *const o) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800140 if (o == nullptr) { // null handle is always valid
141 return true;
142 }
John Stultz653ddd12020-09-19 05:26:24 +0000143 const ExtraData *xd = GetExtraData(o);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800144 // we cannot validate width/height/format/usage without accessing gralloc driver
145 return xd != nullptr && xd->magic == MAGIC;
146 }
147
Sungtak Leea4d13be2019-01-23 15:24:46 -0800148 static C2HandleGralloc* WrapAndMoveNativeHandle(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800149 const native_handle_t *const handle,
150 uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
151 uint32_t stride, uint32_t generation, uint64_t igbp_id = 0, uint32_t igbp_slot = 0) {
152 //CHECK(handle != nullptr);
153 if (native_handle_is_invalid(handle) ||
154 handle->numInts > int((INT_MAX - handle->version) / sizeof(int)) - NUM_INTS - handle->numFds) {
155 return nullptr;
156 }
157 ExtraData xd = {
158 width, height, format, uint32_t(usage & 0xFFFFFFFF), uint32_t(usage >> 32),
159 stride, generation, uint32_t(igbp_id & 0xFFFFFFFF), uint32_t(igbp_id >> 32),
160 igbp_slot, MAGIC
161 };
162 native_handle_t *res = native_handle_create(handle->numFds, handle->numInts + NUM_INTS);
163 if (res != nullptr) {
164 memcpy(&res->data, &handle->data, sizeof(int) * (handle->numFds + handle->numInts));
John Stultz653ddd12020-09-19 05:26:24 +0000165 *GetExtraData(res) = xd;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800166 }
167 return reinterpret_cast<C2HandleGralloc *>(res);
168 }
169
Sungtak Leea4d13be2019-01-23 15:24:46 -0800170 static C2HandleGralloc* WrapNativeHandle(
171 const native_handle_t *const handle,
172 uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
173 uint32_t stride, uint32_t generation, uint64_t igbp_id = 0, uint32_t igbp_slot = 0) {
174 if (handle == nullptr) {
175 return nullptr;
176 }
177 native_handle_t *clone = native_handle_clone(handle);
178 if (clone == nullptr) {
179 return nullptr;
180 }
181 C2HandleGralloc *res = WrapAndMoveNativeHandle(
182 clone, width, height, format, usage, stride, generation, igbp_id, igbp_slot);
183 if (res == nullptr) {
184 native_handle_close(clone);
185 }
186 native_handle_delete(clone);
187 return res;
188 }
189
Sungtak Lee08515812019-06-05 11:16:32 -0700190 static bool MigrateNativeHandle(
191 native_handle_t *handle,
192 uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
John Stultz653ddd12020-09-19 05:26:24 +0000193 if (handle == nullptr || !IsValid(handle)) {
Sungtak Lee08515812019-06-05 11:16:32 -0700194 return false;
195 }
John Stultz653ddd12020-09-19 05:26:24 +0000196 ExtraData *ed = GetExtraData(handle);
Sungtak Lee08515812019-06-05 11:16:32 -0700197 if (!ed) return false;
198 ed->generation = generation;
199 ed->igbp_id_lo = uint32_t(igbp_id & 0xFFFFFFFF);
200 ed->igbp_id_hi = uint32_t(igbp_id >> 32);
201 ed->igbp_slot = igbp_slot;
202 return true;
203 }
204
205
Pawin Vongmasa36653902018-11-15 00:10:25 -0800206 static native_handle_t* UnwrapNativeHandle(
207 const C2Handle *const handle) {
John Stultz653ddd12020-09-19 05:26:24 +0000208 const ExtraData *xd = GetExtraData(handle);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800209 if (xd == nullptr || xd->magic != MAGIC) {
210 return nullptr;
211 }
212 native_handle_t *res = native_handle_create(handle->numFds, handle->numInts - NUM_INTS);
213 if (res != nullptr) {
214 memcpy(&res->data, &handle->data, sizeof(int) * (res->numFds + res->numInts));
215 }
216 return res;
217 }
218
Pawin Vongmasa36653902018-11-15 00:10:25 -0800219 static const C2HandleGralloc* Import(
220 const C2Handle *const handle,
221 uint32_t *width, uint32_t *height, uint32_t *format,
222 uint64_t *usage, uint32_t *stride,
223 uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) {
John Stultz653ddd12020-09-19 05:26:24 +0000224 const ExtraData *xd = GetExtraData(handle);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800225 if (xd == nullptr) {
226 return nullptr;
227 }
228 *width = xd->width;
229 *height = xd->height;
230 *format = xd->format;
231 *usage = xd->usage_lo | (uint64_t(xd->usage_hi) << 32);
232 *stride = xd->stride;
233 *generation = xd->generation;
234 *igbp_id = xd->igbp_id_lo | (uint64_t(xd->igbp_id_hi) << 32);
235 *igbp_slot = xd->igbp_slot;
236 return reinterpret_cast<const C2HandleGralloc *>(handle);
237 }
238};
239
Praveen Chavan34493f12021-02-18 00:51:50 -0800240static
241c2_status_t Gralloc4Mapper_lock(native_handle_t *handle, uint64_t usage, const Rect& bounds,
242 C2PlanarLayout *layout, uint8_t **addr) {
243 GraphicBufferMapper &mapper = GraphicBufferMapper::get();
244
245 std::vector<ui::PlaneLayout> planes;
246 // this method is only supported on Gralloc 4 or later
247 status_t err = mapper.getPlaneLayouts(handle, &planes);
248 if (err != NO_ERROR || planes.empty()) {
249 return C2_CANNOT_DO;
250 }
251
252 uint8_t *pointer = nullptr;
253 err = mapper.lock(handle, usage, bounds, (void **)&pointer, nullptr, nullptr);
254 if (err != NO_ERROR || pointer == nullptr) {
255 return C2_CORRUPTED;
256 }
257
258 using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
259 using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
260
261 layout->type = C2PlanarLayout::TYPE_YUV;
262 layout->numPlanes = 0;
263 layout->rootPlanes = 0;
264
265 for (const ui::PlaneLayout &plane : planes) {
266 layout->rootPlanes++;
267 uint32_t lastOffsetInBits = 0;
Wonsik Kimf12bebc2022-03-24 16:25:03 -0700268 uint32_t rootIx = layout->numPlanes;
Praveen Chavan34493f12021-02-18 00:51:50 -0800269
270 for (const PlaneLayoutComponent &component : plane.components) {
271 if (!gralloc4::isStandardPlaneLayoutComponentType(component.type)) {
Praveen Chavan2c580d92022-02-24 12:23:46 -0800272 mapper.unlock(handle);
Praveen Chavan34493f12021-02-18 00:51:50 -0800273 return C2_CANNOT_DO;
274 }
275
276 uint32_t rightShiftBits = component.offsetInBits - lastOffsetInBits;
277 uint32_t allocatedDepthInBits = component.sizeInBits + rightShiftBits;
278 C2PlanarLayout::plane_index_t planeId;
279 C2PlaneInfo::channel_t channel;
280
281 switch (static_cast<PlaneLayoutComponentType>(component.type.value)) {
282 case PlaneLayoutComponentType::Y:
283 planeId = C2PlanarLayout::PLANE_Y;
284 channel = C2PlaneInfo::CHANNEL_Y;
285 break;
286 case PlaneLayoutComponentType::CB:
287 planeId = C2PlanarLayout::PLANE_U;
288 channel = C2PlaneInfo::CHANNEL_CB;
289 break;
290 case PlaneLayoutComponentType::CR:
291 planeId = C2PlanarLayout::PLANE_V;
292 channel = C2PlaneInfo::CHANNEL_CR;
293 break;
294 default:
Praveen Chavan2c580d92022-02-24 12:23:46 -0800295 mapper.unlock(handle);
Praveen Chavan34493f12021-02-18 00:51:50 -0800296 return C2_CORRUPTED;
297 }
298
299 addr[planeId] = pointer + plane.offsetInBytes + (component.offsetInBits / 8);
300 layout->planes[planeId] = {
301 channel, // channel
302 static_cast<int32_t>(plane.sampleIncrementInBits / 8), // colInc
303 static_cast<int32_t>(plane.strideInBytes), // rowInc
304 static_cast<uint32_t>(plane.horizontalSubsampling), // mColSampling
305 static_cast<uint32_t>(plane.verticalSubsampling), // mRowSampling
306 allocatedDepthInBits, // allocatedDepth (bits)
307 static_cast<uint32_t>(component.sizeInBits), // bitDepth (bits)
308 rightShiftBits, // rightShift (bits)
309 C2PlaneInfo::NATIVE, // endianness
310 rootIx, // rootIx
311 static_cast<uint32_t>(component.offsetInBits / 8), // offset (bytes)
312 };
313
314 layout->numPlanes++;
315 lastOffsetInBits = component.offsetInBits + component.sizeInBits;
Praveen Chavan34493f12021-02-18 00:51:50 -0800316 }
317 }
318 return C2_OK;
319}
320
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700321} // unnamed namespace
322
Praveen Chavan34493f12021-02-18 00:51:50 -0800323
Pawin Vongmasa36653902018-11-15 00:10:25 -0800324native_handle_t *UnwrapNativeCodec2GrallocHandle(const C2Handle *const handle) {
325 return C2HandleGralloc::UnwrapNativeHandle(handle);
326}
327
Pawin Vongmasa36653902018-11-15 00:10:25 -0800328C2Handle *WrapNativeCodec2GrallocHandle(
329 const native_handle_t *const handle,
330 uint32_t width, uint32_t height, uint32_t format, uint64_t usage, uint32_t stride,
331 uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
332 return C2HandleGralloc::WrapNativeHandle(handle, width, height, format, usage, stride,
333 generation, igbp_id, igbp_slot);
334}
335
Sungtak Lee08515812019-06-05 11:16:32 -0700336bool MigrateNativeCodec2GrallocHandle(
337 native_handle_t *handle,
338 uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
339 return C2HandleGralloc::MigrateNativeHandle(handle, generation, igbp_id, igbp_slot);
340}
341
342
Pawin Vongmasa36653902018-11-15 00:10:25 -0800343class C2AllocationGralloc : public C2GraphicAllocation {
344public:
345 virtual ~C2AllocationGralloc() override;
346
347 virtual c2_status_t map(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900348 C2Rect c2Rect, C2MemoryUsage usage, C2Fence *fence,
Pawin Vongmasa36653902018-11-15 00:10:25 -0800349 C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) override;
350 virtual c2_status_t unmap(
351 uint8_t **addr /* nonnull */, C2Rect rect, C2Fence *fence /* nullable */) override;
352 virtual C2Allocator::id_t getAllocatorId() const override { return mAllocatorId; }
353 virtual const C2Handle *handle() const override { return mLockedHandle ? : mHandle; }
354 virtual bool equals(const std::shared_ptr<const C2GraphicAllocation> &other) const override;
355
356 // internal methods
357 // |handle| will be moved.
Marissa Wall2a24a302019-11-25 11:19:18 -0800358
Pawin Vongmasa36653902018-11-15 00:10:25 -0800359 C2AllocationGralloc(
Marissa Wall2a24a302019-11-25 11:19:18 -0800360 uint32_t width, uint32_t height,
361 uint32_t format, uint32_t layerCount,
362 uint64_t grallocUsage, uint32_t stride,
Marissa Wall8806edc2019-06-21 09:50:47 -0700363 hidl_handle &hidlHandle,
364 const C2HandleGralloc *const handle,
365 C2Allocator::id_t allocatorId);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800366 int dup() const;
367 c2_status_t status() const;
368
369private:
Marissa Wall2a24a302019-11-25 11:19:18 -0800370 const uint32_t mWidth;
371 const uint32_t mHeight;
372 const uint32_t mFormat;
373 const uint32_t mLayerCount;
374 const uint64_t mGrallocUsage;
375 const uint32_t mStride;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800376 const hidl_handle mHidlHandle;
377 const C2HandleGralloc *mHandle;
378 buffer_handle_t mBuffer;
379 const C2HandleGralloc *mLockedHandle;
380 bool mLocked;
381 C2Allocator::id_t mAllocatorId;
382 std::mutex mMappedLock;
383};
384
385C2AllocationGralloc::C2AllocationGralloc(
Marissa Wall2a24a302019-11-25 11:19:18 -0800386 uint32_t width, uint32_t height,
387 uint32_t format, uint32_t layerCount,
388 uint64_t grallocUsage, uint32_t stride,
Pawin Vongmasa36653902018-11-15 00:10:25 -0800389 hidl_handle &hidlHandle,
390 const C2HandleGralloc *const handle,
391 C2Allocator::id_t allocatorId)
Marissa Wall2a24a302019-11-25 11:19:18 -0800392 : C2GraphicAllocation(width, height),
393 mWidth(width),
394 mHeight(height),
395 mFormat(format),
396 mLayerCount(layerCount),
397 mGrallocUsage(grallocUsage),
398 mStride(stride),
Marissa Wall8806edc2019-06-21 09:50:47 -0700399 mHidlHandle(std::move(hidlHandle)),
400 mHandle(handle),
401 mBuffer(nullptr),
402 mLockedHandle(nullptr),
403 mLocked(false),
404 mAllocatorId(allocatorId) {
405}
406
Pawin Vongmasa36653902018-11-15 00:10:25 -0800407C2AllocationGralloc::~C2AllocationGralloc() {
Yichi Chenfa94a3b2018-12-08 00:06:25 +0800408 if (mBuffer && mLocked) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800409 // implementation ignores addresss and rect
410 uint8_t* addr[C2PlanarLayout::MAX_NUM_PLANES] = {};
411 unmap(addr, C2Rect(), nullptr);
412 }
Yichi Chenfa94a3b2018-12-08 00:06:25 +0800413 if (mBuffer) {
Marissa Wall2a24a302019-11-25 11:19:18 -0800414 status_t err = GraphicBufferMapper::get().freeBuffer(mBuffer);
415 if (err) {
416 ALOGE("failed transaction: freeBuffer");
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700417 }
Yichi Chenfa94a3b2018-12-08 00:06:25 +0800418 }
419 if (mHandle) {
420 native_handle_delete(
421 const_cast<native_handle_t *>(reinterpret_cast<const native_handle_t *>(mHandle)));
422 }
Sungtak Lee2729dcf2019-01-18 13:15:07 -0800423 if (mLockedHandle) {
424 native_handle_delete(
425 const_cast<native_handle_t *>(
426 reinterpret_cast<const native_handle_t *>(mLockedHandle)));
427 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800428}
429
430c2_status_t C2AllocationGralloc::map(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900431 C2Rect c2Rect, C2MemoryUsage usage, C2Fence *fence,
Pawin Vongmasa36653902018-11-15 00:10:25 -0800432 C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) {
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900433 const Rect rect{(int32_t)c2Rect.left, (int32_t)c2Rect.top,
434 (int32_t)(c2Rect.left + c2Rect.width) /* right */,
435 (int32_t)(c2Rect.top + c2Rect.height) /* bottom */};
436
Pawin Vongmasa36653902018-11-15 00:10:25 -0800437 uint64_t grallocUsage = static_cast<C2AndroidMemoryUsage>(usage).asGrallocUsage();
438 ALOGV("mapping buffer with usage %#llx => %#llx",
439 (long long)usage.expected, (long long)grallocUsage);
440
441 // TODO
Marissa Wall2a24a302019-11-25 11:19:18 -0800442 (void)fence;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800443
444 std::lock_guard<std::mutex> lock(mMappedLock);
445 if (mBuffer && mLocked) {
446 ALOGD("already mapped");
447 return C2_DUPLICATE;
448 }
449 if (!layout || !addr) {
450 ALOGD("wrong param");
451 return C2_BAD_VALUE;
452 }
453
Pawin Vongmasa36653902018-11-15 00:10:25 -0800454 if (!mBuffer) {
Marissa Wall2a24a302019-11-25 11:19:18 -0800455 status_t err = GraphicBufferMapper::get().importBuffer(
456 mHidlHandle.getNativeHandle(), mWidth, mHeight, mLayerCount,
457 mFormat, mGrallocUsage, mStride, &mBuffer);
458 if (err) {
459 ALOGE("failed transaction: importBuffer");
460 return C2_CORRUPTED;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800461 }
462 if (mBuffer == nullptr) {
463 ALOGD("importBuffer returned null buffer");
464 return C2_CORRUPTED;
465 }
466 uint32_t generation = 0;
467 uint64_t igbp_id = 0;
468 uint32_t igbp_slot = 0;
469 if (mHandle) {
470 mHandle->getIgbpData(&generation, &igbp_id, &igbp_slot);
471 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800472
Marissa Wall2a24a302019-11-25 11:19:18 -0800473 mLockedHandle = C2HandleGralloc::WrapAndMoveNativeHandle(
474 mBuffer, mWidth, mHeight, mFormat, mGrallocUsage,
475 mStride, generation, igbp_id, igbp_slot);
Marissa Wall8806edc2019-06-21 09:50:47 -0700476 }
Praveen Chavan34493f12021-02-18 00:51:50 -0800477
478 // 'NATIVE' on Android means LITTLE_ENDIAN
479 constexpr C2PlaneInfo::endianness_t kEndianness = C2PlaneInfo::NATIVE;
480
Marissa Wall2a24a302019-11-25 11:19:18 -0800481 switch (mFormat) {
482 case static_cast<uint32_t>(PixelFormat4::RGBA_1010102): {
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700483 // TRICKY: this is used for media as YUV444 in the case when it is queued directly to a
484 // Surface. In all other cases it is RGBA. We don't know which case it is here, so
485 // default to YUV for now.
486 void *pointer = nullptr;
Marissa Wall2a24a302019-11-25 11:19:18 -0800487 // TODO: fence
488 status_t err = GraphicBufferMapper::get().lock(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900489 const_cast<native_handle_t *>(mBuffer), grallocUsage, rect, &pointer);
Marissa Wall2a24a302019-11-25 11:19:18 -0800490 if (err) {
491 ALOGE("failed transaction: lock(RGBA_1010102)");
492 return C2_CORRUPTED;
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700493 }
494 // treat as 32-bit values
495 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)pointer;
496 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)pointer;
497 addr[C2PlanarLayout::PLANE_V] = (uint8_t *)pointer;
498 addr[C2PlanarLayout::PLANE_A] = (uint8_t *)pointer;
499 layout->type = C2PlanarLayout::TYPE_YUVA;
500 layout->numPlanes = 4;
501 layout->rootPlanes = 1;
502 layout->planes[C2PlanarLayout::PLANE_Y] = {
503 C2PlaneInfo::CHANNEL_Y, // channel
504 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800505 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700506 1, // mColSampling
507 1, // mRowSampling
508 32, // allocatedDepth
509 10, // bitDepth
510 10, // rightShift
511 C2PlaneInfo::LITTLE_END, // endianness
512 C2PlanarLayout::PLANE_Y, // rootIx
513 0, // offset
514 };
515 layout->planes[C2PlanarLayout::PLANE_U] = {
516 C2PlaneInfo::CHANNEL_CB, // channel
517 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800518 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700519 1, // mColSampling
520 1, // mRowSampling
521 32, // allocatedDepth
522 10, // bitDepth
523 0, // rightShift
524 C2PlaneInfo::LITTLE_END, // endianness
525 C2PlanarLayout::PLANE_Y, // rootIx
526 0, // offset
527 };
528 layout->planes[C2PlanarLayout::PLANE_V] = {
529 C2PlaneInfo::CHANNEL_CR, // channel
530 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800531 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700532 1, // mColSampling
533 1, // mRowSampling
534 32, // allocatedDepth
535 10, // bitDepth
536 20, // rightShift
537 C2PlaneInfo::LITTLE_END, // endianness
538 C2PlanarLayout::PLANE_Y, // rootIx
539 0, // offset
540 };
541 layout->planes[C2PlanarLayout::PLANE_A] = {
542 C2PlaneInfo::CHANNEL_A, // channel
543 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800544 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700545 1, // mColSampling
546 1, // mRowSampling
547 32, // allocatedDepth
548 2, // bitDepth
549 30, // rightShift
550 C2PlaneInfo::LITTLE_END, // endianness
551 C2PlanarLayout::PLANE_Y, // rootIx
552 0, // offset
553 };
554 break;
555 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800556
Marissa Wall2a24a302019-11-25 11:19:18 -0800557 case static_cast<uint32_t>(PixelFormat4::RGBA_8888):
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700558 // TODO: alpha channel
559 // fall-through
Marissa Wall2a24a302019-11-25 11:19:18 -0800560 case static_cast<uint32_t>(PixelFormat4::RGBX_8888): {
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700561 void *pointer = nullptr;
Marissa Wall2a24a302019-11-25 11:19:18 -0800562 // TODO: fence
563 status_t err = GraphicBufferMapper::get().lock(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900564 const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &pointer);
Marissa Wall2a24a302019-11-25 11:19:18 -0800565 if (err) {
566 ALOGE("failed transaction: lock(RGBA_8888)");
567 return C2_CORRUPTED;
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700568 }
569 addr[C2PlanarLayout::PLANE_R] = (uint8_t *)pointer;
570 addr[C2PlanarLayout::PLANE_G] = (uint8_t *)pointer + 1;
571 addr[C2PlanarLayout::PLANE_B] = (uint8_t *)pointer + 2;
572 layout->type = C2PlanarLayout::TYPE_RGB;
573 layout->numPlanes = 3;
574 layout->rootPlanes = 1;
575 layout->planes[C2PlanarLayout::PLANE_R] = {
576 C2PlaneInfo::CHANNEL_R, // channel
577 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800578 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700579 1, // mColSampling
580 1, // mRowSampling
581 8, // allocatedDepth
582 8, // bitDepth
583 0, // rightShift
584 C2PlaneInfo::NATIVE, // endianness
585 C2PlanarLayout::PLANE_R, // rootIx
586 0, // offset
587 };
588 layout->planes[C2PlanarLayout::PLANE_G] = {
589 C2PlaneInfo::CHANNEL_G, // channel
590 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800591 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700592 1, // mColSampling
593 1, // mRowSampling
594 8, // allocatedDepth
595 8, // bitDepth
596 0, // rightShift
597 C2PlaneInfo::NATIVE, // endianness
598 C2PlanarLayout::PLANE_R, // rootIx
599 1, // offset
600 };
601 layout->planes[C2PlanarLayout::PLANE_B] = {
602 C2PlaneInfo::CHANNEL_B, // channel
603 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800604 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700605 1, // mColSampling
606 1, // mRowSampling
607 8, // allocatedDepth
608 8, // bitDepth
609 0, // rightShift
610 C2PlaneInfo::NATIVE, // endianness
611 C2PlanarLayout::PLANE_R, // rootIx
612 2, // offset
613 };
614 break;
615 }
616
David Stevens1cadc75d2020-04-03 10:50:51 +0900617 case static_cast<uint32_t>(PixelFormat4::BLOB): {
618 void *pointer = nullptr;
619 // TODO: fence
620 status_t err = GraphicBufferMapper::get().lock(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900621 const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &pointer);
David Stevens1cadc75d2020-04-03 10:50:51 +0900622 if (err) {
623 ALOGE("failed transaction: lock(BLOB)");
624 return C2_CORRUPTED;
625 }
626 *addr = (uint8_t *)pointer;
627 break;
628 }
629
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700630 case static_cast<uint32_t>(PixelFormat4::YCBCR_422_SP):
631 // fall-through
632 case static_cast<uint32_t>(PixelFormat4::YCRCB_420_SP):
633 // fall-through
634 case static_cast<uint32_t>(PixelFormat4::YCBCR_422_I):
635 // fall-through
Marissa Wall2a24a302019-11-25 11:19:18 -0800636 case static_cast<uint32_t>(PixelFormat4::YCBCR_420_888):
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700637 // fall-through
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700638 case static_cast<uint32_t>(PixelFormat4::YV12): {
Marissa Wall2a24a302019-11-25 11:19:18 -0800639 android_ycbcr ycbcrLayout;
640
641 status_t err = GraphicBufferMapper::get().lockYCbCr(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900642 const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &ycbcrLayout);
Marissa Wall2a24a302019-11-25 11:19:18 -0800643 if (err) {
Wonsik Kimd91f3fb2021-02-24 12:35:31 -0800644 ALOGE("failed transaction: lockYCbCr (err=%d)", err);
645 return C2_CORRUPTED;
646 }
647 if (!ycbcrLayout.y || !ycbcrLayout.cb || !ycbcrLayout.cr
648 || ycbcrLayout.ystride == 0
649 || ycbcrLayout.cstride == 0
650 || ycbcrLayout.chroma_step == 0) {
651 ALOGE("invalid layout: lockYCbCr (y=%s cb=%s cr=%s "
652 "ystride=%zu cstride=%zu chroma_step=%zu)",
653 ycbcrLayout.y ? "(non-null)" : "(null)",
654 ycbcrLayout.cb ? "(non-null)" : "(null)",
655 ycbcrLayout.cr ? "(non-null)" : "(null)",
656 ycbcrLayout.ystride, ycbcrLayout.cstride, ycbcrLayout.chroma_step);
Marissa Wall469b90a2019-11-06 10:12:43 -0800657 return C2_CORRUPTED;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700658 }
Marissa Wall2a24a302019-11-25 11:19:18 -0800659
Pawin Vongmasa36653902018-11-15 00:10:25 -0800660 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)ycbcrLayout.y;
661 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)ycbcrLayout.cb;
662 addr[C2PlanarLayout::PLANE_V] = (uint8_t *)ycbcrLayout.cr;
663 layout->type = C2PlanarLayout::TYPE_YUV;
664 layout->numPlanes = 3;
665 layout->rootPlanes = 3;
666 layout->planes[C2PlanarLayout::PLANE_Y] = {
667 C2PlaneInfo::CHANNEL_Y, // channel
668 1, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800669 (int32_t)ycbcrLayout.ystride, // rowInc
Pawin Vongmasa36653902018-11-15 00:10:25 -0800670 1, // mColSampling
671 1, // mRowSampling
672 8, // allocatedDepth
673 8, // bitDepth
674 0, // rightShift
675 C2PlaneInfo::NATIVE, // endianness
676 C2PlanarLayout::PLANE_Y, // rootIx
677 0, // offset
678 };
679 layout->planes[C2PlanarLayout::PLANE_U] = {
680 C2PlaneInfo::CHANNEL_CB, // channel
Marissa Wall2a24a302019-11-25 11:19:18 -0800681 (int32_t)ycbcrLayout.chroma_step, // colInc
682 (int32_t)ycbcrLayout.cstride, // rowInc
Pawin Vongmasa36653902018-11-15 00:10:25 -0800683 2, // mColSampling
684 2, // mRowSampling
685 8, // allocatedDepth
686 8, // bitDepth
687 0, // rightShift
688 C2PlaneInfo::NATIVE, // endianness
689 C2PlanarLayout::PLANE_U, // rootIx
690 0, // offset
691 };
692 layout->planes[C2PlanarLayout::PLANE_V] = {
693 C2PlaneInfo::CHANNEL_CR, // channel
Marissa Wall2a24a302019-11-25 11:19:18 -0800694 (int32_t)ycbcrLayout.chroma_step, // colInc
695 (int32_t)ycbcrLayout.cstride, // rowInc
Pawin Vongmasa36653902018-11-15 00:10:25 -0800696 2, // mColSampling
697 2, // mRowSampling
698 8, // allocatedDepth
699 8, // bitDepth
700 0, // rightShift
701 C2PlaneInfo::NATIVE, // endianness
702 C2PlanarLayout::PLANE_V, // rootIx
703 0, // offset
704 };
Pawin Vongmasa36653902018-11-15 00:10:25 -0800705 break;
706 }
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700707
708 case static_cast<uint32_t>(PixelFormat4::YCBCR_P010): {
709 void *pointer = nullptr;
710 status_t err = GraphicBufferMapper::get().lock(
711 const_cast<native_handle_t *>(mBuffer), grallocUsage, rect, &pointer);
712 if (err) {
713 ALOGE("failed transaction: lock(YCBCR_P010)");
714 return C2_CORRUPTED;
715 }
716 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)pointer;
717 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)pointer + mStride * 2 * rect.height();
718 addr[C2PlanarLayout::PLANE_V] = addr[C2PlanarLayout::PLANE_U] + 2;
719 layout->type = C2PlanarLayout::TYPE_YUV;
720 layout->numPlanes = 3;
721 layout->rootPlanes = 2;
722 layout->planes[C2PlanarLayout::PLANE_Y] = {
723 C2PlaneInfo::CHANNEL_Y, // channel
724 2, // colInc
725 static_cast<int32_t>(2 * mStride), // rowInc
726 1, // mColSampling
727 1, // mRowSampling
728 16, // allocatedDepth
729 10, // bitDepth
730 6, // rightShift
Praveen Chavan34493f12021-02-18 00:51:50 -0800731 kEndianness, // endianness
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700732 C2PlanarLayout::PLANE_Y, // rootIx
733 0, // offset
734 };
735 layout->planes[C2PlanarLayout::PLANE_U] = {
736 C2PlaneInfo::CHANNEL_CB, // channel
737 4, // colInc
738 static_cast<int32_t>(2 * mStride), // rowInc
739 2, // mColSampling
740 2, // mRowSampling
741 16, // allocatedDepth
742 10, // bitDepth
743 6, // rightShift
Praveen Chavan34493f12021-02-18 00:51:50 -0800744 kEndianness, // endianness
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700745 C2PlanarLayout::PLANE_U, // rootIx
746 0, // offset
747 };
748 layout->planes[C2PlanarLayout::PLANE_V] = {
749 C2PlaneInfo::CHANNEL_CR, // channel
750 4, // colInc
751 static_cast<int32_t>(2 * mStride), // rowInc
752 2, // mColSampling
753 2, // mRowSampling
754 16, // allocatedDepth
755 10, // bitDepth
756 6, // rightShift
Praveen Chavan34493f12021-02-18 00:51:50 -0800757 kEndianness, // endianness
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700758 C2PlanarLayout::PLANE_U, // rootIx
759 2, // offset
760 };
761 break;
762 }
763
764 default: {
Praveen Chavan34493f12021-02-18 00:51:50 -0800765 // We don't know what it is, let's try to lock it with gralloc4
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700766 android_ycbcr ycbcrLayout;
Harish Mahendrakar7dc54f92022-06-30 20:36:23 -0700767 if (isAtLeastT()) {
768 c2_status_t status = Gralloc4Mapper_lock(
769 const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, layout, addr);
770 if (status == C2_OK) {
771 break;
772 }
Praveen Chavan34493f12021-02-18 00:51:50 -0800773 }
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700774
Praveen Chavan34493f12021-02-18 00:51:50 -0800775 // fallback to lockYCbCr
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700776 status_t err = GraphicBufferMapper::get().lockYCbCr(
777 const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &ycbcrLayout);
Wonsik Kimd91f3fb2021-02-24 12:35:31 -0800778 if (err == OK && ycbcrLayout.y && ycbcrLayout.cb && ycbcrLayout.cr
779 && ycbcrLayout.ystride > 0
780 && ycbcrLayout.cstride > 0
781 && ycbcrLayout.chroma_step > 0) {
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700782 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)ycbcrLayout.y;
783 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)ycbcrLayout.cb;
784 addr[C2PlanarLayout::PLANE_V] = (uint8_t *)ycbcrLayout.cr;
785 layout->type = C2PlanarLayout::TYPE_YUV;
786 layout->numPlanes = 3;
787 layout->rootPlanes = 3;
788 layout->planes[C2PlanarLayout::PLANE_Y] = {
789 C2PlaneInfo::CHANNEL_Y, // channel
790 1, // colInc
791 (int32_t)ycbcrLayout.ystride, // rowInc
792 1, // mColSampling
793 1, // mRowSampling
794 8, // allocatedDepth
795 8, // bitDepth
796 0, // rightShift
797 C2PlaneInfo::NATIVE, // endianness
798 C2PlanarLayout::PLANE_Y, // rootIx
799 0, // offset
800 };
801 layout->planes[C2PlanarLayout::PLANE_U] = {
802 C2PlaneInfo::CHANNEL_CB, // channel
803 (int32_t)ycbcrLayout.chroma_step, // colInc
804 (int32_t)ycbcrLayout.cstride, // rowInc
805 2, // mColSampling
806 2, // mRowSampling
807 8, // allocatedDepth
808 8, // bitDepth
809 0, // rightShift
810 C2PlaneInfo::NATIVE, // endianness
811 C2PlanarLayout::PLANE_U, // rootIx
812 0, // offset
813 };
814 layout->planes[C2PlanarLayout::PLANE_V] = {
815 C2PlaneInfo::CHANNEL_CR, // channel
816 (int32_t)ycbcrLayout.chroma_step, // colInc
817 (int32_t)ycbcrLayout.cstride, // rowInc
818 2, // mColSampling
819 2, // mRowSampling
820 8, // allocatedDepth
821 8, // bitDepth
822 0, // rightShift
823 C2PlaneInfo::NATIVE, // endianness
824 C2PlanarLayout::PLANE_V, // rootIx
825 0, // offset
826 };
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700827 break;
828 }
829
830 // We really don't know what this is; lock the buffer and pass it through ---
831 // the client may know how to interpret it.
Lajos Molnar8faebbc2021-06-30 17:07:42 -0700832
833 // unlock previous allocation if it was successful
834 if (err == OK) {
835 err = GraphicBufferMapper::get().unlock(mBuffer);
836 if (err) {
837 ALOGE("failed transaction: unlock");
838 return C2_CORRUPTED;
839 }
840 }
841
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700842 void *pointer = nullptr;
843 err = GraphicBufferMapper::get().lock(
844 const_cast<native_handle_t *>(mBuffer), grallocUsage, rect, &pointer);
845 if (err) {
846 ALOGE("failed transaction: lock(??? %x)", mFormat);
847 return C2_CORRUPTED;
848 }
849 addr[0] = (uint8_t *)pointer;
850 layout->type = C2PlanarLayout::TYPE_UNKNOWN;
851 layout->numPlanes = 1;
852 layout->rootPlanes = 1;
853 layout->planes[0] = {
854 // TODO: CHANNEL_UNKNOWN?
855 C2PlaneInfo::channel_t(0xFF), // channel
856 1, // colInc
857 int32_t(mStride), // rowInc
858 1, // mColSampling
859 1, // mRowSampling
860 8, // allocatedDepth
861 8, // bitDepth
862 0, // rightShift
863 C2PlaneInfo::NATIVE, // endianness
864 0, // rootIx
865 0, // offset
866 };
867 break;
868 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800869 }
870 mLocked = true;
871
Wonsik Kimf12bebc2022-03-24 16:25:03 -0700872 // handle interleaved formats
873 if (layout->type == C2PlanarLayout::TYPE_YUV && layout->rootPlanes == 3) {
874 intptr_t uvOffset = addr[C2PlanarLayout::PLANE_V] - addr[C2PlanarLayout::PLANE_U];
875 intptr_t uvColInc = layout->planes[C2PlanarLayout::PLANE_U].colInc;
876 if (uvOffset > 0 && uvOffset < uvColInc) {
877 layout->rootPlanes = 2;
878 layout->planes[C2PlanarLayout::PLANE_V].rootIx = C2PlanarLayout::PLANE_U;
879 layout->planes[C2PlanarLayout::PLANE_V].offset = uvOffset;
880 } else if (uvOffset < 0 && uvOffset > -uvColInc) {
881 layout->rootPlanes = 2;
882 layout->planes[C2PlanarLayout::PLANE_U].rootIx = C2PlanarLayout::PLANE_V;
883 layout->planes[C2PlanarLayout::PLANE_U].offset = -uvOffset;
884 }
885 }
886
887 ALOGV("C2AllocationGralloc::map: layout: type=%d numPlanes=%d rootPlanes=%d",
888 layout->type, layout->numPlanes, layout->rootPlanes);
889 for (int i = 0; i < layout->numPlanes; ++i) {
890 const C2PlaneInfo &plane = layout->planes[i];
891 ALOGV("C2AllocationGralloc::map: plane[%d]: colInc=%d rowInc=%d rootIx=%u offset=%u",
892 i, plane.colInc, plane.rowInc, plane.rootIx, plane.offset);
893 }
894
Pawin Vongmasa36653902018-11-15 00:10:25 -0800895 return C2_OK;
896}
897
898c2_status_t C2AllocationGralloc::unmap(
899 uint8_t **addr, C2Rect rect, C2Fence *fence /* nullable */) {
900 // TODO: check addr and size, use fence
901 (void)addr;
902 (void)rect;
Marissa Wall2a24a302019-11-25 11:19:18 -0800903 (void)fence;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800904
905 std::lock_guard<std::mutex> lock(mMappedLock);
Marissa Wall2a24a302019-11-25 11:19:18 -0800906 // TODO: fence
907 status_t err = GraphicBufferMapper::get().unlock(mBuffer);
908 if (err) {
909 ALOGE("failed transaction: unlock");
910 return C2_CORRUPTED;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700911 }
Marissa Wall2a24a302019-11-25 11:19:18 -0800912
913 mLocked = false;
914 return C2_OK;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800915}
916
917bool C2AllocationGralloc::equals(const std::shared_ptr<const C2GraphicAllocation> &other) const {
918 return other && other->handle() == handle();
919}
920
921/* ===================================== GRALLOC ALLOCATOR ==================================== */
922class C2AllocatorGralloc::Impl {
923public:
924 Impl(id_t id, bool bufferQueue);
925
926 id_t getId() const {
927 return mTraits->id;
928 }
929
930 C2String getName() const {
931 return mTraits->name;
932 }
933
934 std::shared_ptr<const C2Allocator::Traits> getTraits() const {
935 return mTraits;
936 }
937
938 c2_status_t newGraphicAllocation(
939 uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
940 std::shared_ptr<C2GraphicAllocation> *allocation);
941
942 c2_status_t priorGraphicAllocation(
943 const C2Handle *handle,
944 std::shared_ptr<C2GraphicAllocation> *allocation);
945
946 c2_status_t status() const { return mInit; }
947
948private:
949 std::shared_ptr<C2Allocator::Traits> mTraits;
950 c2_status_t mInit;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800951 const bool mBufferQueue;
952};
953
954void _UnwrapNativeCodec2GrallocMetadata(
955 const C2Handle *const handle,
956 uint32_t *width, uint32_t *height, uint32_t *format,uint64_t *usage, uint32_t *stride,
957 uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) {
958 (void)C2HandleGralloc::Import(handle, width, height, format, usage, stride,
959 generation, igbp_id, igbp_slot);
960}
961
962C2AllocatorGralloc::Impl::Impl(id_t id, bool bufferQueue)
963 : mInit(C2_OK), mBufferQueue(bufferQueue) {
964 // TODO: get this from allocator
965 C2MemoryUsage minUsage = { 0, 0 }, maxUsage = { ~(uint64_t)0, ~(uint64_t)0 };
966 Traits traits = { "android.allocator.gralloc", id, C2Allocator::GRAPHIC, minUsage, maxUsage };
967 mTraits = std::make_shared<C2Allocator::Traits>(traits);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800968}
969
970c2_status_t C2AllocatorGralloc::Impl::newGraphicAllocation(
971 uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
972 std::shared_ptr<C2GraphicAllocation> *allocation) {
973 uint64_t grallocUsage = static_cast<C2AndroidMemoryUsage>(usage).asGrallocUsage();
974 ALOGV("allocating buffer with usage %#llx => %#llx",
975 (long long)usage.expected, (long long)grallocUsage);
976
Marissa Wall2a24a302019-11-25 11:19:18 -0800977 buffer_handle_t buffer;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700978
Marissa Wall2a24a302019-11-25 11:19:18 -0800979 uint32_t stride = 0;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700980
Marissa Wall2a24a302019-11-25 11:19:18 -0800981 status_t err = GraphicBufferAllocator::get().allocateRawHandle(width, height, format,
982 1u /* layer count */, grallocUsage, &buffer, &stride, "C2GrallocAllocation");
983 if (err) {
984 ALOGE("failed transaction: allocate");
985 return C2_CORRUPTED;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800986 }
Marissa Wall2a24a302019-11-25 11:19:18 -0800987
988 hidl_handle hidlHandle;
989 hidlHandle.setTo(const_cast<native_handle_t*>(buffer), true);
990
991 allocation->reset(new C2AllocationGralloc(
992 width, height, format, 1u /* layer count */, grallocUsage, stride, hidlHandle,
993 C2HandleGralloc::WrapAndMoveNativeHandle(
994 hidlHandle, width, height,
995 format, grallocUsage, stride,
996 0, 0, mBufferQueue ? ~0 : 0),
997 mTraits->id));
998 return C2_OK;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800999}
1000
1001c2_status_t C2AllocatorGralloc::Impl::priorGraphicAllocation(
1002 const C2Handle *handle,
1003 std::shared_ptr<C2GraphicAllocation> *allocation) {
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001004
Marissa Wall2a24a302019-11-25 11:19:18 -08001005 uint32_t generation;
1006 uint64_t igbp_id;
1007 uint32_t igbp_slot;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001008
Marissa Wall2a24a302019-11-25 11:19:18 -08001009 uint32_t width;
1010 uint32_t height;
1011 uint32_t format;
1012 uint32_t layerCount = 1;
1013 uint64_t grallocUsage;
1014 uint32_t stride;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001015
Marissa Wall2a24a302019-11-25 11:19:18 -08001016 const C2HandleGralloc *grallocHandle = C2HandleGralloc::Import(
1017 handle, &width, &height, &format, &grallocUsage, &stride,
1018 &generation, &igbp_id, &igbp_slot);
1019 if (grallocHandle == nullptr) {
1020 return C2_BAD_VALUE;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001021 }
Marissa Wall2a24a302019-11-25 11:19:18 -08001022
1023 hidl_handle hidlHandle;
1024 hidlHandle.setTo(C2HandleGralloc::UnwrapNativeHandle(grallocHandle), true);
1025
1026 allocation->reset(new C2AllocationGralloc(
1027 width, height, format, layerCount,
1028 grallocUsage, stride, hidlHandle, grallocHandle, mTraits->id));
1029 return C2_OK;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001030}
1031
1032C2AllocatorGralloc::C2AllocatorGralloc(id_t id, bool bufferQueue)
1033 : mImpl(new Impl(id, bufferQueue)) {}
1034
1035C2AllocatorGralloc::~C2AllocatorGralloc() { delete mImpl; }
1036
1037C2Allocator::id_t C2AllocatorGralloc::getId() const {
1038 return mImpl->getId();
1039}
1040
1041C2String C2AllocatorGralloc::getName() const {
1042 return mImpl->getName();
1043}
1044
1045std::shared_ptr<const C2Allocator::Traits> C2AllocatorGralloc::getTraits() const {
1046 return mImpl->getTraits();
1047}
1048
1049c2_status_t C2AllocatorGralloc::newGraphicAllocation(
1050 uint32_t width, uint32_t height, uint32_t format, C2MemoryUsage usage,
1051 std::shared_ptr<C2GraphicAllocation> *allocation) {
1052 return mImpl->newGraphicAllocation(width, height, format, usage, allocation);
1053}
1054
1055c2_status_t C2AllocatorGralloc::priorGraphicAllocation(
1056 const C2Handle *handle,
1057 std::shared_ptr<C2GraphicAllocation> *allocation) {
1058 return mImpl->priorGraphicAllocation(handle, allocation);
1059}
1060
1061c2_status_t C2AllocatorGralloc::status() const {
1062 return mImpl->status();
1063}
1064
John Stultz653ddd12020-09-19 05:26:24 +00001065// static
1066bool C2AllocatorGralloc::CheckHandle(const C2Handle* const o) {
1067 return C2HandleGralloc::IsValid(o);
Pawin Vongmasa36653902018-11-15 00:10:25 -08001068}
1069
1070} // namespace android