Home | History | Annotate | Download | only in gpu_tonemapper
      1 /*
      2  * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
      3  * Not a Contribution.
      4  *
      5  * Copyright 2015 The Android Open Source Project
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  */
     19 
     20 #include "EGLImageWrapper.h"
     21 #include <cutils/native_handle.h>
     22 #include <gralloc_priv.h>
     23 #include <ui/GraphicBuffer.h>
     24 #include <fcntl.h>
     25 #include <linux/msm_ion.h>
     26 
     27 //-----------------------------------------------------------------------------
     28 void free_ion_cookie(int ion_fd, int cookie)
     29 //-----------------------------------------------------------------------------
     30 {
     31   if (ion_fd && !ioctl(ion_fd, ION_IOC_FREE, &cookie)) {
     32   } else {
     33       ALOGE("ION_IOC_FREE failed: ion_fd = %d, cookie = %d", ion_fd, cookie);
     34   }
     35 }
     36 
     37 //-----------------------------------------------------------------------------
     38 int get_ion_cookie(int ion_fd, int fd)
     39 //-----------------------------------------------------------------------------
     40 {
     41    int cookie = fd;
     42 
     43    struct ion_fd_data fdData;
     44    memset(&fdData, 0, sizeof(fdData));
     45    fdData.fd = fd;
     46 
     47    if (ion_fd && !ioctl(ion_fd, ION_IOC_IMPORT, &fdData)) {
     48         cookie = fdData.handle;
     49    } else {
     50         ALOGE("ION_IOC_IMPORT failed: ion_fd = %d, fd = %d", ion_fd, fd);
     51    }
     52 
     53    return cookie;
     54 }
     55 
     56 //-----------------------------------------------------------------------------
     57 EGLImageWrapper::DeleteEGLImageCallback::DeleteEGLImageCallback(int fd)
     58 //-----------------------------------------------------------------------------
     59 {
     60     ion_fd = fd;
     61 }
     62 
     63 //-----------------------------------------------------------------------------
     64 void EGLImageWrapper::DeleteEGLImageCallback::operator()(int& k, EGLImageBuffer*& eglImage)
     65 //-----------------------------------------------------------------------------
     66 {
     67     free_ion_cookie(ion_fd,  k);
     68     if( eglImage != 0 )
     69     {
     70         delete eglImage;
     71     }
     72 }
     73 
     74 //-----------------------------------------------------------------------------
     75 EGLImageWrapper::EGLImageWrapper()
     76 //-----------------------------------------------------------------------------
     77 {
     78     eglImageBufferMap = new android::LruCache<int, EGLImageBuffer*>(32);
     79     ion_fd = open("/dev/ion", O_RDONLY);
     80     callback = new DeleteEGLImageCallback(ion_fd);
     81     eglImageBufferMap->setOnEntryRemovedListener(callback);
     82 }
     83 
     84 //-----------------------------------------------------------------------------
     85 EGLImageWrapper::~EGLImageWrapper()
     86 //-----------------------------------------------------------------------------
     87 {
     88     if( eglImageBufferMap != 0 )
     89     {
     90         eglImageBufferMap->clear();
     91         delete eglImageBufferMap;
     92         eglImageBufferMap = 0;
     93     }
     94 
     95     if( callback != 0 )
     96     {
     97         delete callback;
     98         callback = 0;
     99     }
    100 
    101     if( ion_fd > 0 )
    102     {
    103         close(ion_fd);
    104     }
    105     ion_fd = -1;
    106 }
    107 //-----------------------------------------------------------------------------
    108 static EGLImageBuffer* L_wrap(const private_handle_t *src)
    109 //-----------------------------------------------------------------------------
    110 {
    111     EGLImageBuffer* result = 0;
    112 
    113     native_handle_t *native_handle = const_cast<private_handle_t *>(src);
    114 
    115     int flags = android::GraphicBuffer::USAGE_HW_TEXTURE |
    116                 android::GraphicBuffer::USAGE_SW_READ_NEVER |
    117                 android::GraphicBuffer::USAGE_SW_WRITE_NEVER;
    118 
    119     if (src->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
    120       flags |= android::GraphicBuffer::USAGE_PROTECTED;
    121     }
    122 
    123     android::sp<android::GraphicBuffer> graphicBuffer =
    124         new android::GraphicBuffer(src->unaligned_width, src->unaligned_height, src->format,
    125 #ifndef __NOUGAT__
    126                                    1, // Layer count
    127 #endif
    128                                    flags, src->width /*src->stride*/,
    129                                    native_handle, false);
    130 
    131     result = new EGLImageBuffer(graphicBuffer);
    132 
    133     return result;
    134 }
    135 
    136 //-----------------------------------------------------------------------------
    137 EGLImageBuffer *EGLImageWrapper::wrap(const void *pvt_handle)
    138 //-----------------------------------------------------------------------------
    139 {
    140     const private_handle_t *src = static_cast<const private_handle_t *>(pvt_handle);
    141 
    142     int ion_cookie = get_ion_cookie(ion_fd, src->fd);
    143     EGLImageBuffer* eglImage = eglImageBufferMap->get(ion_cookie);
    144     if( eglImage == 0 )
    145     {
    146         eglImage = L_wrap(src);
    147         eglImageBufferMap->put(ion_cookie, eglImage);
    148     }
    149     else {
    150         free_ion_cookie(ion_fd, ion_cookie);
    151     }
    152 
    153     return eglImage;
    154 }
    155