blob: c2f07326a11ace730fd8101591250f85c1af0419 [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
Craig Donnere6ecb922017-12-27 14:59:29 -080038namespace {
39
Chia-I Wu5bac7f32017-04-06 12:34:32 -070040static constexpr Error kTransactionError = Error::NO_RESOURCES;
41
Craig Donnere6ecb922017-12-27 14:59:29 -080042uint64_t getValid10UsageBits() {
43 static const uint64_t valid10UsageBits = []() -> uint64_t {
44 using hardware::graphics::common::V1_0::BufferUsage;
45 uint64_t bits = 0;
Steven Moreland3cde8752018-05-01 16:54:17 -070046 for (const auto bit : hardware::hidl_enum_range<BufferUsage>()) {
Craig Donnere6ecb922017-12-27 14:59:29 -080047 bits = bits | bit;
48 }
Craig Donnere6ecb922017-12-27 14:59:29 -080049 return bits;
50 }();
51 return valid10UsageBits;
52}
53
54uint64_t getValid11UsageBits() {
55 static const uint64_t valid11UsageBits = []() -> uint64_t {
56 using hardware::graphics::common::V1_1::BufferUsage;
57 uint64_t bits = 0;
Steven Moreland3cde8752018-05-01 16:54:17 -070058 for (const auto bit : hardware::hidl_enum_range<BufferUsage>()) {
Craig Donnere6ecb922017-12-27 14:59:29 -080059 bits = bits | bit;
60 }
Chia-I Wu4f55f162018-01-16 21:58:18 -080061 return bits;
Craig Donnere6ecb922017-12-27 14:59:29 -080062 }();
63 return valid11UsageBits;
64}
65
Marissa Walld380e2c2018-12-29 14:17:29 -080066static inline IMapper::Rect sGralloc2Rect(const Rect& rect) {
67 IMapper::Rect outRect{};
Marissa Wall1e779252018-12-29 12:01:57 -080068 outRect.left = rect.left;
69 outRect.top = rect.top;
70 outRect.width = rect.width();
71 outRect.height = rect.height();
72 return outRect;
73}
74
Craig Donnere6ecb922017-12-27 14:59:29 -080075} // anonymous namespace
76
Marissa Walld380e2c2018-12-29 14:17:29 -080077void Gralloc2Mapper::preload() {
Jesse Hall5dac7812017-07-06 14:02:29 -070078 android::hardware::preloadPassthroughService<hardware::graphics::mapper::V2_0::IMapper>();
79}
80
Marissa Walld380e2c2018-12-29 14:17:29 -080081Gralloc2Mapper::Gralloc2Mapper() {
Chia-I Wu4f55f162018-01-16 21:58:18 -080082 mMapper = hardware::graphics::mapper::V2_0::IMapper::getService();
Chia-I Wudbbe33b2017-09-27 15:22:21 -070083 if (mMapper == nullptr) {
84 LOG_ALWAYS_FATAL("gralloc-mapper is missing");
85 }
86 if (mMapper->isRemote()) {
Chia-I Wu5bac7f32017-04-06 12:34:32 -070087 LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode");
88 }
Chia-I Wudbbe33b2017-09-27 15:22:21 -070089
90 // IMapper 2.1 is optional
Chia-I Wu4f55f162018-01-16 21:58:18 -080091 mMapperV2_1 = IMapper::castFrom(mMapper);
Chia-I Wu5bac7f32017-04-06 12:34:32 -070092}
93
Marissa Walld380e2c2018-12-29 14:17:29 -080094status_t Gralloc2Mapper::validateBufferDescriptorInfo(
95 IMapper::BufferDescriptorInfo* descriptorInfo) const {
Craig Donnere6ecb922017-12-27 14:59:29 -080096 uint64_t validUsageBits = getValid10UsageBits();
97 if (mMapperV2_1 != nullptr) {
98 validUsageBits = validUsageBits | getValid11UsageBits();
99 }
100
Marissa Wall1e779252018-12-29 12:01:57 -0800101 if (descriptorInfo->usage & ~validUsageBits) {
Craig Donnere6ecb922017-12-27 14:59:29 -0800102 ALOGE("buffer descriptor contains invalid usage bits 0x%" PRIx64,
Marissa Wall1e779252018-12-29 12:01:57 -0800103 descriptorInfo->usage & ~validUsageBits);
104 return BAD_VALUE;
Craig Donnere6ecb922017-12-27 14:59:29 -0800105 }
Marissa Wall1e779252018-12-29 12:01:57 -0800106 return NO_ERROR;
Craig Donnere6ecb922017-12-27 14:59:29 -0800107}
108
Marissa Walld380e2c2018-12-29 14:17:29 -0800109status_t Gralloc2Mapper::createDescriptor(void* bufferDescriptorInfo,
110 void* outBufferDescriptor) const {
Marissa Wall1e779252018-12-29 12:01:57 -0800111 IMapper::BufferDescriptorInfo* descriptorInfo =
112 static_cast<IMapper::BufferDescriptorInfo*>(bufferDescriptorInfo);
113 BufferDescriptor* outDescriptor = static_cast<BufferDescriptor*>(outBufferDescriptor);
114
115 status_t status = validateBufferDescriptorInfo(descriptorInfo);
116 if (status != NO_ERROR) {
117 return status;
Craig Donnere6ecb922017-12-27 14:59:29 -0800118 }
119
Marissa Wall1e779252018-12-29 12:01:57 -0800120 Error error;
Chia-I Wu4f55f162018-01-16 21:58:18 -0800121 auto hidl_cb = [&](const auto& tmpError, const auto& tmpDescriptor)
122 {
123 error = tmpError;
124 if (error != Error::NONE) {
125 return;
126 }
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700127
Chia-I Wu4f55f162018-01-16 21:58:18 -0800128 *outDescriptor = tmpDescriptor;
129 };
130
131 hardware::Return<void> ret;
132 if (mMapperV2_1 != nullptr) {
Marissa Wall1e779252018-12-29 12:01:57 -0800133 ret = mMapperV2_1->createDescriptor_2_1(*descriptorInfo, hidl_cb);
Chia-I Wu4f55f162018-01-16 21:58:18 -0800134 } else {
135 const hardware::graphics::mapper::V2_0::IMapper::BufferDescriptorInfo info = {
Marissa Wall1e779252018-12-29 12:01:57 -0800136 descriptorInfo->width,
137 descriptorInfo->height,
138 descriptorInfo->layerCount,
139 static_cast<hardware::graphics::common::V1_0::PixelFormat>(descriptorInfo->format),
140 descriptorInfo->usage,
Chia-I Wu4f55f162018-01-16 21:58:18 -0800141 };
142 ret = mMapper->createDescriptor(info, hidl_cb);
143 }
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700144
Marissa Wall1e779252018-12-29 12:01:57 -0800145 return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700146}
147
Marissa Walld380e2c2018-12-29 14:17:29 -0800148status_t Gralloc2Mapper::importBuffer(const hardware::hidl_handle& rawHandle,
149 buffer_handle_t* outBufferHandle) const {
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700150 Error error;
151 auto ret = mMapper->importBuffer(rawHandle,
152 [&](const auto& tmpError, const auto& tmpBuffer)
153 {
154 error = tmpError;
155 if (error != Error::NONE) {
156 return;
157 }
158
159 *outBufferHandle = static_cast<buffer_handle_t>(tmpBuffer);
160 });
161
Marissa Wall1e779252018-12-29 12:01:57 -0800162 return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700163}
164
Marissa Walld380e2c2018-12-29 14:17:29 -0800165void Gralloc2Mapper::freeBuffer(buffer_handle_t bufferHandle) const {
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700166 auto buffer = const_cast<native_handle_t*>(bufferHandle);
167 auto ret = mMapper->freeBuffer(buffer);
168
169 auto error = (ret.isOk()) ? static_cast<Error>(ret) : kTransactionError;
170 ALOGE_IF(error != Error::NONE, "freeBuffer(%p) failed with %d",
171 buffer, error);
172}
173
Marissa Walld380e2c2018-12-29 14:17:29 -0800174status_t Gralloc2Mapper::validateBufferSize(buffer_handle_t bufferHandle, uint32_t width,
175 uint32_t height, android::PixelFormat format,
176 uint32_t layerCount, uint64_t usage,
177 uint32_t stride) const {
Chia-I Wudbbe33b2017-09-27 15:22:21 -0700178 if (mMapperV2_1 == nullptr) {
Marissa Wall1e779252018-12-29 12:01:57 -0800179 return NO_ERROR;
Chia-I Wudbbe33b2017-09-27 15:22:21 -0700180 }
181
Marissa Wall1e779252018-12-29 12:01:57 -0800182 IMapper::BufferDescriptorInfo descriptorInfo = {};
183 descriptorInfo.width = width;
184 descriptorInfo.height = height;
185 descriptorInfo.layerCount = layerCount;
186 descriptorInfo.format = static_cast<hardware::graphics::common::V1_1::PixelFormat>(format);
187 descriptorInfo.usage = usage;
188
Chia-I Wudbbe33b2017-09-27 15:22:21 -0700189 auto buffer = const_cast<native_handle_t*>(bufferHandle);
190 auto ret = mMapperV2_1->validateBufferSize(buffer, descriptorInfo, stride);
191
Marissa Wall1e779252018-12-29 12:01:57 -0800192 return static_cast<status_t>((ret.isOk()) ? static_cast<Error>(ret) : kTransactionError);
Chia-I Wudbbe33b2017-09-27 15:22:21 -0700193}
194
Marissa Walld380e2c2018-12-29 14:17:29 -0800195void Gralloc2Mapper::getTransportSize(buffer_handle_t bufferHandle, uint32_t* outNumFds,
196 uint32_t* outNumInts) const {
Chia-I Wudbbe33b2017-09-27 15:22:21 -0700197 *outNumFds = uint32_t(bufferHandle->numFds);
198 *outNumInts = uint32_t(bufferHandle->numInts);
199
200 if (mMapperV2_1 == nullptr) {
201 return;
202 }
203
204 Error error;
205 auto buffer = const_cast<native_handle_t*>(bufferHandle);
206 auto ret = mMapperV2_1->getTransportSize(buffer,
207 [&](const auto& tmpError, const auto& tmpNumFds, const auto& tmpNumInts) {
208 error = tmpError;
209 if (error != Error::NONE) {
210 return;
211 }
212
213 *outNumFds = tmpNumFds;
214 *outNumInts = tmpNumInts;
215 });
216
Marissa Wall1e779252018-12-29 12:01:57 -0800217 error = (ret.isOk()) ? error : kTransactionError;
218
219 ALOGE_IF(error != Error::NONE, "getTransportSize(%p) failed with %d", buffer, error);
Chia-I Wudbbe33b2017-09-27 15:22:21 -0700220}
221
Marissa Walld380e2c2018-12-29 14:17:29 -0800222status_t Gralloc2Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
223 int acquireFence, void** outData) const {
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700224 auto buffer = const_cast<native_handle_t*>(bufferHandle);
225
Marissa Wall1e779252018-12-29 12:01:57 -0800226 IMapper::Rect accessRegion = sGralloc2Rect(bounds);
227
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700228 // put acquireFence in a hidl_handle
229 hardware::hidl_handle acquireFenceHandle;
230 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
231 if (acquireFence >= 0) {
232 auto h = native_handle_init(acquireFenceStorage, 1, 0);
233 h->data[0] = acquireFence;
234 acquireFenceHandle = h;
235 }
236
237 Error error;
238 auto ret = mMapper->lock(buffer, usage, accessRegion, acquireFenceHandle,
239 [&](const auto& tmpError, const auto& tmpData)
240 {
241 error = tmpError;
242 if (error != Error::NONE) {
243 return;
244 }
245
246 *outData = tmpData;
247 });
248
249 // we own acquireFence even on errors
250 if (acquireFence >= 0) {
251 close(acquireFence);
252 }
253
Marissa Wall1e779252018-12-29 12:01:57 -0800254 error = (ret.isOk()) ? error : kTransactionError;
255
256 ALOGW_IF(error != Error::NONE, "lock(%p, ...) failed: %d", bufferHandle, error);
257
258 return static_cast<status_t>(error);
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700259}
260
Marissa Walld380e2c2018-12-29 14:17:29 -0800261status_t Gralloc2Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
262 int acquireFence, android_ycbcr* ycbcr) const {
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700263 auto buffer = const_cast<native_handle_t*>(bufferHandle);
264
Marissa Wall1e779252018-12-29 12:01:57 -0800265 IMapper::Rect accessRegion = sGralloc2Rect(bounds);
266
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700267 // put acquireFence in a hidl_handle
268 hardware::hidl_handle acquireFenceHandle;
269 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
270 if (acquireFence >= 0) {
271 auto h = native_handle_init(acquireFenceStorage, 1, 0);
272 h->data[0] = acquireFence;
273 acquireFenceHandle = h;
274 }
275
Marissa Wall1e779252018-12-29 12:01:57 -0800276 YCbCrLayout layout;
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700277 Error error;
278 auto ret = mMapper->lockYCbCr(buffer, usage, accessRegion,
279 acquireFenceHandle,
280 [&](const auto& tmpError, const auto& tmpLayout)
281 {
282 error = tmpError;
283 if (error != Error::NONE) {
284 return;
285 }
286
Marissa Wall1e779252018-12-29 12:01:57 -0800287 layout = tmpLayout;
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700288 });
289
Marissa Wall1e779252018-12-29 12:01:57 -0800290 if (error == Error::NONE) {
291 ycbcr->y = layout.y;
292 ycbcr->cb = layout.cb;
293 ycbcr->cr = layout.cr;
294 ycbcr->ystride = static_cast<size_t>(layout.yStride);
295 ycbcr->cstride = static_cast<size_t>(layout.cStride);
296 ycbcr->chroma_step = static_cast<size_t>(layout.chromaStep);
297 }
298
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700299 // we own acquireFence even on errors
300 if (acquireFence >= 0) {
301 close(acquireFence);
302 }
303
Marissa Wall1e779252018-12-29 12:01:57 -0800304 return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700305}
306
Marissa Walld380e2c2018-12-29 14:17:29 -0800307int Gralloc2Mapper::unlock(buffer_handle_t bufferHandle) const {
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700308 auto buffer = const_cast<native_handle_t*>(bufferHandle);
309
310 int releaseFence = -1;
311 Error error;
312 auto ret = mMapper->unlock(buffer,
313 [&](const auto& tmpError, const auto& tmpReleaseFence)
314 {
315 error = tmpError;
316 if (error != Error::NONE) {
317 return;
318 }
319
320 auto fenceHandle = tmpReleaseFence.getNativeHandle();
321 if (fenceHandle && fenceHandle->numFds == 1) {
322 int fd = dup(fenceHandle->data[0]);
323 if (fd >= 0) {
324 releaseFence = fd;
325 } else {
326 ALOGD("failed to dup unlock release fence");
327 sync_wait(fenceHandle->data[0], -1);
328 }
329 }
330 });
331
Marissa Wall1e779252018-12-29 12:01:57 -0800332 error = (ret.isOk()) ? error : kTransactionError;
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700333 if (error != Error::NONE) {
334 ALOGE("unlock(%p) failed with %d", buffer, error);
335 }
336
337 return releaseFence;
338}
339
Marissa Walld380e2c2018-12-29 14:17:29 -0800340Gralloc2Allocator::Gralloc2Allocator(const Gralloc2Mapper& mapper) : mMapper(mapper) {
Chia-I Wucb8405e2017-04-17 15:20:19 -0700341 mAllocator = IAllocator::getService();
342 if (mAllocator == nullptr) {
343 LOG_ALWAYS_FATAL("gralloc-alloc is missing");
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700344 }
345}
346
Marissa Walld380e2c2018-12-29 14:17:29 -0800347std::string Gralloc2Allocator::dumpDebugInfo() const {
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700348 std::string debugInfo;
349
350 mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) {
351 debugInfo = tmpDebugInfo.c_str();
352 });
353
354 return debugInfo;
355}
356
Marissa Walld380e2c2018-12-29 14:17:29 -0800357status_t Gralloc2Allocator::allocate(uint32_t width, uint32_t height, PixelFormat format,
358 uint32_t layerCount, uint64_t usage, uint32_t bufferCount,
359 uint32_t* outStride, buffer_handle_t* outBufferHandles) const {
Marissa Wall1e779252018-12-29 12:01:57 -0800360 IMapper::BufferDescriptorInfo descriptorInfo = {};
361 descriptorInfo.width = width;
362 descriptorInfo.height = height;
363 descriptorInfo.layerCount = layerCount;
364 descriptorInfo.format = static_cast<hardware::graphics::common::V1_1::PixelFormat>(format);
365 descriptorInfo.usage = usage;
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700366
Marissa Wall1e779252018-12-29 12:01:57 -0800367 BufferDescriptor descriptor;
368 status_t error = mMapper.createDescriptor(static_cast<void*>(&descriptorInfo),
369 static_cast<void*>(&descriptor));
370 if (error != NO_ERROR) {
371 return error;
372 }
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700373
Marissa Wall1e779252018-12-29 12:01:57 -0800374 auto ret = mAllocator->allocate(descriptor, bufferCount,
375 [&](const auto& tmpError, const auto& tmpStride,
376 const auto& tmpBuffers) {
377 error = static_cast<status_t>(tmpError);
378 if (tmpError != Error::NONE) {
379 return;
380 }
381
382 // import buffers
383 for (uint32_t i = 0; i < bufferCount; i++) {
384 error = mMapper.importBuffer(tmpBuffers[i],
385 &outBufferHandles[i]);
386 if (error != NO_ERROR) {
387 for (uint32_t j = 0; j < i; j++) {
388 mMapper.freeBuffer(outBufferHandles[j]);
389 outBufferHandles[j] = nullptr;
390 }
391 return;
392 }
393 }
394
395 *outStride = tmpStride;
396 });
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700397
Chia-I Wud8091b92017-05-16 14:30:34 -0700398 // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now
399 hardware::IPCThreadState::self()->flushCommands();
400
Marissa Wall1e779252018-12-29 12:01:57 -0800401 return (ret.isOk()) ? error : static_cast<status_t>(kTransactionError);
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700402}
403
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700404} // namespace android