From 19d5465b5e01dabf546df9e8c89471b912fd4a47 Mon Sep 17 00:00:00 2001 From: Devpushp Ohri Date: Mon, 11 Nov 2019 11:09:43 +0530 Subject: [PATCH] gpu_tonemapper: ion fix Updating EGLImageWrapper since ion cookie is deprecated. Unique dmabuf names are required to replace ion cookie. LruCache does not support string keys, additional string to int map added. Properly fixes change: I6b3360cf0f8eb87cfc0a3acf9b7244c0d7d54001 Change-Id: I440a181fd60c4e002e183860c2dbeff50a0bf23d CRs-Fixed: 2186983 --- gpu_tonemapper/EGLImageWrapper.cpp | 186 +++++++++++++++++++---------- gpu_tonemapper/EGLImageWrapper.h | 49 +++++--- gpu_tonemapper/Tonemapper.cpp | 12 +- sdm/libs/hwc2/Android.mk | 3 + 4 files changed, 163 insertions(+), 87 deletions(-) diff --git a/gpu_tonemapper/EGLImageWrapper.cpp b/gpu_tonemapper/EGLImageWrapper.cpp index dfc16d84..65f5e5ba 100644 --- a/gpu_tonemapper/EGLImageWrapper.cpp +++ b/gpu_tonemapper/EGLImageWrapper.cpp @@ -22,10 +22,19 @@ #include #include #include -#include +#include +#include +#include +using std::string; +using std::map; +using std::pair; + +static string pidString = std::to_string(getpid()); + +#ifndef TARGET_ION_ABI_VERSION //----------------------------------------------------------------------------- -void free_ion_cookie(int ion_fd, int cookie) +static void free_ion_cookie(int ion_fd, int cookie) //----------------------------------------------------------------------------- { if (ion_fd && !ioctl(ion_fd, ION_IOC_FREE, &cookie)) { @@ -35,120 +44,167 @@ void free_ion_cookie(int ion_fd, int cookie) } //----------------------------------------------------------------------------- -int get_ion_cookie(int ion_fd, int fd) +static int get_ion_cookie(int ion_fd, int fd) //----------------------------------------------------------------------------- { - int cookie = fd; + int cookie = fd; - struct ion_fd_data fdData; - memset(&fdData, 0, sizeof(fdData)); - fdData.fd = fd; + struct ion_fd_data fdData; + memset(&fdData, 0, sizeof(fdData)); + fdData.fd = fd; - if (ion_fd && !ioctl(ion_fd, ION_IOC_IMPORT, &fdData)) { - cookie = fdData.handle; - } else { - ALOGE("ION_IOC_IMPORT failed: ion_fd = %d, fd = %d", ion_fd, fd); - } + if (ion_fd && !ioctl(ion_fd, ION_IOC_IMPORT, &fdData)) { + cookie = fdData.handle; + } else { + ALOGE("ION_IOC_IMPORT failed: ion_fd = %d, fd = %d", ion_fd, fd); + } - return cookie; + return cookie; } - +#else //----------------------------------------------------------------------------- -EGLImageWrapper::DeleteEGLImageCallback::DeleteEGLImageCallback(int fd) +static string get_ion_buff_str(int buff_fd) //----------------------------------------------------------------------------- { - ion_fd = fd; + string retStr = {}; + if (buff_fd >= 0) { + string fdString = std::to_string(buff_fd); + string symlinkPath = "/proc/"+pidString+"/fd/"+fdString; + char buffer[1024] = {}; + ssize_t ret = ::readlink(symlinkPath.c_str(), buffer, sizeof(buffer) - 1); + if (ret != -1) { + buffer[ret] = '\0'; + retStr = buffer; + } + } + + return retStr; } +#endif //----------------------------------------------------------------------------- -void EGLImageWrapper::DeleteEGLImageCallback::operator()(int& k, EGLImageBuffer*& eglImage) +void EGLImageWrapper::DeleteEGLImageCallback::operator()(int& buffInt, EGLImageBuffer*& eglImage) //----------------------------------------------------------------------------- { - free_ion_cookie(ion_fd, k); - if( eglImage != 0 ) - { - delete eglImage; + if (eglImage != 0) { + delete eglImage; + } + +#ifndef TARGET_ION_ABI_VERSION + free_ion_cookie(ion_fd, buffInt /* cookie */); +#else + if (!mapClearPending) { + for (auto it = buffStrbuffIntMapPtr->begin(); it != buffStrbuffIntMapPtr->end(); it++) { + if (it->second == buffInt /* counter */) { + buffStrbuffIntMapPtr->erase(it); + return; + } } + } +#endif } //----------------------------------------------------------------------------- EGLImageWrapper::EGLImageWrapper() //----------------------------------------------------------------------------- { - eglImageBufferMap = new android::LruCache(32); - ion_fd = open("/dev/ion", O_RDONLY); - callback = new DeleteEGLImageCallback(ion_fd); - eglImageBufferMap->setOnEntryRemovedListener(callback); + eglImageBufferCache = new android::LruCache(32); + callback = new DeleteEGLImageCallback(&buffStrbuffIntMap); + eglImageBufferCache->setOnEntryRemovedListener(callback); + +#ifndef TARGET_ION_ABI_VERSION + ion_fd = open("/dev/ion", O_RDONLY); + callback->ion_fd = ion_fd; +#endif } //----------------------------------------------------------------------------- EGLImageWrapper::~EGLImageWrapper() //----------------------------------------------------------------------------- { - if( eglImageBufferMap != 0 ) - { - eglImageBufferMap->clear(); - delete eglImageBufferMap; - eglImageBufferMap = 0; + if (eglImageBufferCache != 0) { + if (callback != 0) { + callback->mapClearPending = true; } + eglImageBufferCache->clear(); + delete eglImageBufferCache; + eglImageBufferCache = 0; + buffStrbuffIntMap.clear(); + } - if( callback != 0 ) - { - delete callback; - callback = 0; - } + if (callback != 0) { + delete callback; + callback = 0; + } - if( ion_fd > 0 ) - { - close(ion_fd); - } +#ifndef TARGET_ION_ABI_VERSION + if (ion_fd > 0) { + close(ion_fd); ion_fd = -1; + } +#endif } + //----------------------------------------------------------------------------- static EGLImageBuffer* L_wrap(const private_handle_t *src) //----------------------------------------------------------------------------- { - EGLImageBuffer* result = 0; + EGLImageBuffer* result = 0; - native_handle_t *native_handle = const_cast(src); + native_handle_t *native_handle = const_cast(src); - int flags = android::GraphicBuffer::USAGE_HW_TEXTURE | - android::GraphicBuffer::USAGE_SW_READ_NEVER | - android::GraphicBuffer::USAGE_SW_WRITE_NEVER; + int flags = android::GraphicBuffer::USAGE_HW_TEXTURE | + android::GraphicBuffer::USAGE_SW_READ_NEVER | + android::GraphicBuffer::USAGE_SW_WRITE_NEVER; - if (src->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) { - flags |= android::GraphicBuffer::USAGE_PROTECTED; - } + if (src->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) { + flags |= android::GraphicBuffer::USAGE_PROTECTED; + } - android::sp graphicBuffer = - new android::GraphicBuffer(src->unaligned_width, src->unaligned_height, src->format, + android::sp graphicBuffer = + new android::GraphicBuffer(src->unaligned_width, src->unaligned_height, src->format, #ifndef __NOUGAT__ - 1, // Layer count + 1, // Layer count #endif - flags, src->width /*src->stride*/, - native_handle, false); + flags, src->width /*src->stride*/, + native_handle, false); - result = new EGLImageBuffer(graphicBuffer); + result = new EGLImageBuffer(graphicBuffer); - return result; + return result; } //----------------------------------------------------------------------------- EGLImageBuffer *EGLImageWrapper::wrap(const void *pvt_handle) //----------------------------------------------------------------------------- { - const private_handle_t *src = static_cast(pvt_handle); - - int ion_cookie = get_ion_cookie(ion_fd, src->fd); - EGLImageBuffer* eglImage = eglImageBufferMap->get(ion_cookie); - if( eglImage == 0 ) - { + const private_handle_t *src = static_cast(pvt_handle); + EGLImageBuffer* eglImage = nullptr; +#ifndef TARGET_ION_ABI_VERSION + int ion_cookie = get_ion_cookie(ion_fd, src->fd); + eglImage = eglImageBufferCache->get(ion_cookie); + if (eglImage == 0) { + eglImage = L_wrap(src); + eglImageBufferCache->put(ion_cookie, eglImage); + } else { + free_ion_cookie(ion_fd, ion_cookie); + } +#else + string buffStr = get_ion_buff_str(src->fd); + if (!buffStr.empty()) { + auto it = buffStrbuffIntMap.find(buffStr); + if (it != buffStrbuffIntMap.end()) { + eglImage = eglImageBufferCache->get(it->second); + } else { eglImage = L_wrap(src); - eglImageBufferMap->put(ion_cookie, eglImage); - } - else { - free_ion_cookie(ion_fd, ion_cookie); + buffStrbuffIntMap.insert(pair(buffStr, buffInt)); + eglImageBufferCache->put(buffInt, eglImage); + buffInt++; } + } else { + ALOGE("Could not provide an eglImage for fd = %d, EGLImageWrapper = %p", src->fd, this); + } +#endif - return eglImage; + return eglImage; } diff --git a/gpu_tonemapper/EGLImageWrapper.h b/gpu_tonemapper/EGLImageWrapper.h index e9a4d68f..296aa667 100644 --- a/gpu_tonemapper/EGLImageWrapper.h +++ b/gpu_tonemapper/EGLImageWrapper.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * Not a Contribution. * * Copyright 2015 The Android Open Source Project @@ -21,27 +21,40 @@ #define __TONEMAPPER_EGLIMAGEWRAPPER_H__ #include +#include +#include +#include #include "EGLImageBuffer.h" +using std::string; +using std::map; + class EGLImageWrapper { - private: - class DeleteEGLImageCallback : public android::OnEntryRemoved - { - private: - int ion_fd; - public: - DeleteEGLImageCallback(int ion_fd); - void operator()(int& ion_cookie, EGLImageBuffer*& eglImage); - }; + private: + class DeleteEGLImageCallback : public android::OnEntryRemoved { + public: + explicit DeleteEGLImageCallback(map* mapPtr) { buffStrbuffIntMapPtr = mapPtr; } + void operator()(int& buffInt, EGLImageBuffer*& eglImage); + map* buffStrbuffIntMapPtr = nullptr; + bool mapClearPending = false; + #ifndef TARGET_ION_ABI_VERSION + int ion_fd = -1; + #endif + }; - android::LruCache* eglImageBufferMap; - DeleteEGLImageCallback* callback; - int ion_fd; + android::LruCache* eglImageBufferCache; + map buffStrbuffIntMap = {}; + DeleteEGLImageCallback* callback = 0; + #ifndef TARGET_ION_ABI_VERSION + int ion_fd = -1; + #else + uint64_t buffInt = 0; + #endif - public: - EGLImageWrapper(); - ~EGLImageWrapper(); - EGLImageBuffer* wrap(const void *pvt_handle); + public: + EGLImageWrapper(); + ~EGLImageWrapper(); + EGLImageBuffer* wrap(const void *pvt_handle); }; -#endif //__TONEMAPPER_EGLIMAGEWRAPPER_H__ +#endif // __TONEMAPPER_EGLIMAGEWRAPPER_H__ diff --git a/gpu_tonemapper/Tonemapper.cpp b/gpu_tonemapper/Tonemapper.cpp index 811e091a..2605c7fe 100644 --- a/gpu_tonemapper/Tonemapper.cpp +++ b/gpu_tonemapper/Tonemapper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * Not a Contribution. * * Copyright 2015 The Android Open Source Project @@ -137,10 +137,14 @@ int Tonemapper::blit(const void *dst, const void *src, int srcFenceFd) } // set destination - engine_setDestination(dst_buffer->getFramebuffer(), 0, 0, dst_buffer->getWidth(), - dst_buffer->getHeight()); + if (dst_buffer) { + engine_setDestination(dst_buffer->getFramebuffer(), 0, 0, dst_buffer->getWidth(), + dst_buffer->getHeight()); + } // set source - engine_setExternalInputBuffer(0, src_buffer->getTexture()); + if (src_buffer) { + engine_setExternalInputBuffer(0, src_buffer->getTexture()); + } // set 3d lut engine_set3DInputBuffer(1, tonemapTexture); // set non-uniform xform diff --git a/sdm/libs/hwc2/Android.mk b/sdm/libs/hwc2/Android.mk index a0ea3587..4746367b 100644 --- a/sdm/libs/hwc2/Android.mk +++ b/sdm/libs/hwc2/Android.mk @@ -9,6 +9,9 @@ LOCAL_VENDOR_MODULE := true LOCAL_MODULE_RELATIVE_PATH := hw LOCAL_MODULE_TAGS := optional LOCAL_C_INCLUDES := $(common_includes) +ifeq ($(TARGET_KERNEL_VERSION), 4.14) +LOCAL_C_INCLUDES += $(kernel_includes) +endif LOCAL_HEADER_LIBRARIES := display_headers LOCAL_CFLAGS := -Wno-missing-field-initializers -Wno-unused-parameter \