Skip to content

Commit

Permalink
gpu_tonemapper: ion fix
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Devpushp Ohri committed Nov 11, 2019
1 parent 98abd17 commit 19d5465
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 87 deletions.
186 changes: 121 additions & 65 deletions gpu_tonemapper/EGLImageWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,19 @@
#include <gralloc_priv.h>
#include <ui/GraphicBuffer.h>
#include <fcntl.h>
#include <linux/msm_ion.h>
#include <string>
#include <map>
#include <utility>

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)) {
Expand All @@ -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<int, EGLImageBuffer*>(32);
ion_fd = open("/dev/ion", O_RDONLY);
callback = new DeleteEGLImageCallback(ion_fd);
eglImageBufferMap->setOnEntryRemovedListener(callback);
eglImageBufferCache = new android::LruCache<int, EGLImageBuffer*>(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<private_handle_t *>(src);
native_handle_t *native_handle = const_cast<private_handle_t *>(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<android::GraphicBuffer> graphicBuffer =
new android::GraphicBuffer(src->unaligned_width, src->unaligned_height, src->format,
android::sp<android::GraphicBuffer> 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<const private_handle_t *>(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<const private_handle_t *>(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<string, int>(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;
}
49 changes: 31 additions & 18 deletions gpu_tonemapper/EGLImageWrapper.h
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -21,27 +21,40 @@
#define __TONEMAPPER_EGLIMAGEWRAPPER_H__

#include <utils/LruCache.h>
#include <linux/msm_ion.h>
#include <string>
#include <map>
#include "EGLImageBuffer.h"

using std::string;
using std::map;

class EGLImageWrapper {
private:
class DeleteEGLImageCallback : public android::OnEntryRemoved<int, EGLImageBuffer*>
{
private:
int ion_fd;
public:
DeleteEGLImageCallback(int ion_fd);
void operator()(int& ion_cookie, EGLImageBuffer*& eglImage);
};
private:
class DeleteEGLImageCallback : public android::OnEntryRemoved<int, EGLImageBuffer*> {
public:
explicit DeleteEGLImageCallback(map<string, int>* mapPtr) { buffStrbuffIntMapPtr = mapPtr; }
void operator()(int& buffInt, EGLImageBuffer*& eglImage);
map<string, int>* buffStrbuffIntMapPtr = nullptr;
bool mapClearPending = false;
#ifndef TARGET_ION_ABI_VERSION
int ion_fd = -1;
#endif
};

android::LruCache<int, EGLImageBuffer *>* eglImageBufferMap;
DeleteEGLImageCallback* callback;
int ion_fd;
android::LruCache<int, EGLImageBuffer *>* eglImageBufferCache;
map<string, int> 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__
12 changes: 8 additions & 4 deletions gpu_tonemapper/Tonemapper.cpp
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions sdm/libs/hwc2/Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down

0 comments on commit 19d5465

Please sign in to comment.