Home | History | Annotate | Download | only in default
      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 #define LOG_TAG "Gralloc1Allocator"
     18 
     19 #include "Gralloc1Allocator.h"
     20 #include "GrallocBufferDescriptor.h"
     21 
     22 #include <vector>
     23 
     24 #include <string.h>
     25 
     26 #include <log/log.h>
     27 
     28 namespace android {
     29 namespace hardware {
     30 namespace graphics {
     31 namespace allocator {
     32 namespace V2_0 {
     33 namespace implementation {
     34 
     35 using android::hardware::graphics::common::V1_0::BufferUsage;
     36 using android::hardware::graphics::mapper::V2_0::implementation::
     37     grallocDecodeBufferDescriptor;
     38 
     39 Gralloc1Allocator::Gralloc1Allocator(const hw_module_t* module)
     40     : mDevice(nullptr), mCapabilities(), mDispatch() {
     41     int result = gralloc1_open(module, &mDevice);
     42     if (result) {
     43         LOG_ALWAYS_FATAL("failed to open gralloc1 device: %s",
     44                          strerror(-result));
     45     }
     46 
     47     initCapabilities();
     48     initDispatch();
     49 }
     50 
     51 Gralloc1Allocator::~Gralloc1Allocator() {
     52     gralloc1_close(mDevice);
     53 }
     54 
     55 void Gralloc1Allocator::initCapabilities() {
     56     uint32_t count = 0;
     57     mDevice->getCapabilities(mDevice, &count, nullptr);
     58 
     59     std::vector<int32_t> capabilities(count);
     60     mDevice->getCapabilities(mDevice, &count, capabilities.data());
     61     capabilities.resize(count);
     62 
     63     for (auto capability : capabilities) {
     64         if (capability == GRALLOC1_CAPABILITY_LAYERED_BUFFERS) {
     65             mCapabilities.layeredBuffers = true;
     66             break;
     67         }
     68     }
     69 }
     70 
     71 template <typename T>
     72 void Gralloc1Allocator::initDispatch(gralloc1_function_descriptor_t desc,
     73                                      T* outPfn) {
     74     auto pfn = mDevice->getFunction(mDevice, desc);
     75     if (!pfn) {
     76         LOG_ALWAYS_FATAL("failed to get gralloc1 function %d", desc);
     77     }
     78 
     79     *outPfn = reinterpret_cast<T>(pfn);
     80 }
     81 
     82 void Gralloc1Allocator::initDispatch() {
     83     initDispatch(GRALLOC1_FUNCTION_DUMP, &mDispatch.dump);
     84     initDispatch(GRALLOC1_FUNCTION_CREATE_DESCRIPTOR,
     85                  &mDispatch.createDescriptor);
     86     initDispatch(GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR,
     87                  &mDispatch.destroyDescriptor);
     88     initDispatch(GRALLOC1_FUNCTION_SET_DIMENSIONS, &mDispatch.setDimensions);
     89     initDispatch(GRALLOC1_FUNCTION_SET_FORMAT, &mDispatch.setFormat);
     90     if (mCapabilities.layeredBuffers) {
     91         initDispatch(GRALLOC1_FUNCTION_SET_LAYER_COUNT,
     92                      &mDispatch.setLayerCount);
     93     }
     94     initDispatch(GRALLOC1_FUNCTION_SET_CONSUMER_USAGE,
     95                  &mDispatch.setConsumerUsage);
     96     initDispatch(GRALLOC1_FUNCTION_SET_PRODUCER_USAGE,
     97                  &mDispatch.setProducerUsage);
     98     initDispatch(GRALLOC1_FUNCTION_GET_STRIDE, &mDispatch.getStride);
     99     initDispatch(GRALLOC1_FUNCTION_ALLOCATE, &mDispatch.allocate);
    100     initDispatch(GRALLOC1_FUNCTION_RELEASE, &mDispatch.release);
    101 }
    102 
    103 Return<void> Gralloc1Allocator::dumpDebugInfo(dumpDebugInfo_cb hidl_cb) {
    104     uint32_t len = 0;
    105     mDispatch.dump(mDevice, &len, nullptr);
    106 
    107     std::vector<char> buf(len + 1);
    108     mDispatch.dump(mDevice, &len, buf.data());
    109     buf.resize(len + 1);
    110     buf[len] = '\0';
    111 
    112     hidl_string reply;
    113     reply.setToExternal(buf.data(), len);
    114     hidl_cb(reply);
    115 
    116     return Void();
    117 }
    118 
    119 Return<void> Gralloc1Allocator::allocate(const BufferDescriptor& descriptor,
    120                                          uint32_t count, allocate_cb hidl_cb) {
    121     IMapper::BufferDescriptorInfo descriptorInfo;
    122     if (!grallocDecodeBufferDescriptor(descriptor, &descriptorInfo)) {
    123         hidl_cb(Error::BAD_DESCRIPTOR, 0, hidl_vec<hidl_handle>());
    124         return Void();
    125     }
    126 
    127     gralloc1_buffer_descriptor_t desc;
    128     Error error = createDescriptor(descriptorInfo, &desc);
    129     if (error != Error::NONE) {
    130         hidl_cb(error, 0, hidl_vec<hidl_handle>());
    131         return Void();
    132     }
    133 
    134     uint32_t stride = 0;
    135     std::vector<hidl_handle> buffers;
    136     buffers.reserve(count);
    137 
    138     // allocate the buffers
    139     for (uint32_t i = 0; i < count; i++) {
    140         buffer_handle_t tmpBuffer;
    141         uint32_t tmpStride;
    142         error = allocateOne(desc, &tmpBuffer, &tmpStride);
    143         if (error != Error::NONE) {
    144             break;
    145         }
    146 
    147         if (stride == 0) {
    148             stride = tmpStride;
    149         } else if (stride != tmpStride) {
    150             // non-uniform strides
    151             mDispatch.release(mDevice, tmpBuffer);
    152             stride = 0;
    153             error = Error::UNSUPPORTED;
    154             break;
    155         }
    156 
    157         buffers.emplace_back(hidl_handle(tmpBuffer));
    158     }
    159 
    160     mDispatch.destroyDescriptor(mDevice, desc);
    161 
    162     // return the buffers
    163     hidl_vec<hidl_handle> hidl_buffers;
    164     if (error == Error::NONE) {
    165         hidl_buffers.setToExternal(buffers.data(), buffers.size());
    166     }
    167     hidl_cb(error, stride, hidl_buffers);
    168 
    169     // free the buffers
    170     for (const auto& buffer : buffers) {
    171         mDispatch.release(mDevice, buffer.getNativeHandle());
    172     }
    173 
    174     return Void();
    175 }
    176 
    177 Error Gralloc1Allocator::toError(int32_t error) {
    178     switch (error) {
    179         case GRALLOC1_ERROR_NONE:
    180             return Error::NONE;
    181         case GRALLOC1_ERROR_BAD_DESCRIPTOR:
    182             return Error::BAD_DESCRIPTOR;
    183         case GRALLOC1_ERROR_BAD_HANDLE:
    184             return Error::BAD_BUFFER;
    185         case GRALLOC1_ERROR_BAD_VALUE:
    186             return Error::BAD_VALUE;
    187         case GRALLOC1_ERROR_NOT_SHARED:
    188             return Error::NONE;  // this is fine
    189         case GRALLOC1_ERROR_NO_RESOURCES:
    190             return Error::NO_RESOURCES;
    191         case GRALLOC1_ERROR_UNDEFINED:
    192         case GRALLOC1_ERROR_UNSUPPORTED:
    193         default:
    194             return Error::UNSUPPORTED;
    195     }
    196 }
    197 
    198 uint64_t Gralloc1Allocator::toProducerUsage(uint64_t usage) {
    199     // this is potentially broken as we have no idea which private flags
    200     // should be filtered out
    201     uint64_t producerUsage =
    202         usage &
    203         ~static_cast<uint64_t>(BufferUsage::CPU_READ_MASK |
    204                                BufferUsage::CPU_WRITE_MASK);
    205 
    206     switch (usage & BufferUsage::CPU_WRITE_MASK) {
    207         case static_cast<uint64_t>(BufferUsage::CPU_WRITE_RARELY):
    208             producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE;
    209             break;
    210         case static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN):
    211             producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN;
    212             break;
    213         default:
    214             break;
    215     }
    216 
    217     switch (usage & BufferUsage::CPU_READ_MASK) {
    218         case static_cast<uint64_t>(BufferUsage::CPU_READ_RARELY):
    219             producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_READ;
    220             break;
    221         case static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN):
    222             producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN;
    223             break;
    224         default:
    225             break;
    226     }
    227 
    228     return producerUsage;
    229 }
    230 
    231 uint64_t Gralloc1Allocator::toConsumerUsage(uint64_t usage) {
    232     // this is potentially broken as we have no idea which private flags
    233     // should be filtered out
    234     uint64_t consumerUsage =
    235         usage &
    236         ~static_cast<uint64_t>(BufferUsage::CPU_READ_MASK |
    237                                BufferUsage::CPU_WRITE_MASK);
    238 
    239     switch (usage & BufferUsage::CPU_READ_MASK) {
    240         case static_cast<uint64_t>(BufferUsage::CPU_READ_RARELY):
    241             consumerUsage |= GRALLOC1_CONSUMER_USAGE_CPU_READ;
    242             break;
    243         case static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN):
    244             consumerUsage |= GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN;
    245             break;
    246         default:
    247             break;
    248     }
    249 
    250     return consumerUsage;
    251 }
    252 
    253 Error Gralloc1Allocator::createDescriptor(
    254     const IMapper::BufferDescriptorInfo& info,
    255     gralloc1_buffer_descriptor_t* outDescriptor) {
    256     gralloc1_buffer_descriptor_t descriptor;
    257 
    258     int32_t error = mDispatch.createDescriptor(mDevice, &descriptor);
    259 
    260     if (error == GRALLOC1_ERROR_NONE) {
    261         error = mDispatch.setDimensions(mDevice, descriptor, info.width,
    262                                         info.height);
    263     }
    264     if (error == GRALLOC1_ERROR_NONE) {
    265         error = mDispatch.setFormat(mDevice, descriptor,
    266                                     static_cast<int32_t>(info.format));
    267     }
    268     if (error == GRALLOC1_ERROR_NONE) {
    269         if (mCapabilities.layeredBuffers) {
    270             error =
    271                 mDispatch.setLayerCount(mDevice, descriptor, info.layerCount);
    272         } else if (info.layerCount > 1) {
    273             error = GRALLOC1_ERROR_UNSUPPORTED;
    274         }
    275     }
    276     if (error == GRALLOC1_ERROR_NONE) {
    277         error = mDispatch.setProducerUsage(mDevice, descriptor,
    278                                            toProducerUsage(info.usage));
    279     }
    280     if (error == GRALLOC1_ERROR_NONE) {
    281         error = mDispatch.setConsumerUsage(mDevice, descriptor,
    282                                            toConsumerUsage(info.usage));
    283     }
    284 
    285     if (error == GRALLOC1_ERROR_NONE) {
    286         *outDescriptor = descriptor;
    287     } else {
    288         mDispatch.destroyDescriptor(mDevice, descriptor);
    289     }
    290 
    291     return toError(error);
    292 }
    293 
    294 Error Gralloc1Allocator::allocateOne(gralloc1_buffer_descriptor_t descriptor,
    295                                      buffer_handle_t* outBuffer,
    296                                      uint32_t* outStride) {
    297     buffer_handle_t buffer = nullptr;
    298     int32_t error = mDispatch.allocate(mDevice, 1, &descriptor, &buffer);
    299     if (error != GRALLOC1_ERROR_NONE && error != GRALLOC1_ERROR_NOT_SHARED) {
    300         return toError(error);
    301     }
    302 
    303     uint32_t stride = 0;
    304     error = mDispatch.getStride(mDevice, buffer, &stride);
    305     if (error != GRALLOC1_ERROR_NONE && error != GRALLOC1_ERROR_UNDEFINED) {
    306         mDispatch.release(mDevice, buffer);
    307         return toError(error);
    308     }
    309 
    310     *outBuffer = buffer;
    311     *outStride = stride;
    312 
    313     return Error::NONE;
    314 }
    315 
    316 }  // namespace implementation
    317 }  // namespace V2_0
    318 }  // namespace allocator
    319 }  // namespace graphics
    320 }  // namespace hardware
    321 }  // namespace android
    322