blob: 0803dc3cec2d611b9f75928663b7889ba385347a [file] [log] [blame]
Pawin Vongmasa36653902018-11-15 00:10:25 -08001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "C2AllocatorGralloc"
19#include <utils/Log.h>
20
Marissa Wall2a24a302019-11-25 11:19:18 -080021#include <mutex>
22
Praveen Chavan34493f12021-02-18 00:51:50 -080023#include <aidl/android/hardware/graphics/common/PlaneLayoutComponentType.h>
Marissa Wall2a24a302019-11-25 11:19:18 -080024#include <android/hardware/graphics/common/1.2/types.h>
Pawin Vongmasa36653902018-11-15 00:10:25 -080025#include <cutils/native_handle.h>
Tao Wu9d482892023-09-15 02:28:41 +000026#include <drm/drm_fourcc.h>
Praveen Chavan34493f12021-02-18 00:51:50 -080027#include <gralloctypes/Gralloc4.h>
Pawin Vongmasa36653902018-11-15 00:10:25 -080028#include <hardware/gralloc.h>
Marissa Wall2a24a302019-11-25 11:19:18 -080029#include <ui/GraphicBufferAllocator.h>
30#include <ui/GraphicBufferMapper.h>
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +090031#include <ui/Rect.h>
Pawin Vongmasa36653902018-11-15 00:10:25 -080032
33#include <C2AllocatorGralloc.h>
34#include <C2Buffer.h>
Praveen Chavan34493f12021-02-18 00:51:50 -080035#include <C2Debug.h>
Pawin Vongmasa36653902018-11-15 00:10:25 -080036#include <C2PlatformSupport.h>
37
Marissa Wall2a24a302019-11-25 11:19:18 -080038using ::android::hardware::hidl_handle;
39using PixelFormat4 = ::android::hardware::graphics::common::V1_2::PixelFormat;
40
Pawin Vongmasa36653902018-11-15 00:10:25 -080041namespace android {
42
Pawin Vongmasad032f2d2019-05-15 08:42:44 -070043namespace /* unnamed */ {
Pawin Vongmasa36653902018-11-15 00:10:25 -080044 enum : uint64_t {
45 /**
46 * Usage mask that is passed through from gralloc to Codec 2.0 usage.
47 */
48 PASSTHROUGH_USAGE_MASK =
Charlie Chen49d3fe72021-03-25 20:02:37 +080049 ~static_cast<uint64_t>(GRALLOC_USAGE_SW_READ_MASK |
50 GRALLOC_USAGE_SW_WRITE_MASK |
51 GRALLOC_USAGE_PROTECTED)
Pawin Vongmasa36653902018-11-15 00:10:25 -080052 };
53
54 // verify that passthrough mask is within the platform mask
55 static_assert((~C2MemoryUsage::PLATFORM_MASK & PASSTHROUGH_USAGE_MASK) == 0, "");
Pawin Vongmasad032f2d2019-05-15 08:42:44 -070056} // unnamed
Pawin Vongmasa36653902018-11-15 00:10:25 -080057
Harish Mahendrakar7dc54f92022-06-30 20:36:23 -070058static bool isAtLeastT() {
59 return android_get_device_api_level() >= __ANDROID_API_T__;
60}
61
Pawin Vongmasa36653902018-11-15 00:10:25 -080062C2MemoryUsage C2AndroidMemoryUsage::FromGrallocUsage(uint64_t usage) {
63 // gralloc does not support WRITE_PROTECTED
64 return C2MemoryUsage(
65 ((usage & GRALLOC_USAGE_SW_READ_MASK) ? C2MemoryUsage::CPU_READ : 0) |
66 ((usage & GRALLOC_USAGE_SW_WRITE_MASK) ? C2MemoryUsage::CPU_WRITE : 0) |
67 ((usage & GRALLOC_USAGE_PROTECTED) ? C2MemoryUsage::READ_PROTECTED : 0) |
68 (usage & PASSTHROUGH_USAGE_MASK));
69}
70
71uint64_t C2AndroidMemoryUsage::asGrallocUsage() const {
72 // gralloc does not support WRITE_PROTECTED
73 return (((expected & C2MemoryUsage::CPU_READ) ? GRALLOC_USAGE_SW_READ_OFTEN : 0) |
74 ((expected & C2MemoryUsage::CPU_WRITE) ? GRALLOC_USAGE_SW_WRITE_OFTEN : 0) |
75 ((expected & C2MemoryUsage::READ_PROTECTED) ? GRALLOC_USAGE_PROTECTED : 0) |
76 (expected & PASSTHROUGH_USAGE_MASK));
77}
78
Pawin Vongmasad032f2d2019-05-15 08:42:44 -070079namespace /* unnamed */ {
80
Pawin Vongmasa36653902018-11-15 00:10:25 -080081/* ===================================== GRALLOC ALLOCATION ==================================== */
Pawin Vongmasa36653902018-11-15 00:10:25 -080082bool native_handle_is_invalid(const native_handle_t *const handle) {
83 // perform basic validation of a native handle
84 if (handle == nullptr) {
85 // null handle is considered valid
86 return false;
87 }
88 return ((size_t)handle->version != sizeof(native_handle_t) ||
89 handle->numFds < 0 ||
90 handle->numInts < 0 ||
91 // for sanity assume handles must occupy less memory than INT_MAX bytes
92 handle->numFds > int((INT_MAX - handle->version) / sizeof(int)) - handle->numInts);
93}
94
95class C2HandleGralloc : public C2Handle {
96private:
97 struct ExtraData {
98 uint32_t width;
99 uint32_t height;
100 uint32_t format;
101 uint32_t usage_lo;
102 uint32_t usage_hi;
103 uint32_t stride;
104 uint32_t generation;
105 uint32_t igbp_id_lo;
106 uint32_t igbp_id_hi;
107 uint32_t igbp_slot;
108 uint32_t magic;
109 };
110
111 enum {
112 NUM_INTS = sizeof(ExtraData) / sizeof(int),
113 };
114 const static uint32_t MAGIC = '\xc2gr\x00';
115
116 static
John Stultz653ddd12020-09-19 05:26:24 +0000117 const ExtraData* GetExtraData(const C2Handle *const handle) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800118 if (handle == nullptr
119 || native_handle_is_invalid(handle)
120 || handle->numInts < NUM_INTS) {
121 return nullptr;
122 }
123 return reinterpret_cast<const ExtraData*>(
124 &handle->data[handle->numFds + handle->numInts - NUM_INTS]);
125 }
126
127 static
John Stultz653ddd12020-09-19 05:26:24 +0000128 ExtraData *GetExtraData(C2Handle *const handle) {
129 return const_cast<ExtraData *>(GetExtraData(const_cast<const C2Handle *const>(handle)));
Pawin Vongmasa36653902018-11-15 00:10:25 -0800130 }
131
132public:
133 void getIgbpData(uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) const {
John Stultz653ddd12020-09-19 05:26:24 +0000134 const ExtraData *ed = GetExtraData(this);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800135 *generation = ed->generation;
136 *igbp_id = unsigned(ed->igbp_id_lo) | uint64_t(unsigned(ed->igbp_id_hi)) << 32;
137 *igbp_slot = ed->igbp_slot;
138 }
139
John Stultz653ddd12020-09-19 05:26:24 +0000140 static bool IsValid(const C2Handle *const o) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800141 if (o == nullptr) { // null handle is always valid
142 return true;
143 }
John Stultz653ddd12020-09-19 05:26:24 +0000144 const ExtraData *xd = GetExtraData(o);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800145 // we cannot validate width/height/format/usage without accessing gralloc driver
146 return xd != nullptr && xd->magic == MAGIC;
147 }
148
Sungtak Leea4d13be2019-01-23 15:24:46 -0800149 static C2HandleGralloc* WrapAndMoveNativeHandle(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800150 const native_handle_t *const handle,
151 uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
152 uint32_t stride, uint32_t generation, uint64_t igbp_id = 0, uint32_t igbp_slot = 0) {
153 //CHECK(handle != nullptr);
154 if (native_handle_is_invalid(handle) ||
155 handle->numInts > int((INT_MAX - handle->version) / sizeof(int)) - NUM_INTS - handle->numFds) {
156 return nullptr;
157 }
158 ExtraData xd = {
159 width, height, format, uint32_t(usage & 0xFFFFFFFF), uint32_t(usage >> 32),
160 stride, generation, uint32_t(igbp_id & 0xFFFFFFFF), uint32_t(igbp_id >> 32),
161 igbp_slot, MAGIC
162 };
163 native_handle_t *res = native_handle_create(handle->numFds, handle->numInts + NUM_INTS);
164 if (res != nullptr) {
165 memcpy(&res->data, &handle->data, sizeof(int) * (handle->numFds + handle->numInts));
John Stultz653ddd12020-09-19 05:26:24 +0000166 *GetExtraData(res) = xd;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800167 }
168 return reinterpret_cast<C2HandleGralloc *>(res);
169 }
170
Sungtak Leea4d13be2019-01-23 15:24:46 -0800171 static C2HandleGralloc* WrapNativeHandle(
172 const native_handle_t *const handle,
173 uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
174 uint32_t stride, uint32_t generation, uint64_t igbp_id = 0, uint32_t igbp_slot = 0) {
175 if (handle == nullptr) {
176 return nullptr;
177 }
178 native_handle_t *clone = native_handle_clone(handle);
179 if (clone == nullptr) {
180 return nullptr;
181 }
182 C2HandleGralloc *res = WrapAndMoveNativeHandle(
183 clone, width, height, format, usage, stride, generation, igbp_id, igbp_slot);
184 if (res == nullptr) {
185 native_handle_close(clone);
186 }
187 native_handle_delete(clone);
188 return res;
189 }
190
Sungtak Lee08515812019-06-05 11:16:32 -0700191 static bool MigrateNativeHandle(
192 native_handle_t *handle,
193 uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
John Stultz653ddd12020-09-19 05:26:24 +0000194 if (handle == nullptr || !IsValid(handle)) {
Sungtak Lee08515812019-06-05 11:16:32 -0700195 return false;
196 }
John Stultz653ddd12020-09-19 05:26:24 +0000197 ExtraData *ed = GetExtraData(handle);
Sungtak Lee08515812019-06-05 11:16:32 -0700198 if (!ed) return false;
199 ed->generation = generation;
200 ed->igbp_id_lo = uint32_t(igbp_id & 0xFFFFFFFF);
201 ed->igbp_id_hi = uint32_t(igbp_id >> 32);
202 ed->igbp_slot = igbp_slot;
203 return true;
204 }
205
206
Pawin Vongmasa36653902018-11-15 00:10:25 -0800207 static native_handle_t* UnwrapNativeHandle(
208 const C2Handle *const handle) {
John Stultz653ddd12020-09-19 05:26:24 +0000209 const ExtraData *xd = GetExtraData(handle);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800210 if (xd == nullptr || xd->magic != MAGIC) {
211 return nullptr;
212 }
213 native_handle_t *res = native_handle_create(handle->numFds, handle->numInts - NUM_INTS);
214 if (res != nullptr) {
215 memcpy(&res->data, &handle->data, sizeof(int) * (res->numFds + res->numInts));
216 }
217 return res;
218 }
219
Pawin Vongmasa36653902018-11-15 00:10:25 -0800220 static const C2HandleGralloc* Import(
221 const C2Handle *const handle,
222 uint32_t *width, uint32_t *height, uint32_t *format,
223 uint64_t *usage, uint32_t *stride,
224 uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) {
John Stultz653ddd12020-09-19 05:26:24 +0000225 const ExtraData *xd = GetExtraData(handle);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800226 if (xd == nullptr) {
227 return nullptr;
228 }
229 *width = xd->width;
230 *height = xd->height;
231 *format = xd->format;
232 *usage = xd->usage_lo | (uint64_t(xd->usage_hi) << 32);
233 *stride = xd->stride;
234 *generation = xd->generation;
235 *igbp_id = xd->igbp_id_lo | (uint64_t(xd->igbp_id_hi) << 32);
236 *igbp_slot = xd->igbp_slot;
237 return reinterpret_cast<const C2HandleGralloc *>(handle);
238 }
239};
240
Praveen Chavan34493f12021-02-18 00:51:50 -0800241static
242c2_status_t Gralloc4Mapper_lock(native_handle_t *handle, uint64_t usage, const Rect& bounds,
243 C2PlanarLayout *layout, uint8_t **addr) {
244 GraphicBufferMapper &mapper = GraphicBufferMapper::get();
245
246 std::vector<ui::PlaneLayout> planes;
247 // this method is only supported on Gralloc 4 or later
248 status_t err = mapper.getPlaneLayouts(handle, &planes);
249 if (err != NO_ERROR || planes.empty()) {
250 return C2_CANNOT_DO;
251 }
252
253 uint8_t *pointer = nullptr;
254 err = mapper.lock(handle, usage, bounds, (void **)&pointer, nullptr, nullptr);
255 if (err != NO_ERROR || pointer == nullptr) {
256 return C2_CORRUPTED;
257 }
258
259 using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
260 using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
261
262 layout->type = C2PlanarLayout::TYPE_YUV;
263 layout->numPlanes = 0;
264 layout->rootPlanes = 0;
265
266 for (const ui::PlaneLayout &plane : planes) {
267 layout->rootPlanes++;
268 uint32_t lastOffsetInBits = 0;
Wonsik Kimf12bebc2022-03-24 16:25:03 -0700269 uint32_t rootIx = layout->numPlanes;
Praveen Chavan34493f12021-02-18 00:51:50 -0800270
271 for (const PlaneLayoutComponent &component : plane.components) {
272 if (!gralloc4::isStandardPlaneLayoutComponentType(component.type)) {
Praveen Chavan2c580d92022-02-24 12:23:46 -0800273 mapper.unlock(handle);
Praveen Chavan34493f12021-02-18 00:51:50 -0800274 return C2_CANNOT_DO;
275 }
276
277 uint32_t rightShiftBits = component.offsetInBits - lastOffsetInBits;
278 uint32_t allocatedDepthInBits = component.sizeInBits + rightShiftBits;
279 C2PlanarLayout::plane_index_t planeId;
280 C2PlaneInfo::channel_t channel;
281
282 switch (static_cast<PlaneLayoutComponentType>(component.type.value)) {
283 case PlaneLayoutComponentType::Y:
284 planeId = C2PlanarLayout::PLANE_Y;
285 channel = C2PlaneInfo::CHANNEL_Y;
286 break;
287 case PlaneLayoutComponentType::CB:
288 planeId = C2PlanarLayout::PLANE_U;
289 channel = C2PlaneInfo::CHANNEL_CB;
290 break;
291 case PlaneLayoutComponentType::CR:
292 planeId = C2PlanarLayout::PLANE_V;
293 channel = C2PlaneInfo::CHANNEL_CR;
294 break;
295 default:
Praveen Chavan2c580d92022-02-24 12:23:46 -0800296 mapper.unlock(handle);
Praveen Chavan34493f12021-02-18 00:51:50 -0800297 return C2_CORRUPTED;
298 }
299
300 addr[planeId] = pointer + plane.offsetInBytes + (component.offsetInBits / 8);
301 layout->planes[planeId] = {
302 channel, // channel
303 static_cast<int32_t>(plane.sampleIncrementInBits / 8), // colInc
304 static_cast<int32_t>(plane.strideInBytes), // rowInc
305 static_cast<uint32_t>(plane.horizontalSubsampling), // mColSampling
306 static_cast<uint32_t>(plane.verticalSubsampling), // mRowSampling
307 allocatedDepthInBits, // allocatedDepth (bits)
308 static_cast<uint32_t>(component.sizeInBits), // bitDepth (bits)
309 rightShiftBits, // rightShift (bits)
310 C2PlaneInfo::NATIVE, // endianness
311 rootIx, // rootIx
312 static_cast<uint32_t>(component.offsetInBits / 8), // offset (bytes)
313 };
314
315 layout->numPlanes++;
316 lastOffsetInBits = component.offsetInBits + component.sizeInBits;
Praveen Chavan34493f12021-02-18 00:51:50 -0800317 }
318 }
319 return C2_OK;
320}
321
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700322} // unnamed namespace
323
Praveen Chavan34493f12021-02-18 00:51:50 -0800324
Pawin Vongmasa36653902018-11-15 00:10:25 -0800325native_handle_t *UnwrapNativeCodec2GrallocHandle(const C2Handle *const handle) {
326 return C2HandleGralloc::UnwrapNativeHandle(handle);
327}
328
Pawin Vongmasa36653902018-11-15 00:10:25 -0800329C2Handle *WrapNativeCodec2GrallocHandle(
330 const native_handle_t *const handle,
331 uint32_t width, uint32_t height, uint32_t format, uint64_t usage, uint32_t stride,
332 uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
333 return C2HandleGralloc::WrapNativeHandle(handle, width, height, format, usage, stride,
334 generation, igbp_id, igbp_slot);
335}
336
Sungtak Lee08515812019-06-05 11:16:32 -0700337bool MigrateNativeCodec2GrallocHandle(
338 native_handle_t *handle,
339 uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
340 return C2HandleGralloc::MigrateNativeHandle(handle, generation, igbp_id, igbp_slot);
341}
342
343
Pawin Vongmasa36653902018-11-15 00:10:25 -0800344class C2AllocationGralloc : public C2GraphicAllocation {
345public:
346 virtual ~C2AllocationGralloc() override;
347
348 virtual c2_status_t map(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900349 C2Rect c2Rect, C2MemoryUsage usage, C2Fence *fence,
Pawin Vongmasa36653902018-11-15 00:10:25 -0800350 C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) override;
351 virtual c2_status_t unmap(
352 uint8_t **addr /* nonnull */, C2Rect rect, C2Fence *fence /* nullable */) override;
353 virtual C2Allocator::id_t getAllocatorId() const override { return mAllocatorId; }
354 virtual const C2Handle *handle() const override { return mLockedHandle ? : mHandle; }
355 virtual bool equals(const std::shared_ptr<const C2GraphicAllocation> &other) const override;
356
357 // internal methods
358 // |handle| will be moved.
Marissa Wall2a24a302019-11-25 11:19:18 -0800359
Pawin Vongmasa36653902018-11-15 00:10:25 -0800360 C2AllocationGralloc(
Marissa Wall2a24a302019-11-25 11:19:18 -0800361 uint32_t width, uint32_t height,
362 uint32_t format, uint32_t layerCount,
363 uint64_t grallocUsage, uint32_t stride,
Marissa Wall8806edc2019-06-21 09:50:47 -0700364 hidl_handle &hidlHandle,
365 const C2HandleGralloc *const handle,
366 C2Allocator::id_t allocatorId);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800367 int dup() const;
368 c2_status_t status() const;
369
370private:
Marissa Wall2a24a302019-11-25 11:19:18 -0800371 const uint32_t mWidth;
372 const uint32_t mHeight;
373 const uint32_t mFormat;
374 const uint32_t mLayerCount;
375 const uint64_t mGrallocUsage;
376 const uint32_t mStride;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800377 const hidl_handle mHidlHandle;
378 const C2HandleGralloc *mHandle;
379 buffer_handle_t mBuffer;
380 const C2HandleGralloc *mLockedHandle;
381 bool mLocked;
382 C2Allocator::id_t mAllocatorId;
383 std::mutex mMappedLock;
384};
385
386C2AllocationGralloc::C2AllocationGralloc(
Marissa Wall2a24a302019-11-25 11:19:18 -0800387 uint32_t width, uint32_t height,
388 uint32_t format, uint32_t layerCount,
389 uint64_t grallocUsage, uint32_t stride,
Pawin Vongmasa36653902018-11-15 00:10:25 -0800390 hidl_handle &hidlHandle,
391 const C2HandleGralloc *const handle,
392 C2Allocator::id_t allocatorId)
Marissa Wall2a24a302019-11-25 11:19:18 -0800393 : C2GraphicAllocation(width, height),
394 mWidth(width),
395 mHeight(height),
396 mFormat(format),
397 mLayerCount(layerCount),
398 mGrallocUsage(grallocUsage),
399 mStride(stride),
Marissa Wall8806edc2019-06-21 09:50:47 -0700400 mHidlHandle(std::move(hidlHandle)),
401 mHandle(handle),
402 mBuffer(nullptr),
403 mLockedHandle(nullptr),
404 mLocked(false),
405 mAllocatorId(allocatorId) {
406}
407
Pawin Vongmasa36653902018-11-15 00:10:25 -0800408C2AllocationGralloc::~C2AllocationGralloc() {
Yichi Chenfa94a3b2018-12-08 00:06:25 +0800409 if (mBuffer && mLocked) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800410 // implementation ignores addresss and rect
411 uint8_t* addr[C2PlanarLayout::MAX_NUM_PLANES] = {};
412 unmap(addr, C2Rect(), nullptr);
413 }
Yichi Chenfa94a3b2018-12-08 00:06:25 +0800414 if (mBuffer) {
Marissa Wall2a24a302019-11-25 11:19:18 -0800415 status_t err = GraphicBufferMapper::get().freeBuffer(mBuffer);
416 if (err) {
417 ALOGE("failed transaction: freeBuffer");
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700418 }
Yichi Chenfa94a3b2018-12-08 00:06:25 +0800419 }
420 if (mHandle) {
421 native_handle_delete(
422 const_cast<native_handle_t *>(reinterpret_cast<const native_handle_t *>(mHandle)));
423 }
Sungtak Lee2729dcf2019-01-18 13:15:07 -0800424 if (mLockedHandle) {
425 native_handle_delete(
426 const_cast<native_handle_t *>(
427 reinterpret_cast<const native_handle_t *>(mLockedHandle)));
428 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800429}
430
431c2_status_t C2AllocationGralloc::map(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900432 C2Rect c2Rect, C2MemoryUsage usage, C2Fence *fence,
Pawin Vongmasa36653902018-11-15 00:10:25 -0800433 C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) {
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900434 const Rect rect{(int32_t)c2Rect.left, (int32_t)c2Rect.top,
435 (int32_t)(c2Rect.left + c2Rect.width) /* right */,
436 (int32_t)(c2Rect.top + c2Rect.height) /* bottom */};
437
Pawin Vongmasa36653902018-11-15 00:10:25 -0800438 uint64_t grallocUsage = static_cast<C2AndroidMemoryUsage>(usage).asGrallocUsage();
439 ALOGV("mapping buffer with usage %#llx => %#llx",
440 (long long)usage.expected, (long long)grallocUsage);
441
442 // TODO
Marissa Wall2a24a302019-11-25 11:19:18 -0800443 (void)fence;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800444
445 std::lock_guard<std::mutex> lock(mMappedLock);
446 if (mBuffer && mLocked) {
447 ALOGD("already mapped");
448 return C2_DUPLICATE;
449 }
450 if (!layout || !addr) {
451 ALOGD("wrong param");
452 return C2_BAD_VALUE;
453 }
454
Pawin Vongmasa36653902018-11-15 00:10:25 -0800455 if (!mBuffer) {
Marissa Wall2a24a302019-11-25 11:19:18 -0800456 status_t err = GraphicBufferMapper::get().importBuffer(
457 mHidlHandle.getNativeHandle(), mWidth, mHeight, mLayerCount,
458 mFormat, mGrallocUsage, mStride, &mBuffer);
459 if (err) {
460 ALOGE("failed transaction: importBuffer");
461 return C2_CORRUPTED;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800462 }
463 if (mBuffer == nullptr) {
464 ALOGD("importBuffer returned null buffer");
465 return C2_CORRUPTED;
466 }
467 uint32_t generation = 0;
468 uint64_t igbp_id = 0;
469 uint32_t igbp_slot = 0;
470 if (mHandle) {
471 mHandle->getIgbpData(&generation, &igbp_id, &igbp_slot);
472 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800473
Marissa Wall2a24a302019-11-25 11:19:18 -0800474 mLockedHandle = C2HandleGralloc::WrapAndMoveNativeHandle(
475 mBuffer, mWidth, mHeight, mFormat, mGrallocUsage,
476 mStride, generation, igbp_id, igbp_slot);
Marissa Wall8806edc2019-06-21 09:50:47 -0700477 }
Praveen Chavan34493f12021-02-18 00:51:50 -0800478
479 // 'NATIVE' on Android means LITTLE_ENDIAN
480 constexpr C2PlaneInfo::endianness_t kEndianness = C2PlaneInfo::NATIVE;
481
Tao Wu9d482892023-09-15 02:28:41 +0000482 // Try to resolve IMPLEMENTATION_DEFINED format to accurate format if
483 // possible.
484 uint32_t format = mFormat;
485 uint32_t fourCc;
486 if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED &&
487 !GraphicBufferMapper::get().getPixelFormatFourCC(mBuffer, &fourCc)) {
488 switch (fourCc) {
489 case DRM_FORMAT_XBGR8888:
490 format = static_cast<uint32_t>(PixelFormat4::RGBX_8888);
491 break;
492 case DRM_FORMAT_ABGR8888:
493 format = static_cast<uint32_t>(PixelFormat4::RGBA_8888);
494 break;
495 default:
496 break;
497 }
498 }
499
500 switch (format) {
Marissa Wall2a24a302019-11-25 11:19:18 -0800501 case static_cast<uint32_t>(PixelFormat4::RGBA_1010102): {
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700502 // TRICKY: this is used for media as YUV444 in the case when it is queued directly to a
503 // Surface. In all other cases it is RGBA. We don't know which case it is here, so
504 // default to YUV for now.
505 void *pointer = nullptr;
Marissa Wall2a24a302019-11-25 11:19:18 -0800506 // TODO: fence
507 status_t err = GraphicBufferMapper::get().lock(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900508 const_cast<native_handle_t *>(mBuffer), grallocUsage, rect, &pointer);
Marissa Wall2a24a302019-11-25 11:19:18 -0800509 if (err) {
510 ALOGE("failed transaction: lock(RGBA_1010102)");
511 return C2_CORRUPTED;
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700512 }
513 // treat as 32-bit values
514 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)pointer;
515 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)pointer;
516 addr[C2PlanarLayout::PLANE_V] = (uint8_t *)pointer;
517 addr[C2PlanarLayout::PLANE_A] = (uint8_t *)pointer;
518 layout->type = C2PlanarLayout::TYPE_YUVA;
519 layout->numPlanes = 4;
520 layout->rootPlanes = 1;
521 layout->planes[C2PlanarLayout::PLANE_Y] = {
522 C2PlaneInfo::CHANNEL_Y, // channel
523 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800524 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700525 1, // mColSampling
526 1, // mRowSampling
527 32, // allocatedDepth
528 10, // bitDepth
529 10, // rightShift
530 C2PlaneInfo::LITTLE_END, // endianness
531 C2PlanarLayout::PLANE_Y, // rootIx
532 0, // offset
533 };
534 layout->planes[C2PlanarLayout::PLANE_U] = {
535 C2PlaneInfo::CHANNEL_CB, // channel
536 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800537 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700538 1, // mColSampling
539 1, // mRowSampling
540 32, // allocatedDepth
541 10, // bitDepth
542 0, // rightShift
543 C2PlaneInfo::LITTLE_END, // endianness
544 C2PlanarLayout::PLANE_Y, // rootIx
545 0, // offset
546 };
547 layout->planes[C2PlanarLayout::PLANE_V] = {
548 C2PlaneInfo::CHANNEL_CR, // channel
549 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800550 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700551 1, // mColSampling
552 1, // mRowSampling
553 32, // allocatedDepth
554 10, // bitDepth
555 20, // rightShift
556 C2PlaneInfo::LITTLE_END, // endianness
557 C2PlanarLayout::PLANE_Y, // rootIx
558 0, // offset
559 };
560 layout->planes[C2PlanarLayout::PLANE_A] = {
561 C2PlaneInfo::CHANNEL_A, // channel
562 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800563 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700564 1, // mColSampling
565 1, // mRowSampling
566 32, // allocatedDepth
567 2, // bitDepth
568 30, // rightShift
569 C2PlaneInfo::LITTLE_END, // endianness
570 C2PlanarLayout::PLANE_Y, // rootIx
571 0, // offset
572 };
573 break;
574 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800575
Marissa Wall2a24a302019-11-25 11:19:18 -0800576 case static_cast<uint32_t>(PixelFormat4::RGBA_8888):
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700577 // TODO: alpha channel
578 // fall-through
Marissa Wall2a24a302019-11-25 11:19:18 -0800579 case static_cast<uint32_t>(PixelFormat4::RGBX_8888): {
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700580 void *pointer = nullptr;
Marissa Wall2a24a302019-11-25 11:19:18 -0800581 // TODO: fence
582 status_t err = GraphicBufferMapper::get().lock(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900583 const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &pointer);
Marissa Wall2a24a302019-11-25 11:19:18 -0800584 if (err) {
585 ALOGE("failed transaction: lock(RGBA_8888)");
586 return C2_CORRUPTED;
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700587 }
588 addr[C2PlanarLayout::PLANE_R] = (uint8_t *)pointer;
589 addr[C2PlanarLayout::PLANE_G] = (uint8_t *)pointer + 1;
590 addr[C2PlanarLayout::PLANE_B] = (uint8_t *)pointer + 2;
591 layout->type = C2PlanarLayout::TYPE_RGB;
592 layout->numPlanes = 3;
593 layout->rootPlanes = 1;
594 layout->planes[C2PlanarLayout::PLANE_R] = {
595 C2PlaneInfo::CHANNEL_R, // channel
596 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800597 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700598 1, // mColSampling
599 1, // mRowSampling
600 8, // allocatedDepth
601 8, // bitDepth
602 0, // rightShift
603 C2PlaneInfo::NATIVE, // endianness
604 C2PlanarLayout::PLANE_R, // rootIx
605 0, // offset
606 };
607 layout->planes[C2PlanarLayout::PLANE_G] = {
608 C2PlaneInfo::CHANNEL_G, // channel
609 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800610 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700611 1, // mColSampling
612 1, // mRowSampling
613 8, // allocatedDepth
614 8, // bitDepth
615 0, // rightShift
616 C2PlaneInfo::NATIVE, // endianness
617 C2PlanarLayout::PLANE_R, // rootIx
618 1, // offset
619 };
620 layout->planes[C2PlanarLayout::PLANE_B] = {
621 C2PlaneInfo::CHANNEL_B, // channel
622 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800623 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700624 1, // mColSampling
625 1, // mRowSampling
626 8, // allocatedDepth
627 8, // bitDepth
628 0, // rightShift
629 C2PlaneInfo::NATIVE, // endianness
630 C2PlanarLayout::PLANE_R, // rootIx
631 2, // offset
632 };
633 break;
634 }
635
David Stevens1cadc75d2020-04-03 10:50:51 +0900636 case static_cast<uint32_t>(PixelFormat4::BLOB): {
637 void *pointer = nullptr;
638 // TODO: fence
639 status_t err = GraphicBufferMapper::get().lock(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900640 const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &pointer);
David Stevens1cadc75d2020-04-03 10:50:51 +0900641 if (err) {
642 ALOGE("failed transaction: lock(BLOB)");
643 return C2_CORRUPTED;
644 }
645 *addr = (uint8_t *)pointer;
646 break;
647 }
648
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700649 case static_cast<uint32_t>(PixelFormat4::YCBCR_422_SP):
650 // fall-through
651 case static_cast<uint32_t>(PixelFormat4::YCRCB_420_SP):
652 // fall-through
653 case static_cast<uint32_t>(PixelFormat4::YCBCR_422_I):
654 // fall-through
Marissa Wall2a24a302019-11-25 11:19:18 -0800655 case static_cast<uint32_t>(PixelFormat4::YCBCR_420_888):
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700656 // fall-through
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700657 case static_cast<uint32_t>(PixelFormat4::YV12): {
Marissa Wall2a24a302019-11-25 11:19:18 -0800658 android_ycbcr ycbcrLayout;
659
660 status_t err = GraphicBufferMapper::get().lockYCbCr(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900661 const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &ycbcrLayout);
Marissa Wall2a24a302019-11-25 11:19:18 -0800662 if (err) {
Wonsik Kimd91f3fb2021-02-24 12:35:31 -0800663 ALOGE("failed transaction: lockYCbCr (err=%d)", err);
664 return C2_CORRUPTED;
665 }
666 if (!ycbcrLayout.y || !ycbcrLayout.cb || !ycbcrLayout.cr
667 || ycbcrLayout.ystride == 0
668 || ycbcrLayout.cstride == 0
669 || ycbcrLayout.chroma_step == 0) {
670 ALOGE("invalid layout: lockYCbCr (y=%s cb=%s cr=%s "
671 "ystride=%zu cstride=%zu chroma_step=%zu)",
672 ycbcrLayout.y ? "(non-null)" : "(null)",
673 ycbcrLayout.cb ? "(non-null)" : "(null)",
674 ycbcrLayout.cr ? "(non-null)" : "(null)",
675 ycbcrLayout.ystride, ycbcrLayout.cstride, ycbcrLayout.chroma_step);
Marissa Wall469b90a2019-11-06 10:12:43 -0800676 return C2_CORRUPTED;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700677 }
Marissa Wall2a24a302019-11-25 11:19:18 -0800678
Pawin Vongmasa36653902018-11-15 00:10:25 -0800679 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)ycbcrLayout.y;
680 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)ycbcrLayout.cb;
681 addr[C2PlanarLayout::PLANE_V] = (uint8_t *)ycbcrLayout.cr;
682 layout->type = C2PlanarLayout::TYPE_YUV;
683 layout->numPlanes = 3;
684 layout->rootPlanes = 3;
685 layout->planes[C2PlanarLayout::PLANE_Y] = {
686 C2PlaneInfo::CHANNEL_Y, // channel
687 1, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800688 (int32_t)ycbcrLayout.ystride, // rowInc
Pawin Vongmasa36653902018-11-15 00:10:25 -0800689 1, // mColSampling
690 1, // mRowSampling
691 8, // allocatedDepth
692 8, // bitDepth
693 0, // rightShift
694 C2PlaneInfo::NATIVE, // endianness
695 C2PlanarLayout::PLANE_Y, // rootIx
696 0, // offset
697 };
698 layout->planes[C2PlanarLayout::PLANE_U] = {
699 C2PlaneInfo::CHANNEL_CB, // channel
Marissa Wall2a24a302019-11-25 11:19:18 -0800700 (int32_t)ycbcrLayout.chroma_step, // colInc
701 (int32_t)ycbcrLayout.cstride, // rowInc
Pawin Vongmasa36653902018-11-15 00:10:25 -0800702 2, // mColSampling
703 2, // mRowSampling
704 8, // allocatedDepth
705 8, // bitDepth
706 0, // rightShift
707 C2PlaneInfo::NATIVE, // endianness
708 C2PlanarLayout::PLANE_U, // rootIx
709 0, // offset
710 };
711 layout->planes[C2PlanarLayout::PLANE_V] = {
712 C2PlaneInfo::CHANNEL_CR, // channel
Marissa Wall2a24a302019-11-25 11:19:18 -0800713 (int32_t)ycbcrLayout.chroma_step, // colInc
714 (int32_t)ycbcrLayout.cstride, // rowInc
Pawin Vongmasa36653902018-11-15 00:10:25 -0800715 2, // mColSampling
716 2, // mRowSampling
717 8, // allocatedDepth
718 8, // bitDepth
719 0, // rightShift
720 C2PlaneInfo::NATIVE, // endianness
721 C2PlanarLayout::PLANE_V, // rootIx
722 0, // offset
723 };
Pawin Vongmasa36653902018-11-15 00:10:25 -0800724 break;
725 }
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700726
727 case static_cast<uint32_t>(PixelFormat4::YCBCR_P010): {
Praveen Chavan6380fff2022-06-22 10:49:48 -0700728 // In Android T, P010 is relaxed to allow arbitrary stride for the Y and UV planes,
729 // try locking with the gralloc4 mapper first.
730 c2_status_t status = Gralloc4Mapper_lock(
731 const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, layout, addr);
732 if (status == C2_OK) {
733 break;
734 }
735
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700736 void *pointer = nullptr;
737 status_t err = GraphicBufferMapper::get().lock(
738 const_cast<native_handle_t *>(mBuffer), grallocUsage, rect, &pointer);
739 if (err) {
740 ALOGE("failed transaction: lock(YCBCR_P010)");
741 return C2_CORRUPTED;
742 }
743 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)pointer;
744 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)pointer + mStride * 2 * rect.height();
745 addr[C2PlanarLayout::PLANE_V] = addr[C2PlanarLayout::PLANE_U] + 2;
746 layout->type = C2PlanarLayout::TYPE_YUV;
747 layout->numPlanes = 3;
748 layout->rootPlanes = 2;
749 layout->planes[C2PlanarLayout::PLANE_Y] = {
750 C2PlaneInfo::CHANNEL_Y, // channel
751 2, // colInc
752 static_cast<int32_t>(2 * mStride), // rowInc
753 1, // mColSampling
754 1, // mRowSampling
755 16, // allocatedDepth
756 10, // bitDepth
757 6, // rightShift
Praveen Chavan34493f12021-02-18 00:51:50 -0800758 kEndianness, // endianness
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700759 C2PlanarLayout::PLANE_Y, // rootIx
760 0, // offset
761 };
762 layout->planes[C2PlanarLayout::PLANE_U] = {
763 C2PlaneInfo::CHANNEL_CB, // channel
764 4, // colInc
765 static_cast<int32_t>(2 * mStride), // rowInc
766 2, // mColSampling
767 2, // mRowSampling
768 16, // allocatedDepth
769 10, // bitDepth
770 6, // rightShift
Praveen Chavan34493f12021-02-18 00:51:50 -0800771 kEndianness, // endianness
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700772 C2PlanarLayout::PLANE_U, // rootIx
773 0, // offset
774 };
775 layout->planes[C2PlanarLayout::PLANE_V] = {
776 C2PlaneInfo::CHANNEL_CR, // channel
777 4, // colInc
778 static_cast<int32_t>(2 * mStride), // rowInc
779 2, // mColSampling
780 2, // mRowSampling
781 16, // allocatedDepth
782 10, // bitDepth
783 6, // rightShift
Praveen Chavan34493f12021-02-18 00:51:50 -0800784 kEndianness, // endianness
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700785 C2PlanarLayout::PLANE_U, // rootIx
786 2, // offset
787 };
788 break;
789 }
790
791 default: {
Praveen Chavan34493f12021-02-18 00:51:50 -0800792 // We don't know what it is, let's try to lock it with gralloc4
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700793 android_ycbcr ycbcrLayout;
Harish Mahendrakar7dc54f92022-06-30 20:36:23 -0700794 if (isAtLeastT()) {
795 c2_status_t status = Gralloc4Mapper_lock(
796 const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, layout, addr);
797 if (status == C2_OK) {
798 break;
799 }
Praveen Chavan34493f12021-02-18 00:51:50 -0800800 }
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700801
Praveen Chavan34493f12021-02-18 00:51:50 -0800802 // fallback to lockYCbCr
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700803 status_t err = GraphicBufferMapper::get().lockYCbCr(
804 const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &ycbcrLayout);
Wonsik Kimd91f3fb2021-02-24 12:35:31 -0800805 if (err == OK && ycbcrLayout.y && ycbcrLayout.cb && ycbcrLayout.cr
806 && ycbcrLayout.ystride > 0
807 && ycbcrLayout.cstride > 0
808 && ycbcrLayout.chroma_step > 0) {
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700809 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)ycbcrLayout.y;
810 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)ycbcrLayout.cb;
811 addr[C2PlanarLayout::PLANE_V] = (uint8_t *)ycbcrLayout.cr;
812 layout->type = C2PlanarLayout::TYPE_YUV;
813 layout->numPlanes = 3;
814 layout->rootPlanes = 3;
815 layout->planes[C2PlanarLayout::PLANE_Y] = {
816 C2PlaneInfo::CHANNEL_Y, // channel
817 1, // colInc
818 (int32_t)ycbcrLayout.ystride, // rowInc
819 1, // mColSampling
820 1, // mRowSampling
821 8, // allocatedDepth
822 8, // bitDepth
823 0, // rightShift
824 C2PlaneInfo::NATIVE, // endianness
825 C2PlanarLayout::PLANE_Y, // rootIx
826 0, // offset
827 };
828 layout->planes[C2PlanarLayout::PLANE_U] = {
829 C2PlaneInfo::CHANNEL_CB, // channel
830 (int32_t)ycbcrLayout.chroma_step, // colInc
831 (int32_t)ycbcrLayout.cstride, // rowInc
832 2, // mColSampling
833 2, // mRowSampling
834 8, // allocatedDepth
835 8, // bitDepth
836 0, // rightShift
837 C2PlaneInfo::NATIVE, // endianness
838 C2PlanarLayout::PLANE_U, // rootIx
839 0, // offset
840 };
841 layout->planes[C2PlanarLayout::PLANE_V] = {
842 C2PlaneInfo::CHANNEL_CR, // channel
843 (int32_t)ycbcrLayout.chroma_step, // colInc
844 (int32_t)ycbcrLayout.cstride, // rowInc
845 2, // mColSampling
846 2, // mRowSampling
847 8, // allocatedDepth
848 8, // bitDepth
849 0, // rightShift
850 C2PlaneInfo::NATIVE, // endianness
851 C2PlanarLayout::PLANE_V, // rootIx
852 0, // offset
853 };
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700854 break;
855 }
856
857 // We really don't know what this is; lock the buffer and pass it through ---
858 // the client may know how to interpret it.
Lajos Molnar8faebbc2021-06-30 17:07:42 -0700859
860 // unlock previous allocation if it was successful
861 if (err == OK) {
862 err = GraphicBufferMapper::get().unlock(mBuffer);
863 if (err) {
864 ALOGE("failed transaction: unlock");
865 return C2_CORRUPTED;
866 }
867 }
868
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700869 void *pointer = nullptr;
870 err = GraphicBufferMapper::get().lock(
871 const_cast<native_handle_t *>(mBuffer), grallocUsage, rect, &pointer);
872 if (err) {
873 ALOGE("failed transaction: lock(??? %x)", mFormat);
874 return C2_CORRUPTED;
875 }
876 addr[0] = (uint8_t *)pointer;
877 layout->type = C2PlanarLayout::TYPE_UNKNOWN;
878 layout->numPlanes = 1;
879 layout->rootPlanes = 1;
880 layout->planes[0] = {
881 // TODO: CHANNEL_UNKNOWN?
882 C2PlaneInfo::channel_t(0xFF), // channel
883 1, // colInc
884 int32_t(mStride), // rowInc
885 1, // mColSampling
886 1, // mRowSampling
887 8, // allocatedDepth
888 8, // bitDepth
889 0, // rightShift
890 C2PlaneInfo::NATIVE, // endianness
891 0, // rootIx
892 0, // offset
893 };
894 break;
895 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800896 }
897 mLocked = true;
898
Wonsik Kimf12bebc2022-03-24 16:25:03 -0700899 // handle interleaved formats
900 if (layout->type == C2PlanarLayout::TYPE_YUV && layout->rootPlanes == 3) {
901 intptr_t uvOffset = addr[C2PlanarLayout::PLANE_V] - addr[C2PlanarLayout::PLANE_U];
902 intptr_t uvColInc = layout->planes[C2PlanarLayout::PLANE_U].colInc;
903 if (uvOffset > 0 && uvOffset < uvColInc) {
904 layout->rootPlanes = 2;
905 layout->planes[C2PlanarLayout::PLANE_V].rootIx = C2PlanarLayout::PLANE_U;
906 layout->planes[C2PlanarLayout::PLANE_V].offset = uvOffset;
907 } else if (uvOffset < 0 && uvOffset > -uvColInc) {
908 layout->rootPlanes = 2;
909 layout->planes[C2PlanarLayout::PLANE_U].rootIx = C2PlanarLayout::PLANE_V;
910 layout->planes[C2PlanarLayout::PLANE_U].offset = -uvOffset;
911 }
912 }
913
914 ALOGV("C2AllocationGralloc::map: layout: type=%d numPlanes=%d rootPlanes=%d",
915 layout->type, layout->numPlanes, layout->rootPlanes);
916 for (int i = 0; i < layout->numPlanes; ++i) {
917 const C2PlaneInfo &plane = layout->planes[i];
918 ALOGV("C2AllocationGralloc::map: plane[%d]: colInc=%d rowInc=%d rootIx=%u offset=%u",
919 i, plane.colInc, plane.rowInc, plane.rootIx, plane.offset);
920 }
921
Pawin Vongmasa36653902018-11-15 00:10:25 -0800922 return C2_OK;
923}
924
925c2_status_t C2AllocationGralloc::unmap(
926 uint8_t **addr, C2Rect rect, C2Fence *fence /* nullable */) {
927 // TODO: check addr and size, use fence
928 (void)addr;
929 (void)rect;
Marissa Wall2a24a302019-11-25 11:19:18 -0800930 (void)fence;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800931
932 std::lock_guard<std::mutex> lock(mMappedLock);
Marissa Wall2a24a302019-11-25 11:19:18 -0800933 // TODO: fence
934 status_t err = GraphicBufferMapper::get().unlock(mBuffer);
935 if (err) {
936 ALOGE("failed transaction: unlock");
937 return C2_CORRUPTED;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700938 }
Marissa Wall2a24a302019-11-25 11:19:18 -0800939
940 mLocked = false;
941 return C2_OK;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800942}
943
944bool C2AllocationGralloc::equals(const std::shared_ptr<const C2GraphicAllocation> &other) const {
945 return other && other->handle() == handle();
946}
947
948/* ===================================== GRALLOC ALLOCATOR ==================================== */
949class C2AllocatorGralloc::Impl {
950public:
951 Impl(id_t id, bool bufferQueue);
952
953 id_t getId() const {
954 return mTraits->id;
955 }
956
957 C2String getName() const {
958 return mTraits->name;
959 }
960
961 std::shared_ptr<const C2Allocator::Traits> getTraits() const {
962 return mTraits;
963 }
964
965 c2_status_t newGraphicAllocation(
966 uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
967 std::shared_ptr<C2GraphicAllocation> *allocation);
968
969 c2_status_t priorGraphicAllocation(
970 const C2Handle *handle,
971 std::shared_ptr<C2GraphicAllocation> *allocation);
972
973 c2_status_t status() const { return mInit; }
974
975private:
976 std::shared_ptr<C2Allocator::Traits> mTraits;
977 c2_status_t mInit;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800978 const bool mBufferQueue;
979};
980
981void _UnwrapNativeCodec2GrallocMetadata(
982 const C2Handle *const handle,
983 uint32_t *width, uint32_t *height, uint32_t *format,uint64_t *usage, uint32_t *stride,
984 uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) {
985 (void)C2HandleGralloc::Import(handle, width, height, format, usage, stride,
986 generation, igbp_id, igbp_slot);
987}
988
989C2AllocatorGralloc::Impl::Impl(id_t id, bool bufferQueue)
990 : mInit(C2_OK), mBufferQueue(bufferQueue) {
991 // TODO: get this from allocator
992 C2MemoryUsage minUsage = { 0, 0 }, maxUsage = { ~(uint64_t)0, ~(uint64_t)0 };
993 Traits traits = { "android.allocator.gralloc", id, C2Allocator::GRAPHIC, minUsage, maxUsage };
994 mTraits = std::make_shared<C2Allocator::Traits>(traits);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800995}
996
997c2_status_t C2AllocatorGralloc::Impl::newGraphicAllocation(
998 uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
999 std::shared_ptr<C2GraphicAllocation> *allocation) {
1000 uint64_t grallocUsage = static_cast<C2AndroidMemoryUsage>(usage).asGrallocUsage();
1001 ALOGV("allocating buffer with usage %#llx => %#llx",
1002 (long long)usage.expected, (long long)grallocUsage);
1003
Marissa Wall2a24a302019-11-25 11:19:18 -08001004 buffer_handle_t buffer;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001005
Marissa Wall2a24a302019-11-25 11:19:18 -08001006 uint32_t stride = 0;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001007
Marissa Wall2a24a302019-11-25 11:19:18 -08001008 status_t err = GraphicBufferAllocator::get().allocateRawHandle(width, height, format,
1009 1u /* layer count */, grallocUsage, &buffer, &stride, "C2GrallocAllocation");
1010 if (err) {
1011 ALOGE("failed transaction: allocate");
1012 return C2_CORRUPTED;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001013 }
Marissa Wall2a24a302019-11-25 11:19:18 -08001014
1015 hidl_handle hidlHandle;
1016 hidlHandle.setTo(const_cast<native_handle_t*>(buffer), true);
1017
1018 allocation->reset(new C2AllocationGralloc(
1019 width, height, format, 1u /* layer count */, grallocUsage, stride, hidlHandle,
1020 C2HandleGralloc::WrapAndMoveNativeHandle(
1021 hidlHandle, width, height,
1022 format, grallocUsage, stride,
1023 0, 0, mBufferQueue ? ~0 : 0),
1024 mTraits->id));
1025 return C2_OK;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001026}
1027
1028c2_status_t C2AllocatorGralloc::Impl::priorGraphicAllocation(
1029 const C2Handle *handle,
1030 std::shared_ptr<C2GraphicAllocation> *allocation) {
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001031
Marissa Wall2a24a302019-11-25 11:19:18 -08001032 uint32_t generation;
1033 uint64_t igbp_id;
1034 uint32_t igbp_slot;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001035
Marissa Wall2a24a302019-11-25 11:19:18 -08001036 uint32_t width;
1037 uint32_t height;
1038 uint32_t format;
1039 uint32_t layerCount = 1;
1040 uint64_t grallocUsage;
1041 uint32_t stride;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001042
Marissa Wall2a24a302019-11-25 11:19:18 -08001043 const C2HandleGralloc *grallocHandle = C2HandleGralloc::Import(
1044 handle, &width, &height, &format, &grallocUsage, &stride,
1045 &generation, &igbp_id, &igbp_slot);
1046 if (grallocHandle == nullptr) {
1047 return C2_BAD_VALUE;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001048 }
Marissa Wall2a24a302019-11-25 11:19:18 -08001049
1050 hidl_handle hidlHandle;
1051 hidlHandle.setTo(C2HandleGralloc::UnwrapNativeHandle(grallocHandle), true);
1052
1053 allocation->reset(new C2AllocationGralloc(
1054 width, height, format, layerCount,
1055 grallocUsage, stride, hidlHandle, grallocHandle, mTraits->id));
1056 return C2_OK;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001057}
1058
1059C2AllocatorGralloc::C2AllocatorGralloc(id_t id, bool bufferQueue)
1060 : mImpl(new Impl(id, bufferQueue)) {}
1061
1062C2AllocatorGralloc::~C2AllocatorGralloc() { delete mImpl; }
1063
1064C2Allocator::id_t C2AllocatorGralloc::getId() const {
1065 return mImpl->getId();
1066}
1067
1068C2String C2AllocatorGralloc::getName() const {
1069 return mImpl->getName();
1070}
1071
1072std::shared_ptr<const C2Allocator::Traits> C2AllocatorGralloc::getTraits() const {
1073 return mImpl->getTraits();
1074}
1075
1076c2_status_t C2AllocatorGralloc::newGraphicAllocation(
1077 uint32_t width, uint32_t height, uint32_t format, C2MemoryUsage usage,
1078 std::shared_ptr<C2GraphicAllocation> *allocation) {
1079 return mImpl->newGraphicAllocation(width, height, format, usage, allocation);
1080}
1081
1082c2_status_t C2AllocatorGralloc::priorGraphicAllocation(
1083 const C2Handle *handle,
1084 std::shared_ptr<C2GraphicAllocation> *allocation) {
1085 return mImpl->priorGraphicAllocation(handle, allocation);
1086}
1087
1088c2_status_t C2AllocatorGralloc::status() const {
1089 return mImpl->status();
1090}
1091
John Stultz653ddd12020-09-19 05:26:24 +00001092// static
1093bool C2AllocatorGralloc::CheckHandle(const C2Handle* const o) {
1094 return C2HandleGralloc::IsValid(o);
Pawin Vongmasa36653902018-11-15 00:10:25 -08001095}
1096
1097} // namespace android