blob: d874911f83ead8f46015d77ebad286d23cf8e38f [file] [log] [blame]
Chia-I Wu5bac7f32017-04-06 12:34:32 -07001/*
2 * Copyright 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_TAG "Gralloc2"
18
Jesse Hall5dac7812017-07-06 14:02:29 -070019#include <hidl/ServiceManagement.h>
Chia-I Wud8091b92017-05-16 14:30:34 -070020#include <hwbinder/IPCThreadState.h>
Chia-I Wu5bac7f32017-04-06 12:34:32 -070021#include <ui/Gralloc2.h>
22
Craig Donnere6ecb922017-12-27 14:59:29 -080023#include <inttypes.h>
Chia-I Wu5bac7f32017-04-06 12:34:32 -070024#include <log/log.h>
25#pragma clang diagnostic push
26#pragma clang diagnostic ignored "-Wzero-length-array"
27#include <sync/sync.h>
28#pragma clang diagnostic pop
29
Marissa Wall1e779252018-12-29 12:01:57 -080030using android::hardware::graphics::common::V1_1::BufferUsage;
31using android::hardware::graphics::common::V1_1::PixelFormat;
32using android::hardware::graphics::mapper::V2_0::BufferDescriptor;
33using android::hardware::graphics::mapper::V2_0::Error;
34using android::hardware::graphics::mapper::V2_0::YCbCrLayout;
35
Chia-I Wu5bac7f32017-04-06 12:34:32 -070036namespace android {
37
38namespace Gralloc2 {
39
Craig Donnere6ecb922017-12-27 14:59:29 -080040namespace {
41
Chia-I Wu5bac7f32017-04-06 12:34:32 -070042static constexpr Error kTransactionError = Error::NO_RESOURCES;
43
Craig Donnere6ecb922017-12-27 14:59:29 -080044uint64_t getValid10UsageBits() {
45 static const uint64_t valid10UsageBits = []() -> uint64_t {
46 using hardware::graphics::common::V1_0::BufferUsage;
47 uint64_t bits = 0;
Steven Moreland3cde8752018-05-01 16:54:17 -070048 for (const auto bit : hardware::hidl_enum_range<BufferUsage>()) {
Craig Donnere6ecb922017-12-27 14:59:29 -080049 bits = bits | bit;
50 }
Craig Donnere6ecb922017-12-27 14:59:29 -080051 return bits;
52 }();
53 return valid10UsageBits;
54}
55
56uint64_t getValid11UsageBits() {
57 static const uint64_t valid11UsageBits = []() -> uint64_t {
58 using hardware::graphics::common::V1_1::BufferUsage;
59 uint64_t bits = 0;
Steven Moreland3cde8752018-05-01 16:54:17 -070060 for (const auto bit : hardware::hidl_enum_range<BufferUsage>()) {
Craig Donnere6ecb922017-12-27 14:59:29 -080061 bits = bits | bit;
62 }
Chia-I Wu4f55f162018-01-16 21:58:18 -080063 return bits;
Craig Donnere6ecb922017-12-27 14:59:29 -080064 }();
65 return valid11UsageBits;
66}
67
Marissa Wall1e779252018-12-29 12:01:57 -080068static inline Gralloc2::IMapper::Rect sGralloc2Rect(const Rect& rect) {
69 Gralloc2::IMapper::Rect outRect{};
70 outRect.left = rect.left;
71 outRect.top = rect.top;
72 outRect.width = rect.width();
73 outRect.height = rect.height();
74 return outRect;
75}
76
Craig Donnere6ecb922017-12-27 14:59:29 -080077} // anonymous namespace
78
Jesse Hall5dac7812017-07-06 14:02:29 -070079void Mapper::preload() {
80 android::hardware::preloadPassthroughService<hardware::graphics::mapper::V2_0::IMapper>();
81}
82
Chia-I Wu5bac7f32017-04-06 12:34:32 -070083Mapper::Mapper()
84{
Chia-I Wu4f55f162018-01-16 21:58:18 -080085 mMapper = hardware::graphics::mapper::V2_0::IMapper::getService();
Chia-I Wudbbe33b2017-09-27 15:22:21 -070086 if (mMapper == nullptr) {
87 LOG_ALWAYS_FATAL("gralloc-mapper is missing");
88 }
89 if (mMapper->isRemote()) {
Chia-I Wu5bac7f32017-04-06 12:34:32 -070090 LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode");
91 }
Chia-I Wudbbe33b2017-09-27 15:22:21 -070092
93 // IMapper 2.1 is optional
Chia-I Wu4f55f162018-01-16 21:58:18 -080094 mMapperV2_1 = IMapper::castFrom(mMapper);
Chia-I Wu5bac7f32017-04-06 12:34:32 -070095}
96
Marissa Wall1e779252018-12-29 12:01:57 -080097status_t Mapper::validateBufferDescriptorInfo(IMapper::BufferDescriptorInfo* descriptorInfo) const {
Craig Donnere6ecb922017-12-27 14:59:29 -080098 uint64_t validUsageBits = getValid10UsageBits();
99 if (mMapperV2_1 != nullptr) {
100 validUsageBits = validUsageBits | getValid11UsageBits();
101 }
102
Marissa Wall1e779252018-12-29 12:01:57 -0800103 if (descriptorInfo->usage & ~validUsageBits) {
Craig Donnere6ecb922017-12-27 14:59:29 -0800104 ALOGE("buffer descriptor contains invalid usage bits 0x%" PRIx64,
Marissa Wall1e779252018-12-29 12:01:57 -0800105 descriptorInfo->usage & ~validUsageBits);
106 return BAD_VALUE;
Craig Donnere6ecb922017-12-27 14:59:29 -0800107 }
Marissa Wall1e779252018-12-29 12:01:57 -0800108 return NO_ERROR;
Craig Donnere6ecb922017-12-27 14:59:29 -0800109}
110
Marissa Wall1e779252018-12-29 12:01:57 -0800111status_t Mapper::createDescriptor(void* bufferDescriptorInfo, void* outBufferDescriptor) const {
112 IMapper::BufferDescriptorInfo* descriptorInfo =
113 static_cast<IMapper::BufferDescriptorInfo*>(bufferDescriptorInfo);
114 BufferDescriptor* outDescriptor = static_cast<BufferDescriptor*>(outBufferDescriptor);
115
116 status_t status = validateBufferDescriptorInfo(descriptorInfo);
117 if (status != NO_ERROR) {
118 return status;
Craig Donnere6ecb922017-12-27 14:59:29 -0800119 }
120
Marissa Wall1e779252018-12-29 12:01:57 -0800121 Error error;
Chia-I Wu4f55f162018-01-16 21:58:18 -0800122 auto hidl_cb = [&](const auto& tmpError, const auto& tmpDescriptor)
123 {
124 error = tmpError;
125 if (error != Error::NONE) {
126 return;
127 }
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700128
Chia-I Wu4f55f162018-01-16 21:58:18 -0800129 *outDescriptor = tmpDescriptor;
130 };
131
132 hardware::Return<void> ret;
133 if (mMapperV2_1 != nullptr) {
Marissa Wall1e779252018-12-29 12:01:57 -0800134 ret = mMapperV2_1->createDescriptor_2_1(*descriptorInfo, hidl_cb);
Chia-I Wu4f55f162018-01-16 21:58:18 -0800135 } else {
136 const hardware::graphics::mapper::V2_0::IMapper::BufferDescriptorInfo info = {
Marissa Wall1e779252018-12-29 12:01:57 -0800137 descriptorInfo->width,
138 descriptorInfo->height,
139 descriptorInfo->layerCount,
140 static_cast<hardware::graphics::common::V1_0::PixelFormat>(descriptorInfo->format),
141 descriptorInfo->usage,
Chia-I Wu4f55f162018-01-16 21:58:18 -0800142 };
143 ret = mMapper->createDescriptor(info, hidl_cb);
144 }
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700145
Marissa Wall1e779252018-12-29 12:01:57 -0800146 return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700147}
148
Marissa Wall1e779252018-12-29 12:01:57 -0800149status_t Mapper::importBuffer(const hardware::hidl_handle& rawHandle,
150 buffer_handle_t* outBufferHandle) const {
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700151 Error error;
152 auto ret = mMapper->importBuffer(rawHandle,
153 [&](const auto& tmpError, const auto& tmpBuffer)
154 {
155 error = tmpError;
156 if (error != Error::NONE) {
157 return;
158 }
159
160 *outBufferHandle = static_cast<buffer_handle_t>(tmpBuffer);
161 });
162
Marissa Wall1e779252018-12-29 12:01:57 -0800163 return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700164}
165
166void Mapper::freeBuffer(buffer_handle_t bufferHandle) const
167{
168 auto buffer = const_cast<native_handle_t*>(bufferHandle);
169 auto ret = mMapper->freeBuffer(buffer);
170
171 auto error = (ret.isOk()) ? static_cast<Error>(ret) : kTransactionError;
172 ALOGE_IF(error != Error::NONE, "freeBuffer(%p) failed with %d",
173 buffer, error);
174}
175
Marissa Wall1e779252018-12-29 12:01:57 -0800176status_t Mapper::validateBufferSize(buffer_handle_t bufferHandle, uint32_t width, uint32_t height,
177 android::PixelFormat format, uint32_t layerCount,
178 uint64_t usage, uint32_t stride) const {
Chia-I Wudbbe33b2017-09-27 15:22:21 -0700179 if (mMapperV2_1 == nullptr) {
Marissa Wall1e779252018-12-29 12:01:57 -0800180 return NO_ERROR;
Chia-I Wudbbe33b2017-09-27 15:22:21 -0700181 }
182
Marissa Wall1e779252018-12-29 12:01:57 -0800183 IMapper::BufferDescriptorInfo descriptorInfo = {};
184 descriptorInfo.width = width;
185 descriptorInfo.height = height;
186 descriptorInfo.layerCount = layerCount;
187 descriptorInfo.format = static_cast<hardware::graphics::common::V1_1::PixelFormat>(format);
188 descriptorInfo.usage = usage;
189
Chia-I Wudbbe33b2017-09-27 15:22:21 -0700190 auto buffer = const_cast<native_handle_t*>(bufferHandle);
191 auto ret = mMapperV2_1->validateBufferSize(buffer, descriptorInfo, stride);
192
Marissa Wall1e779252018-12-29 12:01:57 -0800193 return static_cast<status_t>((ret.isOk()) ? static_cast<Error>(ret) : kTransactionError);
Chia-I Wudbbe33b2017-09-27 15:22:21 -0700194}
195
196void Mapper::getTransportSize(buffer_handle_t bufferHandle,
197 uint32_t* outNumFds, uint32_t* outNumInts) const
198{
199 *outNumFds = uint32_t(bufferHandle->numFds);
200 *outNumInts = uint32_t(bufferHandle->numInts);
201
202 if (mMapperV2_1 == nullptr) {
203 return;
204 }
205
206 Error error;
207 auto buffer = const_cast<native_handle_t*>(bufferHandle);
208 auto ret = mMapperV2_1->getTransportSize(buffer,
209 [&](const auto& tmpError, const auto& tmpNumFds, const auto& tmpNumInts) {
210 error = tmpError;
211 if (error != Error::NONE) {
212 return;
213 }
214
215 *outNumFds = tmpNumFds;
216 *outNumInts = tmpNumInts;
217 });
218
Marissa Wall1e779252018-12-29 12:01:57 -0800219 error = (ret.isOk()) ? error : kTransactionError;
220
221 ALOGE_IF(error != Error::NONE, "getTransportSize(%p) failed with %d", buffer, error);
Chia-I Wudbbe33b2017-09-27 15:22:21 -0700222}
223
Marissa Wall1e779252018-12-29 12:01:57 -0800224status_t Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
225 int acquireFence, void** outData) const {
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700226 auto buffer = const_cast<native_handle_t*>(bufferHandle);
227
Marissa Wall1e779252018-12-29 12:01:57 -0800228 IMapper::Rect accessRegion = sGralloc2Rect(bounds);
229
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700230 // put acquireFence in a hidl_handle
231 hardware::hidl_handle acquireFenceHandle;
232 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
233 if (acquireFence >= 0) {
234 auto h = native_handle_init(acquireFenceStorage, 1, 0);
235 h->data[0] = acquireFence;
236 acquireFenceHandle = h;
237 }
238
239 Error error;
240 auto ret = mMapper->lock(buffer, usage, accessRegion, acquireFenceHandle,
241 [&](const auto& tmpError, const auto& tmpData)
242 {
243 error = tmpError;
244 if (error != Error::NONE) {
245 return;
246 }
247
248 *outData = tmpData;
249 });
250
251 // we own acquireFence even on errors
252 if (acquireFence >= 0) {
253 close(acquireFence);
254 }
255
Marissa Wall1e779252018-12-29 12:01:57 -0800256 error = (ret.isOk()) ? error : kTransactionError;
257
258 ALOGW_IF(error != Error::NONE, "lock(%p, ...) failed: %d", bufferHandle, error);
259
260 return static_cast<status_t>(error);
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700261}
262
Marissa Wall1e779252018-12-29 12:01:57 -0800263status_t Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
264 int acquireFence, android_ycbcr* ycbcr) const {
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700265 auto buffer = const_cast<native_handle_t*>(bufferHandle);
266
Marissa Wall1e779252018-12-29 12:01:57 -0800267 IMapper::Rect accessRegion = sGralloc2Rect(bounds);
268
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700269 // put acquireFence in a hidl_handle
270 hardware::hidl_handle acquireFenceHandle;
271 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
272 if (acquireFence >= 0) {
273 auto h = native_handle_init(acquireFenceStorage, 1, 0);
274 h->data[0] = acquireFence;
275 acquireFenceHandle = h;
276 }
277
Marissa Wall1e779252018-12-29 12:01:57 -0800278 YCbCrLayout layout;
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700279 Error error;
280 auto ret = mMapper->lockYCbCr(buffer, usage, accessRegion,
281 acquireFenceHandle,
282 [&](const auto& tmpError, const auto& tmpLayout)
283 {
284 error = tmpError;
285 if (error != Error::NONE) {
286 return;
287 }
288
Marissa Wall1e779252018-12-29 12:01:57 -0800289 layout = tmpLayout;
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700290 });
291
Marissa Wall1e779252018-12-29 12:01:57 -0800292 if (error == Error::NONE) {
293 ycbcr->y = layout.y;
294 ycbcr->cb = layout.cb;
295 ycbcr->cr = layout.cr;
296 ycbcr->ystride = static_cast<size_t>(layout.yStride);
297 ycbcr->cstride = static_cast<size_t>(layout.cStride);
298 ycbcr->chroma_step = static_cast<size_t>(layout.chromaStep);
299 }
300
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700301 // we own acquireFence even on errors
302 if (acquireFence >= 0) {
303 close(acquireFence);
304 }
305
Marissa Wall1e779252018-12-29 12:01:57 -0800306 return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700307}
308
309int Mapper::unlock(buffer_handle_t bufferHandle) const
310{
311 auto buffer = const_cast<native_handle_t*>(bufferHandle);
312
313 int releaseFence = -1;
314 Error error;
315 auto ret = mMapper->unlock(buffer,
316 [&](const auto& tmpError, const auto& tmpReleaseFence)
317 {
318 error = tmpError;
319 if (error != Error::NONE) {
320 return;
321 }
322
323 auto fenceHandle = tmpReleaseFence.getNativeHandle();
324 if (fenceHandle && fenceHandle->numFds == 1) {
325 int fd = dup(fenceHandle->data[0]);
326 if (fd >= 0) {
327 releaseFence = fd;
328 } else {
329 ALOGD("failed to dup unlock release fence");
330 sync_wait(fenceHandle->data[0], -1);
331 }
332 }
333 });
334
Marissa Wall1e779252018-12-29 12:01:57 -0800335 error = (ret.isOk()) ? error : kTransactionError;
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700336 if (error != Error::NONE) {
337 ALOGE("unlock(%p) failed with %d", buffer, error);
338 }
339
340 return releaseFence;
341}
342
343Allocator::Allocator(const Mapper& mapper)
344 : mMapper(mapper)
345{
Chia-I Wucb8405e2017-04-17 15:20:19 -0700346 mAllocator = IAllocator::getService();
347 if (mAllocator == nullptr) {
348 LOG_ALWAYS_FATAL("gralloc-alloc is missing");
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700349 }
350}
351
352std::string Allocator::dumpDebugInfo() const
353{
354 std::string debugInfo;
355
356 mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) {
357 debugInfo = tmpDebugInfo.c_str();
358 });
359
360 return debugInfo;
361}
362
Marissa Wall1e779252018-12-29 12:01:57 -0800363status_t Allocator::allocate(uint32_t width, uint32_t height, PixelFormat format,
364 uint32_t layerCount, uint64_t usage, uint32_t bufferCount,
365 uint32_t* outStride, buffer_handle_t* outBufferHandles) const {
366 IMapper::BufferDescriptorInfo descriptorInfo = {};
367 descriptorInfo.width = width;
368 descriptorInfo.height = height;
369 descriptorInfo.layerCount = layerCount;
370 descriptorInfo.format = static_cast<hardware::graphics::common::V1_1::PixelFormat>(format);
371 descriptorInfo.usage = usage;
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700372
Marissa Wall1e779252018-12-29 12:01:57 -0800373 BufferDescriptor descriptor;
374 status_t error = mMapper.createDescriptor(static_cast<void*>(&descriptorInfo),
375 static_cast<void*>(&descriptor));
376 if (error != NO_ERROR) {
377 return error;
378 }
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700379
Marissa Wall1e779252018-12-29 12:01:57 -0800380 auto ret = mAllocator->allocate(descriptor, bufferCount,
381 [&](const auto& tmpError, const auto& tmpStride,
382 const auto& tmpBuffers) {
383 error = static_cast<status_t>(tmpError);
384 if (tmpError != Error::NONE) {
385 return;
386 }
387
388 // import buffers
389 for (uint32_t i = 0; i < bufferCount; i++) {
390 error = mMapper.importBuffer(tmpBuffers[i],
391 &outBufferHandles[i]);
392 if (error != NO_ERROR) {
393 for (uint32_t j = 0; j < i; j++) {
394 mMapper.freeBuffer(outBufferHandles[j]);
395 outBufferHandles[j] = nullptr;
396 }
397 return;
398 }
399 }
400
401 *outStride = tmpStride;
402 });
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700403
Chia-I Wud8091b92017-05-16 14:30:34 -0700404 // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now
405 hardware::IPCThreadState::self()->flushCommands();
406
Marissa Wall1e779252018-12-29 12:01:57 -0800407 return (ret.isOk()) ? error : static_cast<status_t>(kTransactionError);
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700408}
409
410} // namespace Gralloc2
411
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700412} // namespace android