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