Home | History | Annotate | Download | only in libgralloc
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 #include <limits.h>
     19 #include <errno.h>
     20 #include <pthread.h>
     21 #include <unistd.h>
     22 #include <string.h>
     23 #include <stdarg.h>
     24 
     25 #include <sys/mman.h>
     26 #include <sys/stat.h>
     27 #include <sys/types.h>
     28 #include <sys/ioctl.h>
     29 
     30 #include <cutils/log.h>
     31 #include <cutils/atomic.h>
     32 
     33 #include <hardware/hardware.h>
     34 #include <hardware/gralloc.h>
     35 
     36 #include "gralloc_priv.h"
     37 #include "gr.h"
     38 #include "alloc_controller.h"
     39 #include "memalloc.h"
     40 #include <qdMetaData.h>
     41 
     42 using namespace gralloc;
     43 /*****************************************************************************/
     44 
     45 // Return the type of allocator -
     46 // these are used for mapping/unmapping
     47 static IMemAlloc* getAllocator(int flags)
     48 {
     49     IMemAlloc* memalloc;
     50     IAllocController* alloc_ctrl = IAllocController::getInstance();
     51     memalloc = alloc_ctrl->getAllocator(flags);
     52     return memalloc;
     53 }
     54 
     55 static int gralloc_map(gralloc_module_t const* module,
     56                        buffer_handle_t handle)
     57 {
     58     if(!module)
     59         return -EINVAL;
     60 
     61     private_handle_t* hnd = (private_handle_t*)handle;
     62     void *mappedAddress;
     63     if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) &&
     64         !(hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER)) {
     65         unsigned int size = hnd->size;
     66         IMemAlloc* memalloc = getAllocator(hnd->flags) ;
     67         int err = memalloc->map_buffer(&mappedAddress, size,
     68                                        hnd->offset, hnd->fd);
     69         if(err || mappedAddress == MAP_FAILED) {
     70             ALOGE("Could not mmap handle %p, fd=%d (%s)",
     71                   handle, hnd->fd, strerror(errno));
     72             hnd->base = 0;
     73             return -errno;
     74         }
     75 
     76         hnd->base = uint64_t(mappedAddress) + hnd->offset;
     77         mappedAddress = MAP_FAILED;
     78         size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
     79         err = memalloc->map_buffer(&mappedAddress, size,
     80                                        hnd->offset_metadata, hnd->fd_metadata);
     81         if(err || mappedAddress == MAP_FAILED) {
     82             ALOGE("Could not mmap handle %p, fd=%d (%s)",
     83                   handle, hnd->fd_metadata, strerror(errno));
     84             hnd->base_metadata = 0;
     85             return -errno;
     86         }
     87         hnd->base_metadata = uint64_t(mappedAddress) + hnd->offset_metadata;
     88     }
     89     return 0;
     90 }
     91 
     92 static int gralloc_unmap(gralloc_module_t const* module,
     93                          buffer_handle_t handle)
     94 {
     95     if(!module)
     96         return -EINVAL;
     97 
     98     private_handle_t* hnd = (private_handle_t*)handle;
     99     if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
    100         int err = -EINVAL;
    101         void* base = (void*)hnd->base;
    102         unsigned int size = hnd->size;
    103         IMemAlloc* memalloc = getAllocator(hnd->flags) ;
    104         if(memalloc != NULL) {
    105             err = memalloc->unmap_buffer(base, size, hnd->offset);
    106             if (err) {
    107                 ALOGE("Could not unmap memory at address %p", base);
    108             }
    109             base = (void*)hnd->base_metadata;
    110             size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
    111             err = memalloc->unmap_buffer(base, size, hnd->offset_metadata);
    112             if (err) {
    113                 ALOGE("Could not unmap memory at address %p", base);
    114             }
    115         }
    116     }
    117     /* need to initialize the pointer to NULL otherwise unmapping for that
    118      * buffer happens twice which leads to crash */
    119     hnd->base = 0;
    120     hnd->base_metadata = 0;
    121     return 0;
    122 }
    123 
    124 /*****************************************************************************/
    125 
    126 static pthread_mutex_t sMapLock = PTHREAD_MUTEX_INITIALIZER;
    127 
    128 /*****************************************************************************/
    129 
    130 int gralloc_register_buffer(gralloc_module_t const* module,
    131                             buffer_handle_t handle)
    132 {
    133     if (!module || private_handle_t::validate(handle) < 0)
    134         return -EINVAL;
    135 
    136     // In this implementation, we don't need to do anything here
    137 
    138     /* NOTE: we need to initialize the buffer as not mapped/not locked
    139      * because it shouldn't when this function is called the first time
    140      * in a new process. Ideally these flags shouldn't be part of the
    141      * handle, but instead maintained in the kernel or at least
    142      * out-of-line
    143      */
    144 
    145     private_handle_t* hnd = (private_handle_t*)handle;
    146     hnd->base = 0;
    147     hnd->base_metadata = 0;
    148     int err = gralloc_map(module, handle);
    149     if (err) {
    150         ALOGE("%s: gralloc_map failed", __FUNCTION__);
    151         return err;
    152     }
    153 
    154     return 0;
    155 }
    156 
    157 int gralloc_unregister_buffer(gralloc_module_t const* module,
    158                               buffer_handle_t handle)
    159 {
    160     if (!module || private_handle_t::validate(handle) < 0)
    161         return -EINVAL;
    162 
    163     /*
    164      * If the buffer has been mapped during a lock operation, it's time
    165      * to un-map it. It's an error to be here with a locked buffer.
    166      * NOTE: the framebuffer is handled differently and is never unmapped.
    167      */
    168 
    169     private_handle_t* hnd = (private_handle_t*)handle;
    170 
    171     if (hnd->base != 0) {
    172         gralloc_unmap(module, handle);
    173     }
    174     hnd->base = 0;
    175     hnd->base_metadata = 0;
    176     return 0;
    177 }
    178 
    179 int terminateBuffer(gralloc_module_t const* module,
    180                     private_handle_t* hnd)
    181 {
    182     if(!module)
    183         return -EINVAL;
    184 
    185     /*
    186      * If the buffer has been mapped during a lock operation, it's time
    187      * to un-map it. It's an error to be here with a locked buffer.
    188      */
    189 
    190     if (hnd->base != 0) {
    191         // this buffer was mapped, unmap it now
    192         if (hnd->flags & (private_handle_t::PRIV_FLAGS_USES_PMEM |
    193                           private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP |
    194                           private_handle_t::PRIV_FLAGS_USES_ASHMEM |
    195                           private_handle_t::PRIV_FLAGS_USES_ION)) {
    196                 gralloc_unmap(module, hnd);
    197         } else {
    198             ALOGE("terminateBuffer: unmapping a non pmem/ashmem buffer flags = 0x%x",
    199                   hnd->flags);
    200             gralloc_unmap(module, hnd);
    201         }
    202     }
    203 
    204     return 0;
    205 }
    206 
    207 static int gralloc_map_and_invalidate (gralloc_module_t const* module,
    208                                        buffer_handle_t handle, int usage)
    209 {
    210     if (!module || private_handle_t::validate(handle) < 0)
    211         return -EINVAL;
    212 
    213     int err = 0;
    214     private_handle_t* hnd = (private_handle_t*)handle;
    215     if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) {
    216         if (hnd->base == 0) {
    217             // we need to map for real
    218             pthread_mutex_t* const lock = &sMapLock;
    219             pthread_mutex_lock(lock);
    220             err = gralloc_map(module, handle);
    221             pthread_mutex_unlock(lock);
    222         }
    223         if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) {
    224             //Invalidate if reading in software. No need to do this for the
    225             //metadata buffer as it is only read/written in software.
    226             IMemAlloc* memalloc = getAllocator(hnd->flags) ;
    227             err = memalloc->clean_buffer((void*)hnd->base,
    228                                          hnd->size, hnd->offset, hnd->fd,
    229                                          CACHE_INVALIDATE);
    230             if (usage & GRALLOC_USAGE_SW_WRITE_MASK) {
    231                 // Mark the buffer to be flushed after cpu read/write
    232                 hnd->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
    233             }
    234         }
    235     } else {
    236         hnd->flags |= private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH;
    237     }
    238     return err;
    239 }
    240 
    241 int gralloc_lock(gralloc_module_t const* module,
    242                  buffer_handle_t handle, int usage,
    243                  int /*l*/, int /*t*/, int /*w*/, int /*h*/,
    244                  void** vaddr)
    245 {
    246     private_handle_t* hnd = (private_handle_t*)handle;
    247     int err = gralloc_map_and_invalidate(module, handle, usage);
    248     if(!err)
    249         *vaddr = (void*)hnd->base;
    250     return err;
    251 }
    252 
    253 int gralloc_lock_ycbcr(gralloc_module_t const* module,
    254                  buffer_handle_t handle, int usage,
    255                  int /*l*/, int /*t*/, int /*w*/, int /*h*/,
    256                  struct android_ycbcr *ycbcr)
    257 {
    258     private_handle_t* hnd = (private_handle_t*)handle;
    259     int err = gralloc_map_and_invalidate(module, handle, usage);
    260     if(!err)
    261         err = getYUVPlaneInfo(hnd, ycbcr);
    262     return err;
    263 }
    264 
    265 int gralloc_unlock(gralloc_module_t const* module,
    266                    buffer_handle_t handle)
    267 {
    268     if (!module || private_handle_t::validate(handle) < 0)
    269         return -EINVAL;
    270 
    271     int err = 0;
    272     private_handle_t* hnd = (private_handle_t*)handle;
    273 
    274     if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) {
    275         IMemAlloc* memalloc = getAllocator(hnd->flags);
    276         if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
    277             err = memalloc->clean_buffer((void*)hnd->base,
    278                                          hnd->size, hnd->offset, hnd->fd,
    279                                          CACHE_CLEAN_AND_INVALIDATE);
    280             hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
    281         } else if(hnd->flags & private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH) {
    282             hnd->flags &= ~private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH;
    283         } else {
    284             //Probably a round about way to do this, but this avoids adding new
    285             //flags
    286             err = memalloc->clean_buffer((void*)hnd->base,
    287                                          hnd->size, hnd->offset, hnd->fd,
    288                                          CACHE_INVALIDATE);
    289         }
    290     }
    291 
    292     return err;
    293 }
    294 
    295 /*****************************************************************************/
    296 
    297 int gralloc_perform(struct gralloc_module_t const* module,
    298                     int operation, ... )
    299 {
    300     int res = -EINVAL;
    301     va_list args;
    302     if(!module)
    303         return res;
    304 
    305     va_start(args, operation);
    306     switch (operation) {
    307         case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER:
    308             {
    309                 int fd = va_arg(args, int);
    310                 unsigned int size = va_arg(args, unsigned int);
    311                 unsigned int offset = va_arg(args, unsigned int);
    312                 void* base = va_arg(args, void*);
    313                 int width = va_arg(args, int);
    314                 int height = va_arg(args, int);
    315                 int format = va_arg(args, int);
    316 
    317                 native_handle_t** handle = va_arg(args, native_handle_t**);
    318                 private_handle_t* hnd = (private_handle_t*)native_handle_create(
    319                     private_handle_t::sNumFds, private_handle_t::sNumInts());
    320                 hnd->magic = private_handle_t::sMagic;
    321                 hnd->fd = fd;
    322                 hnd->flags =  private_handle_t::PRIV_FLAGS_USES_ION;
    323                 hnd->size = size;
    324                 hnd->offset = offset;
    325                 hnd->base = uint64_t(base) + offset;
    326                 hnd->gpuaddr = 0;
    327                 hnd->width = width;
    328                 hnd->height = height;
    329                 hnd->format = format;
    330                 *handle = (native_handle_t *)hnd;
    331                 res = 0;
    332                 break;
    333 
    334             }
    335 #ifdef QCOM_BSP
    336         case GRALLOC_MODULE_PERFORM_UPDATE_BUFFER_GEOMETRY:
    337             {
    338                 int width = va_arg(args, int);
    339                 int height = va_arg(args, int);
    340                 int format = va_arg(args, int);
    341                 private_handle_t* hnd =  va_arg(args, private_handle_t*);
    342                 if (private_handle_t::validate(hnd)) {
    343                     return res;
    344                 }
    345                 hnd->width = width;
    346                 hnd->height = height;
    347                 hnd->format = format;
    348                 res = 0;
    349             }
    350             break;
    351 #endif
    352         case GRALLOC_MODULE_PERFORM_GET_STRIDE:
    353             {
    354                 int width   = va_arg(args, int);
    355                 int format  = va_arg(args, int);
    356                 int *stride = va_arg(args, int *);
    357                 int alignedw = 0, alignedh = 0;
    358                 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
    359                         0, format, false, alignedw, alignedh);
    360                 *stride = alignedw;
    361                 res = 0;
    362             } break;
    363 
    364         case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE:
    365             {
    366                 private_handle_t* hnd =  va_arg(args, private_handle_t*);
    367                 int *stride = va_arg(args, int *);
    368                 if (private_handle_t::validate(hnd)) {
    369                     return res;
    370                 }
    371                 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
    372                 if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
    373                     *stride = metadata->bufferDim.sliceWidth;
    374                 } else {
    375                     *stride = hnd->width;
    376                 }
    377                 res = 0;
    378             } break;
    379 
    380         case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE:
    381             {
    382                 private_handle_t* hnd =  va_arg(args, private_handle_t*);
    383                 int *stride = va_arg(args, int *);
    384                 int *height = va_arg(args, int *);
    385                 if (private_handle_t::validate(hnd)) {
    386                     return res;
    387                 }
    388                 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
    389                 if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
    390                     *stride = metadata->bufferDim.sliceWidth;
    391                     *height = metadata->bufferDim.sliceHeight;
    392                 } else {
    393                     *stride = hnd->width;
    394                     *height = hnd->height;
    395                 }
    396                 res = 0;
    397             } break;
    398 
    399         case GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES:
    400             {
    401                 int width   = va_arg(args, int);
    402                 int height  = va_arg(args, int);
    403                 int format  = va_arg(args, int);
    404                 int usage   = va_arg(args, int);
    405                 int *alignedWidth = va_arg(args, int *);
    406                 int *alignedHeight = va_arg(args, int *);
    407                 int *tileEnabled = va_arg(args,int *);
    408                 *tileEnabled = isMacroTileEnabled(format, usage);
    409                 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
    410                         height, format, *tileEnabled, *alignedWidth,
    411                         *alignedHeight);
    412                 res = 0;
    413             } break;
    414 
    415         case GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE:
    416             {
    417                 private_handle_t* hnd =  va_arg(args, private_handle_t*);
    418                 int *color_space = va_arg(args, int *);
    419                 if (private_handle_t::validate(hnd)) {
    420                     return res;
    421                 }
    422                 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
    423                 if(metadata && metadata->operation & UPDATE_COLOR_SPACE) {
    424                     *color_space = metadata->colorSpace;
    425                     res = 0;
    426                 }
    427             } break;
    428         case GRALLOC_MODULE_PERFORM_GET_YUV_PLANE_INFO:
    429             {
    430                 private_handle_t* hnd =  va_arg(args, private_handle_t*);
    431                 android_ycbcr* ycbcr = va_arg(args, struct android_ycbcr *);
    432                 if (!private_handle_t::validate(hnd)) {
    433                     res = getYUVPlaneInfo(hnd, ycbcr);
    434                 }
    435             } break;
    436 
    437         default:
    438             break;
    439     }
    440     va_end(args);
    441     return res;
    442 }
    443