14a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/* 24a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. 34a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * Not a Contribution. 44a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * 54a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * Copyright 2015 The Android Open Source Project 64a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * 74a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * Licensed under the Apache License, Version 2.0 (the "License"); 84a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * you may not use this file except in compliance with the License. 94a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * You may obtain a copy of the License at 104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * 114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * http://www.apache.org/licenses/LICENSE-2.0 124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * 134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * Unless required by applicable law or agreed to in writing, software 144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * distributed under the License is distributed on an "AS IS" BASIS, 154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * See the License for the specific language governing permissions and 174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * limitations under the License. 184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh */ 194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include "EGLImageWrapper.h" 214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <cutils/native_handle.h> 224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <gralloc_priv.h> 234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <ui/GraphicBuffer.h> 244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <fcntl.h> 254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <linux/msm_ion.h> 264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh//----------------------------------------------------------------------------- 284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhvoid free_ion_cookie(int ion_fd, int cookie) 294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh//----------------------------------------------------------------------------- 304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{ 314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if (ion_fd && !ioctl(ion_fd, ION_IOC_FREE, &cookie)) { 324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } else { 334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh ALOGE("ION_IOC_FREE failed: ion_fd = %d, cookie = %d", ion_fd, cookie); 344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh} 364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh//----------------------------------------------------------------------------- 384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhint get_ion_cookie(int ion_fd, int fd) 394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh//----------------------------------------------------------------------------- 404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{ 414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh int cookie = fd; 424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh struct ion_fd_data fdData; 444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh memset(&fdData, 0, sizeof(fdData)); 454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh fdData.fd = fd; 464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if (ion_fd && !ioctl(ion_fd, ION_IOC_IMPORT, &fdData)) { 484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh cookie = fdData.handle; 494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } else { 504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh ALOGE("ION_IOC_IMPORT failed: ion_fd = %d, fd = %d", ion_fd, fd); 514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh return cookie; 544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh} 554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh//----------------------------------------------------------------------------- 574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhEGLImageWrapper::DeleteEGLImageCallback::DeleteEGLImageCallback(int fd) 584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh//----------------------------------------------------------------------------- 594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{ 604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh ion_fd = fd; 614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh} 624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh//----------------------------------------------------------------------------- 644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhvoid EGLImageWrapper::DeleteEGLImageCallback::operator()(int& k, EGLImageBuffer*& eglImage) 654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh//----------------------------------------------------------------------------- 664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{ 674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh free_ion_cookie(ion_fd, k); 684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if( eglImage != 0 ) 694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh { 704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh delete eglImage; 714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh} 734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh//----------------------------------------------------------------------------- 754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhEGLImageWrapper::EGLImageWrapper() 764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh//----------------------------------------------------------------------------- 774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{ 784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh eglImageBufferMap = new android::LruCache<int, EGLImageBuffer*>(32); 794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh ion_fd = open("/dev/ion", O_RDONLY); 804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh callback = new DeleteEGLImageCallback(ion_fd); 814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh eglImageBufferMap->setOnEntryRemovedListener(callback); 824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh} 834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh//----------------------------------------------------------------------------- 854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhEGLImageWrapper::~EGLImageWrapper() 864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh//----------------------------------------------------------------------------- 874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{ 884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if( eglImageBufferMap != 0 ) 894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh { 904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh eglImageBufferMap->clear(); 914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh delete eglImageBufferMap; 924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh eglImageBufferMap = 0; 934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if( callback != 0 ) 964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh { 974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh delete callback; 984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh callback = 0; 994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 1004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 1014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if( ion_fd > 0 ) 1024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh { 1034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh close(ion_fd); 1044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 1054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh ion_fd = -1; 1064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh} 1074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh//----------------------------------------------------------------------------- 1084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic EGLImageBuffer* L_wrap(const private_handle_t *src) 1094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh//----------------------------------------------------------------------------- 1104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{ 1114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh EGLImageBuffer* result = 0; 1124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 1134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh native_handle_t *native_handle = const_cast<private_handle_t *>(src); 1144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 1154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh int flags = android::GraphicBuffer::USAGE_HW_TEXTURE | 1164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh android::GraphicBuffer::USAGE_SW_READ_NEVER | 1174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh android::GraphicBuffer::USAGE_SW_WRITE_NEVER; 1184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 1194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if (src->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) { 1204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh flags |= android::GraphicBuffer::USAGE_PROTECTED; 1214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 1224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 1234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh android::sp<android::GraphicBuffer> graphicBuffer = 1244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh new android::GraphicBuffer(src->unaligned_width, src->unaligned_height, src->format, 1254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#ifndef __NOUGAT__ 1264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 1, // Layer count 1274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#endif 1284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh flags, src->width /*src->stride*/, 1294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh native_handle, false); 1304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 1314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh result = new EGLImageBuffer(graphicBuffer); 1324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 1334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh return result; 1344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh} 1354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 1364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh//----------------------------------------------------------------------------- 1374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhEGLImageBuffer *EGLImageWrapper::wrap(const void *pvt_handle) 1384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh//----------------------------------------------------------------------------- 1394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{ 1404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh const private_handle_t *src = static_cast<const private_handle_t *>(pvt_handle); 1414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 1424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh int ion_cookie = get_ion_cookie(ion_fd, src->fd); 1434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh EGLImageBuffer* eglImage = eglImageBufferMap->get(ion_cookie); 1444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh if( eglImage == 0 ) 1454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh { 1464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh eglImage = L_wrap(src); 1474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh eglImageBufferMap->put(ion_cookie, eglImage); 1484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 1494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh else { 1504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh free_ion_cookie(ion_fd, ion_cookie); 1514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh } 1524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh 1534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh return eglImage; 1544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh} 155