blob: 040a62b5426ab4d20514d1b38a2b870922f36e2f [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 Wall925bf7f2018-12-29 14:27:11 -080030using android::hardware::graphics::allocator::V2_0::IAllocator;
Marissa Wall1e779252018-12-29 12:01:57 -080031using android::hardware::graphics::common::V1_1::BufferUsage;
32using android::hardware::graphics::common::V1_1::PixelFormat;
33using android::hardware::graphics::mapper::V2_0::BufferDescriptor;
34using android::hardware::graphics::mapper::V2_0::Error;
35using android::hardware::graphics::mapper::V2_0::YCbCrLayout;
Marissa Wall925bf7f2018-12-29 14:27:11 -080036using android::hardware::graphics::mapper::V2_1::IMapper;
Marissa Wall1e779252018-12-29 12:01:57 -080037
Chia-I Wu5bac7f32017-04-06 12:34:32 -070038namespace android {
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 Walld380e2c2018-12-29 14:17:29 -080068static inline IMapper::Rect sGralloc2Rect(const Rect& rect) {
69 IMapper::Rect outRect{};
Marissa Wall1e779252018-12-29 12:01:57 -080070 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
Marissa Walld380e2c2018-12-29 14:17:29 -080079void Gralloc2Mapper::preload() {
Jesse Hall5dac7812017-07-06 14:02:29 -070080 android::hardware::preloadPassthroughService<hardware::graphics::mapper::V2_0::IMapper>();
81}
82
Marissa Walld380e2c2018-12-29 14:17:29 -080083Gralloc2Mapper::Gralloc2Mapper() {
Chia-I Wu4f55f162018-01-16 21:58:18 -080084 mMapper = hardware::graphics::mapper::V2_0::IMapper::getService();
Chia-I Wudbbe33b2017-09-27 15:22:21 -070085 if (mMapper == nullptr) {
Marissa Wall925bf7f2018-12-29 14:27:11 -080086 ALOGW("mapper 2.x is not supported");
87 return;
Chia-I Wudbbe33b2017-09-27 15:22:21 -070088 }
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
Valerie Hau250c6542019-01-31 14:23:43 -080097bool Gralloc2Mapper::isLoaded() const {
Marissa Wall925bf7f2018-12-29 14:27:11 -080098 return mMapper != nullptr;
99}
100
Marissa Walld380e2c2018-12-29 14:17:29 -0800101status_t Gralloc2Mapper::validateBufferDescriptorInfo(
102 IMapper::BufferDescriptorInfo* descriptorInfo) const {
Craig Donnere6ecb922017-12-27 14:59:29 -0800103 uint64_t validUsageBits = getValid10UsageBits();
104 if (mMapperV2_1 != nullptr) {
105 validUsageBits = validUsageBits | getValid11UsageBits();
106 }
107
Marissa Wall1e779252018-12-29 12:01:57 -0800108 if (descriptorInfo->usage & ~validUsageBits) {
Craig Donnere6ecb922017-12-27 14:59:29 -0800109 ALOGE("buffer descriptor contains invalid usage bits 0x%" PRIx64,
Marissa Wall1e779252018-12-29 12:01:57 -0800110 descriptorInfo->usage & ~validUsageBits);
111 return BAD_VALUE;
Craig Donnere6ecb922017-12-27 14:59:29 -0800112 }
Marissa Wall1e779252018-12-29 12:01:57 -0800113 return NO_ERROR;
Craig Donnere6ecb922017-12-27 14:59:29 -0800114}
115
Marissa Walld380e2c2018-12-29 14:17:29 -0800116status_t Gralloc2Mapper::createDescriptor(void* bufferDescriptorInfo,
117 void* outBufferDescriptor) const {
Marissa Wall1e779252018-12-29 12:01:57 -0800118 IMapper::BufferDescriptorInfo* descriptorInfo =
119 static_cast<IMapper::BufferDescriptorInfo*>(bufferDescriptorInfo);
120 BufferDescriptor* outDescriptor = static_cast<BufferDescriptor*>(outBufferDescriptor);
121
122 status_t status = validateBufferDescriptorInfo(descriptorInfo);
123 if (status != NO_ERROR) {
124 return status;
Craig Donnere6ecb922017-12-27 14:59:29 -0800125 }
126
Marissa Wall1e779252018-12-29 12:01:57 -0800127 Error error;
Chia-I Wu4f55f162018-01-16 21:58:18 -0800128 auto hidl_cb = [&](const auto& tmpError, const auto& tmpDescriptor)
129 {
130 error = tmpError;
131 if (error != Error::NONE) {
132 return;
133 }
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700134
Chia-I Wu4f55f162018-01-16 21:58:18 -0800135 *outDescriptor = tmpDescriptor;
136 };
137
138 hardware::Return<void> ret;
139 if (mMapperV2_1 != nullptr) {
Marissa Wall1e779252018-12-29 12:01:57 -0800140 ret = mMapperV2_1->createDescriptor_2_1(*descriptorInfo, hidl_cb);
Chia-I Wu4f55f162018-01-16 21:58:18 -0800141 } else {
142 const hardware::graphics::mapper::V2_0::IMapper::BufferDescriptorInfo info = {
Marissa Wall1e779252018-12-29 12:01:57 -0800143 descriptorInfo->width,
144 descriptorInfo->height,
145 descriptorInfo->layerCount,
146 static_cast<hardware::graphics::common::V1_0::PixelFormat>(descriptorInfo->format),
147 descriptorInfo->usage,
Chia-I Wu4f55f162018-01-16 21:58:18 -0800148 };
149 ret = mMapper->createDescriptor(info, hidl_cb);
150 }
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700151
Marissa Wall1e779252018-12-29 12:01:57 -0800152 return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700153}
154
Marissa Walld380e2c2018-12-29 14:17:29 -0800155status_t Gralloc2Mapper::importBuffer(const hardware::hidl_handle& rawHandle,
156 buffer_handle_t* outBufferHandle) const {
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700157 Error error;
158 auto ret = mMapper->importBuffer(rawHandle,
159 [&](const auto& tmpError, const auto& tmpBuffer)
160 {
161 error = tmpError;
162 if (error != Error::NONE) {
163 return;
164 }
165
166 *outBufferHandle = static_cast<buffer_handle_t>(tmpBuffer);
167 });
168
Marissa Wall1e779252018-12-29 12:01:57 -0800169 return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700170}
171
Marissa Walld380e2c2018-12-29 14:17:29 -0800172void Gralloc2Mapper::freeBuffer(buffer_handle_t bufferHandle) const {
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700173 auto buffer = const_cast<native_handle_t*>(bufferHandle);
174 auto ret = mMapper->freeBuffer(buffer);
175
176 auto error = (ret.isOk()) ? static_cast<Error>(ret) : kTransactionError;
177 ALOGE_IF(error != Error::NONE, "freeBuffer(%p) failed with %d",
178 buffer, error);
179}
180
Marissa Walld380e2c2018-12-29 14:17:29 -0800181status_t Gralloc2Mapper::validateBufferSize(buffer_handle_t bufferHandle, uint32_t width,
182 uint32_t height, android::PixelFormat format,
183 uint32_t layerCount, uint64_t usage,
184 uint32_t stride) const {
Chia-I Wudbbe33b2017-09-27 15:22:21 -0700185 if (mMapperV2_1 == nullptr) {
Marissa Wall1e779252018-12-29 12:01:57 -0800186 return NO_ERROR;
Chia-I Wudbbe33b2017-09-27 15:22:21 -0700187 }
188
Marissa Wall1e779252018-12-29 12:01:57 -0800189 IMapper::BufferDescriptorInfo descriptorInfo = {};
190 descriptorInfo.width = width;
191 descriptorInfo.height = height;
192 descriptorInfo.layerCount = layerCount;
193 descriptorInfo.format = static_cast<hardware::graphics::common::V1_1::PixelFormat>(format);
194 descriptorInfo.usage = usage;
195
Chia-I Wudbbe33b2017-09-27 15:22:21 -0700196 auto buffer = const_cast<native_handle_t*>(bufferHandle);
197 auto ret = mMapperV2_1->validateBufferSize(buffer, descriptorInfo, stride);
198
Marissa Wall1e779252018-12-29 12:01:57 -0800199 return static_cast<status_t>((ret.isOk()) ? static_cast<Error>(ret) : kTransactionError);
Chia-I Wudbbe33b2017-09-27 15:22:21 -0700200}
201
Marissa Walld380e2c2018-12-29 14:17:29 -0800202void Gralloc2Mapper::getTransportSize(buffer_handle_t bufferHandle, uint32_t* outNumFds,
203 uint32_t* outNumInts) const {
Chia-I Wudbbe33b2017-09-27 15:22:21 -0700204 *outNumFds = uint32_t(bufferHandle->numFds);
205 *outNumInts = uint32_t(bufferHandle->numInts);
206
207 if (mMapperV2_1 == nullptr) {
208 return;
209 }
210
211 Error error;
212 auto buffer = const_cast<native_handle_t*>(bufferHandle);
213 auto ret = mMapperV2_1->getTransportSize(buffer,
214 [&](const auto& tmpError, const auto& tmpNumFds, const auto& tmpNumInts) {
215 error = tmpError;
216 if (error != Error::NONE) {
217 return;
218 }
219
220 *outNumFds = tmpNumFds;
221 *outNumInts = tmpNumInts;
222 });
223
Marissa Wall1e779252018-12-29 12:01:57 -0800224 error = (ret.isOk()) ? error : kTransactionError;
225
226 ALOGE_IF(error != Error::NONE, "getTransportSize(%p) failed with %d", buffer, error);
Chia-I Wudbbe33b2017-09-27 15:22:21 -0700227}
228
Marissa Walld380e2c2018-12-29 14:17:29 -0800229status_t Gralloc2Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
Valerie Hau0c9fc362019-01-22 09:17:19 -0800230 int acquireFence, void** outData, int32_t* outBytesPerPixel,
231 int32_t* outBytesPerStride) const {
232 if (outBytesPerPixel) {
233 *outBytesPerPixel = -1;
234 }
235 if (outBytesPerStride) {
236 *outBytesPerStride = -1;
237 }
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700238 auto buffer = const_cast<native_handle_t*>(bufferHandle);
239
Marissa Wall1e779252018-12-29 12:01:57 -0800240 IMapper::Rect accessRegion = sGralloc2Rect(bounds);
241
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700242 // put acquireFence in a hidl_handle
243 hardware::hidl_handle acquireFenceHandle;
244 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
245 if (acquireFence >= 0) {
246 auto h = native_handle_init(acquireFenceStorage, 1, 0);
247 h->data[0] = acquireFence;
248 acquireFenceHandle = h;
249 }
250
251 Error error;
252 auto ret = mMapper->lock(buffer, usage, accessRegion, acquireFenceHandle,
253 [&](const auto& tmpError, const auto& tmpData)
254 {
255 error = tmpError;
256 if (error != Error::NONE) {
257 return;
258 }
259
260 *outData = tmpData;
261 });
262
263 // we own acquireFence even on errors
264 if (acquireFence >= 0) {
265 close(acquireFence);
266 }
267
Marissa Wall1e779252018-12-29 12:01:57 -0800268 error = (ret.isOk()) ? error : kTransactionError;
269
270 ALOGW_IF(error != Error::NONE, "lock(%p, ...) failed: %d", bufferHandle, error);
271
272 return static_cast<status_t>(error);
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700273}
274
Marissa Walld380e2c2018-12-29 14:17:29 -0800275status_t Gralloc2Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
276 int acquireFence, android_ycbcr* ycbcr) const {
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700277 auto buffer = const_cast<native_handle_t*>(bufferHandle);
278
Marissa Wall1e779252018-12-29 12:01:57 -0800279 IMapper::Rect accessRegion = sGralloc2Rect(bounds);
280
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700281 // put acquireFence in a hidl_handle
282 hardware::hidl_handle acquireFenceHandle;
283 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
284 if (acquireFence >= 0) {
285 auto h = native_handle_init(acquireFenceStorage, 1, 0);
286 h->data[0] = acquireFence;
287 acquireFenceHandle = h;
288 }
289
Marissa Wall1e779252018-12-29 12:01:57 -0800290 YCbCrLayout layout;
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700291 Error error;
292 auto ret = mMapper->lockYCbCr(buffer, usage, accessRegion,
293 acquireFenceHandle,
294 [&](const auto& tmpError, const auto& tmpLayout)
295 {
296 error = tmpError;
297 if (error != Error::NONE) {
298 return;
299 }
300
Marissa Wall1e779252018-12-29 12:01:57 -0800301 layout = tmpLayout;
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700302 });
303
Marissa Wall1e779252018-12-29 12:01:57 -0800304 if (error == Error::NONE) {
305 ycbcr->y = layout.y;
306 ycbcr->cb = layout.cb;
307 ycbcr->cr = layout.cr;
308 ycbcr->ystride = static_cast<size_t>(layout.yStride);
309 ycbcr->cstride = static_cast<size_t>(layout.cStride);
310 ycbcr->chroma_step = static_cast<size_t>(layout.chromaStep);
311 }
312
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700313 // we own acquireFence even on errors
314 if (acquireFence >= 0) {
315 close(acquireFence);
316 }
317
Marissa Wall1e779252018-12-29 12:01:57 -0800318 return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700319}
320
Marissa Walld380e2c2018-12-29 14:17:29 -0800321int Gralloc2Mapper::unlock(buffer_handle_t bufferHandle) const {
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700322 auto buffer = const_cast<native_handle_t*>(bufferHandle);
323
324 int releaseFence = -1;
325 Error error;
326 auto ret = mMapper->unlock(buffer,
327 [&](const auto& tmpError, const auto& tmpReleaseFence)
328 {
329 error = tmpError;
330 if (error != Error::NONE) {
331 return;
332 }
333
334 auto fenceHandle = tmpReleaseFence.getNativeHandle();
335 if (fenceHandle && fenceHandle->numFds == 1) {
336 int fd = dup(fenceHandle->data[0]);
337 if (fd >= 0) {
338 releaseFence = fd;
339 } else {
340 ALOGD("failed to dup unlock release fence");
341 sync_wait(fenceHandle->data[0], -1);
342 }
343 }
344 });
345
Marissa Wall1e779252018-12-29 12:01:57 -0800346 error = (ret.isOk()) ? error : kTransactionError;
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700347 if (error != Error::NONE) {
348 ALOGE("unlock(%p) failed with %d", buffer, error);
349 }
350
351 return releaseFence;
352}
353
Marissa Walld380e2c2018-12-29 14:17:29 -0800354Gralloc2Allocator::Gralloc2Allocator(const Gralloc2Mapper& mapper) : mMapper(mapper) {
Chia-I Wucb8405e2017-04-17 15:20:19 -0700355 mAllocator = IAllocator::getService();
356 if (mAllocator == nullptr) {
Marissa Wall925bf7f2018-12-29 14:27:11 -0800357 ALOGW("allocator 2.x is not supported");
358 return;
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700359 }
360}
361
Valerie Hau250c6542019-01-31 14:23:43 -0800362bool Gralloc2Allocator::isLoaded() const {
Marissa Wall925bf7f2018-12-29 14:27:11 -0800363 return mAllocator != nullptr;
364}
365
Marissa Wall22b2de12019-12-02 18:11:43 -0800366std::string Gralloc2Allocator::dumpDebugInfo(bool /*less*/) const {
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700367 std::string debugInfo;
368
369 mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) {
370 debugInfo = tmpDebugInfo.c_str();
371 });
372
373 return debugInfo;
374}
375
Marissa Wall22b2de12019-12-02 18:11:43 -0800376status_t Gralloc2Allocator::allocate(std::string /*requestorName*/, uint32_t width, uint32_t height,
377 PixelFormat format, uint32_t layerCount, uint64_t usage,
378 uint32_t bufferCount, uint32_t* outStride,
379 buffer_handle_t* outBufferHandles, bool importBuffers) const {
Marissa Wall1e779252018-12-29 12:01:57 -0800380 IMapper::BufferDescriptorInfo descriptorInfo = {};
381 descriptorInfo.width = width;
382 descriptorInfo.height = height;
383 descriptorInfo.layerCount = layerCount;
384 descriptorInfo.format = static_cast<hardware::graphics::common::V1_1::PixelFormat>(format);
385 descriptorInfo.usage = usage;
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700386
Marissa Wall1e779252018-12-29 12:01:57 -0800387 BufferDescriptor descriptor;
388 status_t error = mMapper.createDescriptor(static_cast<void*>(&descriptorInfo),
389 static_cast<void*>(&descriptor));
390 if (error != NO_ERROR) {
391 return error;
392 }
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700393
Marissa Wall1e779252018-12-29 12:01:57 -0800394 auto ret = mAllocator->allocate(descriptor, bufferCount,
395 [&](const auto& tmpError, const auto& tmpStride,
396 const auto& tmpBuffers) {
397 error = static_cast<status_t>(tmpError);
398 if (tmpError != Error::NONE) {
399 return;
400 }
401
Marissa Wallbfcf81f2019-11-27 10:36:29 -0800402 if (importBuffers) {
403 for (uint32_t i = 0; i < bufferCount; i++) {
404 error = mMapper.importBuffer(tmpBuffers[i],
405 &outBufferHandles[i]);
406 if (error != NO_ERROR) {
407 for (uint32_t j = 0; j < i; j++) {
408 mMapper.freeBuffer(outBufferHandles[j]);
409 outBufferHandles[j] = nullptr;
410 }
411 return;
Marissa Wall1e779252018-12-29 12:01:57 -0800412 }
Marissa Wallbfcf81f2019-11-27 10:36:29 -0800413 }
414 } else {
415 for (uint32_t i = 0; i < bufferCount; i++) {
416 outBufferHandles[i] = native_handle_clone(
417 tmpBuffers[i].getNativeHandle());
418 if (!outBufferHandles[i]) {
419 for (uint32_t j = 0; j < i; j++) {
420 auto buffer = const_cast<native_handle_t*>(
421 outBufferHandles[j]);
422 native_handle_close(buffer);
423 native_handle_delete(buffer);
424 outBufferHandles[j] = nullptr;
425 }
426 }
Marissa Wall1e779252018-12-29 12:01:57 -0800427 }
428 }
Marissa Wall1e779252018-12-29 12:01:57 -0800429 *outStride = tmpStride;
430 });
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700431
Chia-I Wud8091b92017-05-16 14:30:34 -0700432 // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now
433 hardware::IPCThreadState::self()->flushCommands();
434
Marissa Wall1e779252018-12-29 12:01:57 -0800435 return (ret.isOk()) ? error : static_cast<status_t>(kTransactionError);
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700436}
437
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700438} // namespace android