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