blob: bd7c6a1a4615571a7cf755139cdeadf638b1d348 [file] [log] [blame]
Dan Stoza1e2a2a02016-01-11 15:21:07 -08001/*
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#undef LOG_TAG
18#define LOG_TAG "Gralloc1On0Adapter"
19//#define LOG_NDEBUG 0
20
Mathias Agopianfe2f54f2017-02-15 19:48:58 -080021#include <ui/Gralloc1On0Adapter.h>
22
Jesse Hall79927812017-03-23 11:03:23 -070023#include <grallocusage/GrallocUsageConversion.h>
Mathias Agopianfe2f54f2017-02-15 19:48:58 -080024
Dan Stoza1e2a2a02016-01-11 15:21:07 -080025#include <hardware/gralloc.h>
26
Mathias Agopiana9347642017-02-13 16:42:28 -080027#include <ui/GraphicBuffer.h>
Mathias Agopianfe2f54f2017-02-15 19:48:58 -080028#include <ui/Gralloc1.h>
Dan Stoza1e2a2a02016-01-11 15:21:07 -080029
30#include <utils/Log.h>
31
32#include <inttypes.h>
33
34template <typename PFN, typename T>
35static gralloc1_function_pointer_t asFP(T function)
36{
37 static_assert(std::is_same<PFN, T>::value, "Incompatible function pointer");
38 return reinterpret_cast<gralloc1_function_pointer_t>(function);
39}
40
41namespace android {
42
43Gralloc1On0Adapter::Gralloc1On0Adapter(const hw_module_t* module)
44 : mModule(reinterpret_cast<const gralloc_module_t*>(module)),
45 mMinorVersion(mModule->common.module_api_version & 0xFF),
46 mDevice(nullptr)
47{
48 ALOGV("Constructing");
49 getCapabilities = getCapabilitiesHook;
50 getFunction = getFunctionHook;
51 int error = ::gralloc_open(&(mModule->common), &mDevice);
52 if (error) {
53 ALOGE("Failed to open gralloc0 module: %d", error);
54 }
55 ALOGV("Opened gralloc0 device %p", mDevice);
56}
57
58Gralloc1On0Adapter::~Gralloc1On0Adapter()
59{
60 ALOGV("Destructing");
61 if (mDevice) {
62 ALOGV("Closing gralloc0 device %p", mDevice);
63 ::gralloc_close(mDevice);
64 }
65}
66
67void Gralloc1On0Adapter::doGetCapabilities(uint32_t* outCount,
68 int32_t* outCapabilities)
69{
70 if (outCapabilities == nullptr) {
71 *outCount = 1;
72 return;
73 }
74 if (*outCount >= 1) {
75 *outCapabilities = GRALLOC1_CAPABILITY_ON_ADAPTER;
76 *outCount = 1;
77 }
78}
79
80gralloc1_function_pointer_t Gralloc1On0Adapter::doGetFunction(
81 int32_t intDescriptor)
82{
83 constexpr auto lastDescriptor =
84 static_cast<int32_t>(GRALLOC1_LAST_ADAPTER_FUNCTION);
85 if (intDescriptor < 0 || intDescriptor > lastDescriptor) {
86 ALOGE("Invalid function descriptor");
87 return nullptr;
88 }
89
90 auto descriptor =
91 static_cast<gralloc1_function_descriptor_t>(intDescriptor);
92 switch (descriptor) {
93 case GRALLOC1_FUNCTION_DUMP:
94 return asFP<GRALLOC1_PFN_DUMP>(dumpHook);
95 case GRALLOC1_FUNCTION_CREATE_DESCRIPTOR:
96 return asFP<GRALLOC1_PFN_CREATE_DESCRIPTOR>(createDescriptorHook);
97 case GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR:
98 return asFP<GRALLOC1_PFN_DESTROY_DESCRIPTOR>(destroyDescriptorHook);
99 case GRALLOC1_FUNCTION_SET_CONSUMER_USAGE:
100 return asFP<GRALLOC1_PFN_SET_CONSUMER_USAGE>(setConsumerUsageHook);
101 case GRALLOC1_FUNCTION_SET_DIMENSIONS:
102 return asFP<GRALLOC1_PFN_SET_DIMENSIONS>(setDimensionsHook);
103 case GRALLOC1_FUNCTION_SET_FORMAT:
104 return asFP<GRALLOC1_PFN_SET_FORMAT>(setFormatHook);
Craig Donner6ebc46a2016-10-21 15:23:44 -0700105 case GRALLOC1_FUNCTION_SET_LAYER_COUNT:
106 return asFP<GRALLOC1_PFN_SET_LAYER_COUNT>(setLayerCountHook);
Dan Stoza1e2a2a02016-01-11 15:21:07 -0800107 case GRALLOC1_FUNCTION_SET_PRODUCER_USAGE:
108 return asFP<GRALLOC1_PFN_SET_PRODUCER_USAGE>(setProducerUsageHook);
109 case GRALLOC1_FUNCTION_GET_BACKING_STORE:
110 return asFP<GRALLOC1_PFN_GET_BACKING_STORE>(
111 bufferHook<decltype(&Buffer::getBackingStore),
112 &Buffer::getBackingStore, gralloc1_backing_store_t*>);
113 case GRALLOC1_FUNCTION_GET_CONSUMER_USAGE:
114 return asFP<GRALLOC1_PFN_GET_CONSUMER_USAGE>(getConsumerUsageHook);
115 case GRALLOC1_FUNCTION_GET_DIMENSIONS:
116 return asFP<GRALLOC1_PFN_GET_DIMENSIONS>(
117 bufferHook<decltype(&Buffer::getDimensions),
118 &Buffer::getDimensions, uint32_t*, uint32_t*>);
119 case GRALLOC1_FUNCTION_GET_FORMAT:
120 return asFP<GRALLOC1_PFN_GET_FORMAT>(
121 bufferHook<decltype(&Buffer::getFormat),
122 &Buffer::getFormat, int32_t*>);
Craig Donner6ebc46a2016-10-21 15:23:44 -0700123 case GRALLOC1_FUNCTION_GET_LAYER_COUNT:
124 return asFP<GRALLOC1_PFN_GET_LAYER_COUNT>(
125 bufferHook<decltype(&Buffer::getLayerCount),
126 &Buffer::getLayerCount, uint32_t*>);
Dan Stoza1e2a2a02016-01-11 15:21:07 -0800127 case GRALLOC1_FUNCTION_GET_PRODUCER_USAGE:
128 return asFP<GRALLOC1_PFN_GET_PRODUCER_USAGE>(getProducerUsageHook);
129 case GRALLOC1_FUNCTION_GET_STRIDE:
130 return asFP<GRALLOC1_PFN_GET_STRIDE>(
131 bufferHook<decltype(&Buffer::getStride),
132 &Buffer::getStride, uint32_t*>);
133 case GRALLOC1_FUNCTION_ALLOCATE:
134 // Not provided, since we'll use ALLOCATE_WITH_ID
135 return nullptr;
136 case GRALLOC1_FUNCTION_ALLOCATE_WITH_ID:
137 if (mDevice != nullptr) {
138 return asFP<GRALLOC1_PFN_ALLOCATE_WITH_ID>(allocateWithIdHook);
139 } else {
140 return nullptr;
141 }
142 case GRALLOC1_FUNCTION_RETAIN:
143 return asFP<GRALLOC1_PFN_RETAIN>(
144 managementHook<&Gralloc1On0Adapter::retain>);
145 case GRALLOC1_FUNCTION_RELEASE:
146 return asFP<GRALLOC1_PFN_RELEASE>(
147 managementHook<&Gralloc1On0Adapter::release>);
148 case GRALLOC1_FUNCTION_RETAIN_GRAPHIC_BUFFER:
149 return asFP<GRALLOC1_PFN_RETAIN_GRAPHIC_BUFFER>(
150 retainGraphicBufferHook);
151 case GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES:
152 return asFP<GRALLOC1_PFN_GET_NUM_FLEX_PLANES>(
153 bufferHook<decltype(&Buffer::getNumFlexPlanes),
154 &Buffer::getNumFlexPlanes, uint32_t*>);
155 case GRALLOC1_FUNCTION_LOCK:
156 return asFP<GRALLOC1_PFN_LOCK>(
157 lockHook<void*, &Gralloc1On0Adapter::lock>);
158 case GRALLOC1_FUNCTION_LOCK_FLEX:
159 return asFP<GRALLOC1_PFN_LOCK_FLEX>(
160 lockHook<struct android_flex_layout,
161 &Gralloc1On0Adapter::lockFlex>);
162 case GRALLOC1_FUNCTION_LOCK_YCBCR:
163 return asFP<GRALLOC1_PFN_LOCK_YCBCR>(
164 lockHook<struct android_ycbcr,
165 &Gralloc1On0Adapter::lockYCbCr>);
166 case GRALLOC1_FUNCTION_UNLOCK:
167 return asFP<GRALLOC1_PFN_UNLOCK>(unlockHook);
168 case GRALLOC1_FUNCTION_INVALID:
169 ALOGE("Invalid function descriptor");
170 return nullptr;
171 }
172
173 ALOGE("Unknown function descriptor: %d", intDescriptor);
174 return nullptr;
175}
176
177void Gralloc1On0Adapter::dump(uint32_t* outSize, char* outBuffer)
178{
179 ALOGV("dump(%u (%p), %p", outSize ? *outSize : 0, outSize, outBuffer);
180
181 if (!mDevice->dump) {
182 // dump is optional on gralloc0 implementations
183 *outSize = 0;
184 return;
185 }
186
187 if (!outBuffer) {
188 constexpr int32_t BUFFER_LENGTH = 4096;
189 char buffer[BUFFER_LENGTH] = {};
190 mDevice->dump(mDevice, buffer, BUFFER_LENGTH);
191 buffer[BUFFER_LENGTH - 1] = 0; // Ensure the buffer is null-terminated
192 size_t actualLength = std::strlen(buffer);
193 mCachedDump.resize(actualLength);
194 std::copy_n(buffer, actualLength, mCachedDump.begin());
195 *outSize = static_cast<uint32_t>(actualLength);
196 } else {
197 *outSize = std::min(*outSize,
198 static_cast<uint32_t>(mCachedDump.size()));
199 outBuffer = std::copy_n(mCachedDump.cbegin(), *outSize, outBuffer);
200 }
201}
202
203gralloc1_error_t Gralloc1On0Adapter::createDescriptor(
204 gralloc1_buffer_descriptor_t* outDescriptor)
205{
206 auto descriptorId = sNextBufferDescriptorId++;
Dan Stoza923c0662016-06-21 16:22:06 -0700207 std::lock_guard<std::mutex> lock(mDescriptorMutex);
Dan Stoza1e2a2a02016-01-11 15:21:07 -0800208 mDescriptors.emplace(descriptorId,
209 std::make_shared<Descriptor>(this, descriptorId));
210
211 ALOGV("Created descriptor %" PRIu64, descriptorId);
212
213 *outDescriptor = descriptorId;
214 return GRALLOC1_ERROR_NONE;
215}
216
217gralloc1_error_t Gralloc1On0Adapter::destroyDescriptor(
218 gralloc1_buffer_descriptor_t descriptor)
219{
220 ALOGV("Destroying descriptor %" PRIu64, descriptor);
221
Dan Stoza923c0662016-06-21 16:22:06 -0700222 std::lock_guard<std::mutex> lock(mDescriptorMutex);
Dan Stoza1e2a2a02016-01-11 15:21:07 -0800223 if (mDescriptors.count(descriptor) == 0) {
224 return GRALLOC1_ERROR_BAD_DESCRIPTOR;
225 }
226
227 mDescriptors.erase(descriptor);
228 return GRALLOC1_ERROR_NONE;
229}
230
231Gralloc1On0Adapter::Buffer::Buffer(buffer_handle_t handle,
232 gralloc1_backing_store_t store, const Descriptor& descriptor,
233 uint32_t stride, bool wasAllocated)
234 : mHandle(handle),
235 mReferenceCount(1),
236 mStore(store),
237 mDescriptor(descriptor),
238 mStride(stride),
239 mWasAllocated(wasAllocated) {}
240
241gralloc1_error_t Gralloc1On0Adapter::allocate(
242 const std::shared_ptr<Descriptor>& descriptor,
243 gralloc1_backing_store_t store,
244 buffer_handle_t* outBufferHandle)
245{
246 ALOGV("allocate(%" PRIu64 ", %#" PRIx64 ")", descriptor->id, store);
247
248 // If this function is being called, it's because we handed out its function
249 // pointer, which only occurs when mDevice has been loaded successfully and
250 // we are permitted to allocate
251
Jesse Hall79927812017-03-23 11:03:23 -0700252 int usage = android_convertGralloc1To0Usage(descriptor->producerUsage,
253 descriptor->consumerUsage);
Dan Stoza1e2a2a02016-01-11 15:21:07 -0800254 buffer_handle_t handle = nullptr;
255 int stride = 0;
256 ALOGV("Calling alloc(%p, %u, %u, %i, %u)", mDevice, descriptor->width,
257 descriptor->height, descriptor->format, usage);
258 auto error = mDevice->alloc(mDevice,
259 static_cast<int>(descriptor->width),
260 static_cast<int>(descriptor->height), descriptor->format,
261 usage, &handle, &stride);
262 if (error != 0) {
263 ALOGE("gralloc0 allocation failed: %d (%s)", error,
264 strerror(-error));
265 return GRALLOC1_ERROR_NO_RESOURCES;
266 }
267
268 *outBufferHandle = handle;
269 auto buffer = std::make_shared<Buffer>(handle, store, *descriptor, stride,
270 true);
Dan Stoza923c0662016-06-21 16:22:06 -0700271
272 std::lock_guard<std::mutex> lock(mBufferMutex);
Dan Stoza1e2a2a02016-01-11 15:21:07 -0800273 mBuffers.emplace(handle, std::move(buffer));
274
275 return GRALLOC1_ERROR_NONE;
276}
277
278gralloc1_error_t Gralloc1On0Adapter::allocateWithIdHook(
279 gralloc1_device_t* device, gralloc1_buffer_descriptor_t descriptorId,
280 gralloc1_backing_store_t store, buffer_handle_t* outBuffer)
281{
282 auto adapter = getAdapter(device);
283
284 auto descriptor = adapter->getDescriptor(descriptorId);
285 if (!descriptor) {
286 return GRALLOC1_ERROR_BAD_DESCRIPTOR;
287 }
288
289 buffer_handle_t bufferHandle = nullptr;
290 auto error = adapter->allocate(descriptor, store, &bufferHandle);
291 if (error != GRALLOC1_ERROR_NONE) {
292 return error;
293 }
294
295 *outBuffer = bufferHandle;
296 return error;
297}
298
299gralloc1_error_t Gralloc1On0Adapter::retain(
300 const std::shared_ptr<Buffer>& buffer)
301{
Ajit Kumar56ec3af2016-11-25 12:08:53 +0530302 std::lock_guard<std::mutex> lock(mBufferMutex);
Dan Stoza1e2a2a02016-01-11 15:21:07 -0800303 buffer->retain();
304 return GRALLOC1_ERROR_NONE;
305}
306
307gralloc1_error_t Gralloc1On0Adapter::release(
308 const std::shared_ptr<Buffer>& buffer)
309{
Ajit Kumar56ec3af2016-11-25 12:08:53 +0530310 std::lock_guard<std::mutex> lock(mBufferMutex);
Dan Stoza1e2a2a02016-01-11 15:21:07 -0800311 if (!buffer->release()) {
312 return GRALLOC1_ERROR_NONE;
313 }
314
315 buffer_handle_t handle = buffer->getHandle();
316 if (buffer->wasAllocated()) {
317 ALOGV("Calling free(%p)", handle);
318 int result = mDevice->free(mDevice, handle);
319 if (result != 0) {
320 ALOGE("gralloc0 free failed: %d", result);
321 }
322 } else {
323 ALOGV("Calling unregisterBuffer(%p)", handle);
324 int result = mModule->unregisterBuffer(mModule, handle);
325 if (result != 0) {
326 ALOGE("gralloc0 unregister failed: %d", result);
327 }
328 }
Dan Stoza923c0662016-06-21 16:22:06 -0700329
Dan Stoza1e2a2a02016-01-11 15:21:07 -0800330 mBuffers.erase(handle);
331 return GRALLOC1_ERROR_NONE;
332}
333
334gralloc1_error_t Gralloc1On0Adapter::retain(
335 const android::GraphicBuffer* graphicBuffer)
336{
337 ALOGV("retainGraphicBuffer(%p, %#" PRIx64 ")",
338 graphicBuffer->getNativeBuffer()->handle, graphicBuffer->getId());
339
340 buffer_handle_t handle = graphicBuffer->getNativeBuffer()->handle;
Dan Stoza923c0662016-06-21 16:22:06 -0700341 std::lock_guard<std::mutex> lock(mBufferMutex);
Dan Stoza1e2a2a02016-01-11 15:21:07 -0800342 if (mBuffers.count(handle) != 0) {
343 mBuffers[handle]->retain();
344 return GRALLOC1_ERROR_NONE;
345 }
346
347 ALOGV("Calling registerBuffer(%p)", handle);
348 int result = mModule->registerBuffer(mModule, handle);
349 if (result != 0) {
350 ALOGE("gralloc0 register failed: %d", result);
351 return GRALLOC1_ERROR_NO_RESOURCES;
352 }
353
354 Descriptor descriptor{this, sNextBufferDescriptorId++};
355 descriptor.setDimensions(graphicBuffer->getWidth(),
356 graphicBuffer->getHeight());
357 descriptor.setFormat(graphicBuffer->getPixelFormat());
358 descriptor.setProducerUsage(
359 static_cast<gralloc1_producer_usage_t>(graphicBuffer->getUsage()));
360 descriptor.setConsumerUsage(
361 static_cast<gralloc1_consumer_usage_t>(graphicBuffer->getUsage()));
362 auto buffer = std::make_shared<Buffer>(handle,
363 static_cast<gralloc1_backing_store_t>(graphicBuffer->getId()),
364 descriptor, graphicBuffer->getStride(), false);
365 mBuffers.emplace(handle, std::move(buffer));
366 return GRALLOC1_ERROR_NONE;
367}
368
369gralloc1_error_t Gralloc1On0Adapter::lock(
370 const std::shared_ptr<Buffer>& buffer,
371 gralloc1_producer_usage_t producerUsage,
372 gralloc1_consumer_usage_t consumerUsage,
373 const gralloc1_rect_t& accessRegion, void** outData,
374 const sp<Fence>& acquireFence)
375{
376 if (mMinorVersion >= 3) {
377 int result = mModule->lockAsync(mModule, buffer->getHandle(),
Jesse Hall79927812017-03-23 11:03:23 -0700378 android_convertGralloc1To0Usage(producerUsage, consumerUsage),
Dan Stoza1e2a2a02016-01-11 15:21:07 -0800379 accessRegion.left, accessRegion.top, accessRegion.width,
380 accessRegion.height, outData, acquireFence->dup());
381 if (result != 0) {
382 return GRALLOC1_ERROR_UNSUPPORTED;
383 }
384 } else {
385 acquireFence->waitForever("Gralloc1On0Adapter::lock");
386 int result = mModule->lock(mModule, buffer->getHandle(),
Jesse Hall79927812017-03-23 11:03:23 -0700387 android_convertGralloc1To0Usage(producerUsage, consumerUsage),
Dan Stoza1e2a2a02016-01-11 15:21:07 -0800388 accessRegion.left, accessRegion.top, accessRegion.width,
389 accessRegion.height, outData);
390 ALOGV("gralloc0 lock returned %d", result);
391 if (result != 0) {
392 return GRALLOC1_ERROR_UNSUPPORTED;
393 }
394 }
395 return GRALLOC1_ERROR_NONE;
396}
397
398gralloc1_error_t Gralloc1On0Adapter::lockFlex(
399 const std::shared_ptr<Buffer>& /*buffer*/,
400 gralloc1_producer_usage_t /*producerUsage*/,
401 gralloc1_consumer_usage_t /*consumerUsage*/,
402 const gralloc1_rect_t& /*accessRegion*/,
403 struct android_flex_layout* /*outData*/,
404 const sp<Fence>& /*acquireFence*/)
405{
406 // TODO
407 return GRALLOC1_ERROR_UNSUPPORTED;
408}
409
410gralloc1_error_t Gralloc1On0Adapter::lockYCbCr(
411 const std::shared_ptr<Buffer>& buffer,
412 gralloc1_producer_usage_t producerUsage,
413 gralloc1_consumer_usage_t consumerUsage,
414 const gralloc1_rect_t& accessRegion, struct android_ycbcr* outData,
415 const sp<Fence>& acquireFence)
416{
417 if (mMinorVersion >= 3 && mModule->lockAsync_ycbcr) {
418 int result = mModule->lockAsync_ycbcr(mModule, buffer->getHandle(),
Jesse Hall79927812017-03-23 11:03:23 -0700419 android_convertGralloc1To0Usage(producerUsage, consumerUsage),
Dan Stoza1e2a2a02016-01-11 15:21:07 -0800420 accessRegion.left, accessRegion.top, accessRegion.width,
421 accessRegion.height, outData, acquireFence->dup());
422 if (result != 0) {
423 return GRALLOC1_ERROR_UNSUPPORTED;
424 }
425 } else if (mModule->lock_ycbcr) {
426 acquireFence->waitForever("Gralloc1On0Adapter::lockYCbCr");
427 int result = mModule->lock_ycbcr(mModule, buffer->getHandle(),
Jesse Hall79927812017-03-23 11:03:23 -0700428 android_convertGralloc1To0Usage(producerUsage, consumerUsage),
Dan Stoza1e2a2a02016-01-11 15:21:07 -0800429 accessRegion.left, accessRegion.top, accessRegion.width,
430 accessRegion.height, outData);
431 ALOGV("gralloc0 lockYCbCr returned %d", result);
432 if (result != 0) {
433 return GRALLOC1_ERROR_UNSUPPORTED;
434 }
435 } else {
436 return GRALLOC1_ERROR_UNSUPPORTED;
437 }
438
439 return GRALLOC1_ERROR_NONE;
440}
441
442gralloc1_error_t Gralloc1On0Adapter::unlock(
443 const std::shared_ptr<Buffer>& buffer,
444 sp<Fence>* outReleaseFence)
445{
446 if (mMinorVersion >= 3) {
447 int fenceFd = -1;
448 int result = mModule->unlockAsync(mModule, buffer->getHandle(),
449 &fenceFd);
450 if (result != 0) {
451 close(fenceFd);
452 ALOGE("gralloc0 unlockAsync failed: %d", result);
453 } else {
454 *outReleaseFence = new Fence(fenceFd);
455 }
456 } else {
457 int result = mModule->unlock(mModule, buffer->getHandle());
458 if (result != 0) {
459 ALOGE("gralloc0 unlock failed: %d", result);
460 }
461 }
462 return GRALLOC1_ERROR_NONE;
463}
464
465std::shared_ptr<Gralloc1On0Adapter::Descriptor>
466Gralloc1On0Adapter::getDescriptor(gralloc1_buffer_descriptor_t descriptorId)
467{
Dan Stoza923c0662016-06-21 16:22:06 -0700468 std::lock_guard<std::mutex> lock(mDescriptorMutex);
Dan Stoza1e2a2a02016-01-11 15:21:07 -0800469 if (mDescriptors.count(descriptorId) == 0) {
470 return nullptr;
471 }
472
473 return mDescriptors[descriptorId];
474}
475
476std::shared_ptr<Gralloc1On0Adapter::Buffer> Gralloc1On0Adapter::getBuffer(
477 buffer_handle_t bufferHandle)
478{
Dan Stoza923c0662016-06-21 16:22:06 -0700479 std::lock_guard<std::mutex> lock(mBufferMutex);
Dan Stoza1e2a2a02016-01-11 15:21:07 -0800480 if (mBuffers.count(bufferHandle) == 0) {
481 return nullptr;
482 }
483
484 return mBuffers[bufferHandle];
485}
486
487std::atomic<gralloc1_buffer_descriptor_t>
488 Gralloc1On0Adapter::sNextBufferDescriptorId(1);
489
490} // namespace android