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