Home | History | Annotate | Download | only in camera
      1 /*
      2  * Copyright (C) Texas Instruments - http://www.ti.com/
      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 #include "CameraHal.h"
     18 #include "TICameraParameters.h"
     19 
     20 extern "C" {
     21 
     22 //#include <timm_osal_interfaces.h>
     23 //#include <timm_osal_trace.h>
     24 
     25 
     26 };
     27 
     28 namespace Ti {
     29 namespace Camera {
     30 
     31 ///@todo Move these constants to a common header file, preferably in tiler.h
     32 #define STRIDE_8BIT (4 * 1024)
     33 #define STRIDE_16BIT (4 * 1024)
     34 
     35 #define ALLOCATION_2D 2
     36 
     37 ///Utility Macro Declarations
     38 
     39 /*--------------------MemoryManager Class STARTS here-----------------------------*/
     40 MemoryManager::MemoryManager() {
     41     mIonFd = -1;
     42 }
     43 
     44 MemoryManager::~MemoryManager() {
     45     if ( mIonFd >= 0 ) {
     46         ion_close(mIonFd);
     47         mIonFd = -1;
     48     }
     49 }
     50 
     51 status_t MemoryManager::initialize() {
     52     if ( mIonFd == -1 ) {
     53         mIonFd = ion_open();
     54         if ( mIonFd < 0 ) {
     55             CAMHAL_LOGE("ion_open() failed, error: %d", mIonFd);
     56             mIonFd = -1;
     57             return NO_INIT;
     58         }
     59     }
     60 
     61     return OK;
     62 }
     63 
     64 CameraBuffer* MemoryManager::allocateBufferList(int width, int height, const char* format, int &size, int numBufs)
     65 {
     66     LOG_FUNCTION_NAME;
     67 
     68     CAMHAL_ASSERT(mIonFd != -1);
     69 
     70     ///We allocate numBufs+1 because the last entry will be marked NULL to indicate end of array, which is used when freeing
     71     ///the buffers
     72     const uint numArrayEntriesC = (uint)(numBufs+1);
     73 
     74     ///Allocate a buffer array
     75     CameraBuffer *buffers = new CameraBuffer [numArrayEntriesC];
     76     if(!buffers) {
     77         CAMHAL_LOGEB("Allocation failed when creating buffers array of %d CameraBuffer elements", numArrayEntriesC);
     78         goto error;
     79     }
     80 
     81     ///Initialize the array with zeros - this will help us while freeing the array in case of error
     82     ///If a value of an array element is NULL, it means we didnt allocate it
     83     memset(buffers, 0, sizeof(CameraBuffer) * numArrayEntriesC);
     84 
     85     //2D Allocations are not supported currently
     86     if(size != 0) {
     87         struct ion_handle *handle;
     88         int mmap_fd;
     89         size_t stride;
     90 
     91         ///1D buffers
     92         for (int i = 0; i < numBufs; i++) {
     93             unsigned char *data;
     94             int ret = ion_alloc(mIonFd, size, 0, 1 << ION_HEAP_TYPE_CARVEOUT,
     95                     &handle);
     96             if((ret < 0) || ((int)handle == -ENOMEM)) {
     97                 ret = ion_alloc_tiler(mIonFd, (size_t)size, 1, TILER_PIXEL_FMT_PAGE,
     98                 OMAP_ION_HEAP_TILER_MASK, &handle, &stride);
     99             }
    100 
    101             if((ret < 0) || ((int)handle == -ENOMEM)) {
    102                 CAMHAL_LOGEB("FAILED to allocate ion buffer of size=%d. ret=%d(0x%x)", size, ret, ret);
    103                 goto error;
    104             }
    105 
    106             CAMHAL_LOGDB("Before mapping, handle = %p, nSize = %d", handle, size);
    107             if ((ret = ion_map(mIonFd, handle, size, PROT_READ | PROT_WRITE, MAP_SHARED, 0,
    108                           &data, &mmap_fd)) < 0) {
    109                 CAMHAL_LOGEB("Userspace mapping of ION buffers returned error %d", ret);
    110                 ion_free(mIonFd, handle);
    111                 goto error;
    112             }
    113 
    114             buffers[i].type = CAMERA_BUFFER_ION;
    115             buffers[i].opaque = data;
    116             buffers[i].mapped = data;
    117             buffers[i].ion_handle = handle;
    118             buffers[i].ion_fd = mIonFd;
    119             buffers[i].fd = mmap_fd;
    120             buffers[i].size = size;
    121             buffers[i].format = CameraHal::getPixelFormatConstant(format);
    122 
    123         }
    124     }
    125 
    126     LOG_FUNCTION_NAME_EXIT;
    127 
    128     return buffers;
    129 
    130 error:
    131 
    132     CAMHAL_LOGE("Freeing buffers already allocated after error occurred");
    133     if(buffers)
    134         freeBufferList(buffers);
    135 
    136     if ( NULL != mErrorNotifier.get() )
    137         mErrorNotifier->errorNotify(-ENOMEM);
    138     LOG_FUNCTION_NAME_EXIT;
    139 
    140     return NULL;
    141 }
    142 
    143 CameraBuffer* MemoryManager::getBufferList(int *numBufs) {
    144     LOG_FUNCTION_NAME;
    145     if (numBufs) *numBufs = -1;
    146 
    147     return NULL;
    148 }
    149 
    150 //TODO: Get needed data to map tiler buffers
    151 //Return dummy data for now
    152 uint32_t * MemoryManager::getOffsets()
    153 {
    154     LOG_FUNCTION_NAME;
    155 
    156     LOG_FUNCTION_NAME_EXIT;
    157 
    158     return NULL;
    159 }
    160 
    161 int MemoryManager::getFd()
    162 {
    163     LOG_FUNCTION_NAME;
    164 
    165     LOG_FUNCTION_NAME_EXIT;
    166 
    167     return -1;
    168 }
    169 
    170 int MemoryManager::freeBufferList(CameraBuffer *buffers)
    171 {
    172     status_t ret = NO_ERROR;
    173     LOG_FUNCTION_NAME;
    174 
    175     int i;
    176 
    177     if(!buffers)
    178         {
    179         CAMHAL_LOGEA("NULL pointer passed to freebuffer");
    180         LOG_FUNCTION_NAME_EXIT;
    181         return BAD_VALUE;
    182         }
    183 
    184     i = 0;
    185     while(buffers[i].type == CAMERA_BUFFER_ION)
    186         {
    187         if(buffers[i].size)
    188             {
    189             munmap(buffers[i].opaque, buffers[i].size);
    190             close(buffers[i].fd);
    191             ion_free(mIonFd, buffers[i].ion_handle);
    192             }
    193         else
    194             {
    195             CAMHAL_LOGEA("Not a valid Memory Manager buffer");
    196             }
    197         i++;
    198         }
    199 
    200     delete [] buffers;
    201 
    202     LOG_FUNCTION_NAME_EXIT;
    203     return ret;
    204 }
    205 
    206 status_t MemoryManager::setErrorHandler(ErrorNotifier *errorNotifier)
    207 {
    208     status_t ret = NO_ERROR;
    209 
    210     LOG_FUNCTION_NAME;
    211 
    212     if ( NULL == errorNotifier )
    213         {
    214         CAMHAL_LOGEA("Invalid Error Notifier reference");
    215         ret = -EINVAL;
    216         }
    217 
    218     if ( NO_ERROR == ret )
    219         {
    220         mErrorNotifier = errorNotifier;
    221         }
    222 
    223     LOG_FUNCTION_NAME_EXIT;
    224 
    225     return ret;
    226 }
    227 
    228 } // namespace Camera
    229 } // namespace Ti
    230 
    231 
    232 /*--------------------MemoryManager Class ENDS here-----------------------------*/
    233