1/*
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
21#include "Gralloc1On0Adapter.h"
22#include "gralloc1-adapter.h"
23
24#include <grallocusage/GrallocUsageConversion.h>
25
26#include <hardware/gralloc.h>
27
28#include <log/log.h>
29#include <sync/sync.h>
30
31#include <inttypes.h>
32
33template <typename PFN, typename T>
34static gralloc1_function_pointer_t asFP(T function)
35{
36    static_assert(std::is_same<PFN, T>::value, "Incompatible function pointer");
37    return reinterpret_cast<gralloc1_function_pointer_t>(function);
38}
39
40namespace android {
41namespace hardware {
42
43Gralloc1On0Adapter::Gralloc1On0Adapter(const hw_module_t* module)
44  : gralloc1_device_t(),
45    mModule(reinterpret_cast<const gralloc_module_t*>(module)),
46    mDevice(nullptr)
47{
48    ALOGV("Constructing");
49
50    int minor = 0;
51    mModule->perform(mModule,
52            GRALLOC1_ADAPTER_PERFORM_GET_REAL_MODULE_API_VERSION_MINOR,
53            &minor);
54    mMinorVersion = minor;
55
56    common.tag = HARDWARE_DEVICE_TAG,
57    common.version = HARDWARE_DEVICE_API_VERSION(0, 0),
58    common.module = const_cast<struct hw_module_t*>(module),
59    common.close = closeHook,
60
61    getCapabilities = getCapabilitiesHook;
62    getFunction = getFunctionHook;
63    int error = ::gralloc_open(&(mModule->common), &mDevice);
64    if (error) {
65        ALOGE("Failed to open gralloc0 module: %d", error);
66    }
67    ALOGV("Opened gralloc0 device %p", mDevice);
68}
69
70Gralloc1On0Adapter::~Gralloc1On0Adapter()
71{
72    ALOGV("Destructing");
73    if (mDevice) {
74        ALOGV("Closing gralloc0 device %p", mDevice);
75        ::gralloc_close(mDevice);
76    }
77}
78
79void Gralloc1On0Adapter::doGetCapabilities(uint32_t* outCount,
80                                           int32_t* /*outCapabilities*/) {
81    *outCount = 0;
82}
83
84gralloc1_function_pointer_t Gralloc1On0Adapter::doGetFunction(
85        int32_t intDescriptor)
86{
87    constexpr auto lastDescriptor =
88            static_cast<int32_t>(GRALLOC1_LAST_FUNCTION);
89    if (intDescriptor < 0 || intDescriptor > lastDescriptor) {
90        ALOGE("Invalid function descriptor");
91        return nullptr;
92    }
93
94    auto descriptor =
95            static_cast<gralloc1_function_descriptor_t>(intDescriptor);
96    switch (descriptor) {
97        case GRALLOC1_FUNCTION_DUMP:
98            return asFP<GRALLOC1_PFN_DUMP>(dumpHook);
99        case GRALLOC1_FUNCTION_CREATE_DESCRIPTOR:
100            return asFP<GRALLOC1_PFN_CREATE_DESCRIPTOR>(createDescriptorHook);
101        case GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR:
102            return asFP<GRALLOC1_PFN_DESTROY_DESCRIPTOR>(destroyDescriptorHook);
103        case GRALLOC1_FUNCTION_SET_CONSUMER_USAGE:
104            return asFP<GRALLOC1_PFN_SET_CONSUMER_USAGE>(setConsumerUsageHook);
105        case GRALLOC1_FUNCTION_SET_DIMENSIONS:
106            return asFP<GRALLOC1_PFN_SET_DIMENSIONS>(setDimensionsHook);
107        case GRALLOC1_FUNCTION_SET_FORMAT:
108            return asFP<GRALLOC1_PFN_SET_FORMAT>(setFormatHook);
109        case GRALLOC1_FUNCTION_SET_LAYER_COUNT:
110            return asFP<GRALLOC1_PFN_SET_LAYER_COUNT>(setLayerCountHook);
111        case GRALLOC1_FUNCTION_SET_PRODUCER_USAGE:
112            return asFP<GRALLOC1_PFN_SET_PRODUCER_USAGE>(setProducerUsageHook);
113        case GRALLOC1_FUNCTION_GET_BACKING_STORE:
114            return asFP<GRALLOC1_PFN_GET_BACKING_STORE>(
115                    bufferHook<decltype(&Buffer::getBackingStore),
116                    &Buffer::getBackingStore, gralloc1_backing_store_t*>);
117        case GRALLOC1_FUNCTION_GET_CONSUMER_USAGE:
118            return asFP<GRALLOC1_PFN_GET_CONSUMER_USAGE>(getConsumerUsageHook);
119        case GRALLOC1_FUNCTION_GET_DIMENSIONS:
120            return asFP<GRALLOC1_PFN_GET_DIMENSIONS>(
121                    bufferHook<decltype(&Buffer::getDimensions),
122                    &Buffer::getDimensions, uint32_t*, uint32_t*>);
123        case GRALLOC1_FUNCTION_GET_FORMAT:
124            return asFP<GRALLOC1_PFN_GET_FORMAT>(
125                    bufferHook<decltype(&Buffer::getFormat),
126                    &Buffer::getFormat, int32_t*>);
127        case GRALLOC1_FUNCTION_GET_LAYER_COUNT:
128            return asFP<GRALLOC1_PFN_GET_LAYER_COUNT>(
129                    bufferHook<decltype(&Buffer::getLayerCount),
130                    &Buffer::getLayerCount, uint32_t*>);
131        case GRALLOC1_FUNCTION_GET_PRODUCER_USAGE:
132            return asFP<GRALLOC1_PFN_GET_PRODUCER_USAGE>(getProducerUsageHook);
133        case GRALLOC1_FUNCTION_GET_STRIDE:
134            return asFP<GRALLOC1_PFN_GET_STRIDE>(
135                    bufferHook<decltype(&Buffer::getStride),
136                    &Buffer::getStride, uint32_t*>);
137        case GRALLOC1_FUNCTION_ALLOCATE:
138            if (mDevice != nullptr) {
139                return asFP<GRALLOC1_PFN_ALLOCATE>(allocateHook);
140            } else {
141                return nullptr;
142            }
143        case GRALLOC1_FUNCTION_RETAIN:
144            return asFP<GRALLOC1_PFN_RETAIN>(retainHook);
145        case GRALLOC1_FUNCTION_RELEASE:
146            return asFP<GRALLOC1_PFN_RELEASE>(releaseHook);
147        case GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES:
148            return asFP<GRALLOC1_PFN_GET_NUM_FLEX_PLANES>(
149                    bufferHook<decltype(&Buffer::getNumFlexPlanes),
150                    &Buffer::getNumFlexPlanes, uint32_t*>);
151        case GRALLOC1_FUNCTION_LOCK:
152            return asFP<GRALLOC1_PFN_LOCK>(
153                    lockHook<void*, &Gralloc1On0Adapter::lock>);
154        case GRALLOC1_FUNCTION_LOCK_FLEX:
155            return asFP<GRALLOC1_PFN_LOCK_FLEX>(
156                    lockHook<struct android_flex_layout,
157                    &Gralloc1On0Adapter::lockFlex>);
158        case GRALLOC1_FUNCTION_UNLOCK:
159            return asFP<GRALLOC1_PFN_UNLOCK>(unlockHook);
160        case GRALLOC1_FUNCTION_INVALID:
161            ALOGE("Invalid function descriptor");
162            return nullptr;
163    }
164
165    ALOGE("Unknown function descriptor: %d", intDescriptor);
166    return nullptr;
167}
168
169void Gralloc1On0Adapter::dump(uint32_t* outSize, char* outBuffer)
170{
171    ALOGV("dump(%u (%p), %p", outSize ? *outSize : 0, outSize, outBuffer);
172
173    if (!mDevice->dump) {
174        // dump is optional on gralloc0 implementations
175        *outSize = 0;
176        return;
177    }
178
179    if (!outBuffer) {
180        constexpr int32_t BUFFER_LENGTH = 4096;
181        char buffer[BUFFER_LENGTH] = {};
182        mDevice->dump(mDevice, buffer, BUFFER_LENGTH);
183        buffer[BUFFER_LENGTH - 1] = 0; // Ensure the buffer is null-terminated
184        size_t actualLength = std::strlen(buffer);
185        mCachedDump.resize(actualLength);
186        std::copy_n(buffer, actualLength, mCachedDump.begin());
187        *outSize = static_cast<uint32_t>(actualLength);
188    } else {
189        *outSize = std::min(*outSize,
190                static_cast<uint32_t>(mCachedDump.size()));
191        outBuffer = std::copy_n(mCachedDump.cbegin(), *outSize, outBuffer);
192    }
193}
194
195gralloc1_error_t Gralloc1On0Adapter::createDescriptor(
196        gralloc1_buffer_descriptor_t* outDescriptor)
197{
198    auto descriptorId = sNextBufferDescriptorId++;
199    std::lock_guard<std::mutex> lock(mDescriptorMutex);
200    mDescriptors.emplace(descriptorId, std::make_shared<Descriptor>());
201
202    ALOGV("Created descriptor %" PRIu64, descriptorId);
203
204    *outDescriptor = descriptorId;
205    return GRALLOC1_ERROR_NONE;
206}
207
208gralloc1_error_t Gralloc1On0Adapter::destroyDescriptor(
209        gralloc1_buffer_descriptor_t descriptor)
210{
211    ALOGV("Destroying descriptor %" PRIu64, descriptor);
212
213    std::lock_guard<std::mutex> lock(mDescriptorMutex);
214    if (mDescriptors.count(descriptor) == 0) {
215        return GRALLOC1_ERROR_BAD_DESCRIPTOR;
216    }
217
218    mDescriptors.erase(descriptor);
219    return GRALLOC1_ERROR_NONE;
220}
221
222Gralloc1On0Adapter::Buffer::Buffer(buffer_handle_t handle,
223        gralloc1_backing_store_t store, const Descriptor& descriptor,
224        uint32_t stride, uint32_t numFlexPlanes, bool wasAllocated)
225  : mHandle(handle),
226    mReferenceCount(1),
227    mStore(store),
228    mDescriptor(descriptor),
229    mStride(stride),
230    mNumFlexPlanes(numFlexPlanes),
231    mWasAllocated(wasAllocated) {}
232
233gralloc1_error_t Gralloc1On0Adapter::allocate(
234        gralloc1_buffer_descriptor_t id,
235        const std::shared_ptr<Descriptor>& descriptor,
236        buffer_handle_t* outBufferHandle)
237{
238    ALOGV("allocate(%" PRIu64 ")", id);
239
240    // If this function is being called, it's because we handed out its function
241    // pointer, which only occurs when mDevice has been loaded successfully and
242    // we are permitted to allocate
243
244    int usage = android_convertGralloc1To0Usage(
245            descriptor->producerUsage, descriptor->consumerUsage);
246    buffer_handle_t handle = nullptr;
247    int stride = 0;
248    ALOGV("Calling alloc(%p, %u, %u, %i, %u)", mDevice, descriptor->width,
249            descriptor->height, descriptor->format, usage);
250    auto error = mDevice->alloc(mDevice,
251            static_cast<int>(descriptor->width),
252            static_cast<int>(descriptor->height), descriptor->format,
253            usage, &handle, &stride);
254    if (error != 0) {
255        ALOGE("gralloc0 allocation failed: %d (%s)", error,
256                strerror(-error));
257        return GRALLOC1_ERROR_NO_RESOURCES;
258    }
259
260    mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_SET_USAGES,
261            handle,
262            static_cast<int>(descriptor->producerUsage),
263            static_cast<int>(descriptor->consumerUsage));
264
265    uint64_t backingStore = 0;
266    mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_BACKING_STORE,
267            handle, &backingStore);
268    int numFlexPlanes = 0;
269    mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_NUM_FLEX_PLANES,
270            handle, &numFlexPlanes);
271
272    *outBufferHandle = handle;
273    auto buffer = std::make_shared<Buffer>(handle, backingStore,
274            *descriptor, stride, numFlexPlanes, true);
275
276    std::lock_guard<std::mutex> lock(mBufferMutex);
277    mBuffers.emplace(handle, std::move(buffer));
278
279    return GRALLOC1_ERROR_NONE;
280}
281
282int32_t Gralloc1On0Adapter::allocateHook(gralloc1_device* device,
283        uint32_t numDescriptors,
284        const gralloc1_buffer_descriptor_t* descriptors,
285        buffer_handle_t* outBuffers)
286{
287    if (!outBuffers) {
288        return GRALLOC1_ERROR_UNDEFINED;
289    }
290
291    auto adapter = getAdapter(device);
292
293    gralloc1_error_t error = GRALLOC1_ERROR_NONE;
294    uint32_t i;
295    for (i = 0; i < numDescriptors; i++) {
296        auto descriptor = adapter->getDescriptor(descriptors[i]);
297        if (!descriptor) {
298            error = GRALLOC1_ERROR_BAD_DESCRIPTOR;
299            break;
300        }
301
302        buffer_handle_t bufferHandle = nullptr;
303        error = adapter->allocate(descriptors[i], descriptor, &bufferHandle);
304        if (error != GRALLOC1_ERROR_NONE) {
305            break;
306        }
307
308        outBuffers[i] = bufferHandle;
309    }
310
311    if (error == GRALLOC1_ERROR_NONE) {
312        if (numDescriptors > 1) {
313            error = GRALLOC1_ERROR_NOT_SHARED;
314        }
315    } else {
316        for (uint32_t j = 0; j < i; j++) {
317            adapter->release(adapter->getBuffer(outBuffers[j]));
318            outBuffers[j] = nullptr;
319        }
320    }
321
322    return error;
323}
324
325gralloc1_error_t Gralloc1On0Adapter::retain(
326        const std::shared_ptr<Buffer>& buffer)
327{
328    std::lock_guard<std::mutex> lock(mBufferMutex);
329    buffer->retain();
330    return GRALLOC1_ERROR_NONE;
331}
332
333gralloc1_error_t Gralloc1On0Adapter::release(
334        const std::shared_ptr<Buffer>& buffer)
335{
336    std::lock_guard<std::mutex> lock(mBufferMutex);
337    if (!buffer->release()) {
338        return GRALLOC1_ERROR_NONE;
339    }
340
341    buffer_handle_t handle = buffer->getHandle();
342    if (buffer->wasAllocated()) {
343        ALOGV("Calling free(%p)", handle);
344        int result = mDevice->free(mDevice, handle);
345        if (result != 0) {
346            ALOGE("gralloc0 free failed: %d", result);
347        }
348    } else {
349        ALOGV("Calling unregisterBuffer(%p)", handle);
350        int result = mModule->unregisterBuffer(mModule, handle);
351        if (result != 0) {
352            ALOGE("gralloc0 unregister failed: %d", result);
353        }
354    }
355
356    mBuffers.erase(handle);
357    return GRALLOC1_ERROR_NONE;
358}
359
360gralloc1_error_t Gralloc1On0Adapter::retain(buffer_handle_t bufferHandle)
361{
362    ALOGV("retain(%p)", bufferHandle);
363
364    std::lock_guard<std::mutex> lock(mBufferMutex);
365
366    if (mBuffers.count(bufferHandle) != 0) {
367        mBuffers[bufferHandle]->retain();
368        return GRALLOC1_ERROR_NONE;
369    }
370
371    ALOGV("Calling registerBuffer(%p)", bufferHandle);
372    int result = mModule->registerBuffer(mModule, bufferHandle);
373    if (result != 0) {
374        ALOGE("gralloc0 register failed: %d", result);
375        return GRALLOC1_ERROR_NO_RESOURCES;
376    }
377
378    uint64_t backingStore = 0;
379    mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_BACKING_STORE,
380            bufferHandle, &backingStore);
381
382    int numFlexPlanes = 0;
383    mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_NUM_FLEX_PLANES,
384            bufferHandle, &numFlexPlanes);
385
386    int stride = 0;
387    mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_STRIDE,
388            bufferHandle, &stride);
389
390    int width = 0;
391    int height = 0;
392    int format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
393    int producerUsage = 0;
394    int consumerUsage = 0;
395    mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_DIMENSIONS,
396            bufferHandle, &width, &height);
397    mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_FORMAT,
398            bufferHandle, &format);
399    mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_PRODUCER_USAGE,
400            bufferHandle, &producerUsage);
401    mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_CONSUMER_USAGE,
402            bufferHandle, &consumerUsage);
403
404    Descriptor descriptor;
405    descriptor.setDimensions(width, height);
406    descriptor.setFormat(format);
407    descriptor.setProducerUsage(
408            static_cast<gralloc1_producer_usage_t>(producerUsage));
409    descriptor.setConsumerUsage(
410            static_cast<gralloc1_consumer_usage_t>(consumerUsage));
411
412    auto buffer = std::make_shared<Buffer>(bufferHandle, backingStore,
413            descriptor, stride, numFlexPlanes, false);
414    mBuffers.emplace(bufferHandle, std::move(buffer));
415    return GRALLOC1_ERROR_NONE;
416}
417
418static void syncWaitForever(int fd, const char* logname)
419{
420    if (fd < 0) {
421        return;
422    }
423
424    const int warningTimeout = 3500;
425    const int error = sync_wait(fd, warningTimeout);
426    if (error < 0 && errno == ETIME) {
427        ALOGE("%s: fence %d didn't signal in %u ms", logname, fd,
428                warningTimeout);
429        sync_wait(fd, -1);
430    }
431}
432
433gralloc1_error_t Gralloc1On0Adapter::lock(
434        const std::shared_ptr<Buffer>& buffer,
435        gralloc1_producer_usage_t producerUsage,
436        gralloc1_consumer_usage_t consumerUsage,
437        const gralloc1_rect_t& accessRegion, void** outData,
438        int acquireFence)
439{
440    if (mMinorVersion >= 3) {
441        int result = mModule->lockAsync(mModule, buffer->getHandle(),
442                android_convertGralloc1To0Usage(producerUsage, consumerUsage),
443                accessRegion.left, accessRegion.top, accessRegion.width,
444                accessRegion.height, outData, acquireFence);
445        if (result != 0) {
446            return GRALLOC1_ERROR_UNSUPPORTED;
447        }
448    } else {
449        syncWaitForever(acquireFence, "Gralloc1On0Adapter::lock");
450
451        int result = mModule->lock(mModule, buffer->getHandle(),
452                android_convertGralloc1To0Usage(producerUsage, consumerUsage),
453                accessRegion.left, accessRegion.top, accessRegion.width,
454                accessRegion.height, outData);
455        ALOGV("gralloc0 lock returned %d", result);
456        if (result != 0) {
457            return GRALLOC1_ERROR_UNSUPPORTED;
458        } else if (acquireFence >= 0) {
459            close(acquireFence);
460        }
461    }
462    return GRALLOC1_ERROR_NONE;
463}
464
465gralloc1_error_t Gralloc1On0Adapter::lockFlex(
466        const std::shared_ptr<Buffer>& buffer,
467        gralloc1_producer_usage_t producerUsage,
468        gralloc1_consumer_usage_t consumerUsage,
469        const gralloc1_rect_t& accessRegion,
470        struct android_flex_layout* outFlex,
471        int acquireFence)
472{
473    if (mMinorVersion >= 3) {
474        int result = mModule->perform(mModule,
475                GRALLOC1_ADAPTER_PERFORM_LOCK_FLEX,
476                buffer->getHandle(),
477                static_cast<int>(producerUsage),
478                static_cast<int>(consumerUsage),
479                accessRegion.left,
480                accessRegion.top,
481                accessRegion.width,
482                accessRegion.height,
483                outFlex, acquireFence);
484        if (result != 0) {
485            return GRALLOC1_ERROR_UNSUPPORTED;
486        }
487    } else {
488        syncWaitForever(acquireFence, "Gralloc1On0Adapter::lockFlex");
489
490        int result = mModule->perform(mModule,
491                GRALLOC1_ADAPTER_PERFORM_LOCK_FLEX,
492                buffer->getHandle(),
493                static_cast<int>(producerUsage),
494                static_cast<int>(consumerUsage),
495                accessRegion.left,
496                accessRegion.top,
497                accessRegion.width,
498                accessRegion.height,
499                outFlex, -1);
500        if (result != 0) {
501            return GRALLOC1_ERROR_UNSUPPORTED;
502        } else if (acquireFence >= 0) {
503            close(acquireFence);
504        }
505    }
506
507    return GRALLOC1_ERROR_NONE;
508}
509
510gralloc1_error_t Gralloc1On0Adapter::unlock(
511        const std::shared_ptr<Buffer>& buffer,
512        int* outReleaseFence)
513{
514    if (mMinorVersion >= 3) {
515        int fenceFd = -1;
516        int result = mModule->unlockAsync(mModule, buffer->getHandle(),
517                &fenceFd);
518        if (result != 0) {
519            close(fenceFd);
520            ALOGE("gralloc0 unlockAsync failed: %d", result);
521        } else {
522            *outReleaseFence = fenceFd;
523        }
524    } else {
525        int result = mModule->unlock(mModule, buffer->getHandle());
526        if (result != 0) {
527            ALOGE("gralloc0 unlock failed: %d", result);
528        } else {
529            *outReleaseFence = -1;
530        }
531    }
532    return GRALLOC1_ERROR_NONE;
533}
534
535std::shared_ptr<Gralloc1On0Adapter::Descriptor>
536Gralloc1On0Adapter::getDescriptor(gralloc1_buffer_descriptor_t descriptorId)
537{
538    std::lock_guard<std::mutex> lock(mDescriptorMutex);
539    if (mDescriptors.count(descriptorId) == 0) {
540        return nullptr;
541    }
542
543    return mDescriptors[descriptorId];
544}
545
546std::shared_ptr<Gralloc1On0Adapter::Buffer> Gralloc1On0Adapter::getBuffer(
547        buffer_handle_t bufferHandle)
548{
549    std::lock_guard<std::mutex> lock(mBufferMutex);
550    if (mBuffers.count(bufferHandle) == 0) {
551        return nullptr;
552    }
553
554    return mBuffers[bufferHandle];
555}
556
557std::atomic<gralloc1_buffer_descriptor_t>
558        Gralloc1On0Adapter::sNextBufferDescriptorId(1);
559
560} // namespace hardware
561} // namespace android
562