Skip to content

Commit

Permalink
gralloc: Changes to align to new ion api requirements
Browse files Browse the repository at this point in the history
Update ion handling in gralloc to align to new ion api
requirements.
Based on compile time flag TARGET_ION_ABI_VERSION,
gralloc will call old ion api or new libion apis

Change-Id: I9905a6a6edade9bcd70fa6e20b5593a26d088457
CRs-Fixed: 2185970
  • Loading branch information
Devpushp Ohri committed Nov 11, 2019
1 parent 98abd17 commit bb98d30
Show file tree
Hide file tree
Showing 6 changed files with 200 additions and 48 deletions.
19 changes: 16 additions & 3 deletions gralloc/Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,21 @@ LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := $(common_includes)

LOCAL_HEADER_LIBRARIES := display_headers
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdgralloc\" -Wall -Werror
LOCAL_SHARED_LIBRARIES := $(common_libs) libqdMetaData libsync libgrallocutils \
[email protected]
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdgralloc\" -Wall -Werror
ifeq ($(TARGET_KERNEL_VERSION), 4.14)
LOCAL_C_INCLUDES += external/libcxx/include \
system/core/libion/include/ \
system/core/libion/kernel-headers/ \
$(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
LOCAL_SHARED_LIBRARIES += libion
LOCAL_CFLAGS += -std=c++14
endif
LOCAL_HEADER_LIBRARIES := display_headers
ifneq ($(TARGET_KERNEL_VERSION), 4.14)
LOCAL_CFLAGS += -isystem $(kernel_includes)
endif
LOCAL_CLANG := true
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) $(kernel_deps)
LOCAL_SRC_FILES := gr_ion_alloc.cpp \
Expand All @@ -35,6 +44,10 @@ LOCAL_MODULE := libgrallocutils
LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
ifeq ($(TARGET_KERNEL_VERSION), 4.14)
LOCAL_C_INCLUDES += system/core/libion/include \
system/core/libion/kernel-headers
endif
LOCAL_HEADER_LIBRARIES := display_headers
LOCAL_SHARED_LIBRARIES := $(common_libs) libqdMetaData libdl [email protected]
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"grallocutils\" -Wno-sign-conversion
Expand Down
13 changes: 10 additions & 3 deletions gralloc/gr_allocator.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
* Copyright (c) 2011-2019, The Linux Foundation. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
Expand Down Expand Up @@ -49,6 +49,12 @@
#define ION_FLAG_CP_CAMERA_PREVIEW 0
#endif

#if TARGET_ION_ABI_VERSION >= 2
#ifndef ION_SECURE
#define ION_SECURE ION_FLAG_SECURE
#endif
#endif

#ifdef MASTER_SIDE_CP
#define CP_HEAP_ID ION_SECURE_HEAP_ID
#define SD_HEAP_ID ION_SECURE_DISPLAY_HEAP_ID
Expand Down Expand Up @@ -141,9 +147,10 @@ int Allocator::FreeBuffer(void *base, unsigned int size, unsigned int offset, in
return -EINVAL;
}

int Allocator::CleanBuffer(void *base, unsigned int size, unsigned int offset, int handle, int op) {
int Allocator::CleanBuffer(void *base, unsigned int size, unsigned int offset, int handle, int op,
int fd) {
if (ion_allocator_) {
return ion_allocator_->CleanBuffer(base, size, offset, handle, op);
return ion_allocator_->CleanBuffer(base, size, offset, handle, op, fd);
}

return -EINVAL;
Expand Down
3 changes: 1 addition & 2 deletions gralloc/gr_allocator.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/*
* Copyright (c) 2011-2017,2019, The Linux Foundation. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
Expand Down Expand Up @@ -47,7 +46,7 @@ class Allocator {
int MapBuffer(void **base, unsigned int size, unsigned int offset, int fd);
int ImportBuffer(int fd);
int FreeBuffer(void *base, unsigned int size, unsigned int offset, int fd, int handle);
int CleanBuffer(void *base, unsigned int size, unsigned int offset, int handle, int op);
int CleanBuffer(void *base, unsigned int size, unsigned int offset, int handle, int op, int fd);
int AllocateMem(AllocData *data, gralloc1_producer_usage_t prod_usage,
gralloc1_consumer_usage_t cons_usage);
// @return : index of the descriptor with maximum buffer size req
Expand Down
4 changes: 2 additions & 2 deletions gralloc/gr_buf_mgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ gralloc1_error_t BufferManager::LockBuffer(const private_handle_t *hnd,
if ((cons_usage & (GRALLOC1_CONSUMER_USAGE_CPU_READ | GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN))
&& (hnd->flags & private_handle_t::PRIV_FLAGS_NON_CPU_WRITER)) {
if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
buf->ion_handle_main, CACHE_INVALIDATE)) {
buf->ion_handle_main, CACHE_INVALIDATE, hnd->fd)) {

return GRALLOC1_ERROR_BAD_HANDLE;
}
Expand Down Expand Up @@ -375,7 +375,7 @@ gralloc1_error_t BufferManager::UnlockBuffer(const private_handle_t *handle) {

if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
buf->ion_handle_main, CACHE_CLEAN) != 0) {
buf->ion_handle_main, CACHE_CLEAN, hnd->fd) != 0) {
status = GRALLOC1_ERROR_BAD_HANDLE;
}
hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
Expand Down
202 changes: 167 additions & 35 deletions gralloc/gr_ion_alloc.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
* Copyright (c) 2011-2019, The Linux Foundation. All rights reserved.

* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
Expand Down Expand Up @@ -32,6 +32,11 @@
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <linux/msm_ion.h>
#if TARGET_ION_ABI_VERSION >= 2
#include <ion/ion.h>
#include <linux/dma-buf.h>
#endif
#include <stdlib.h>
#include <fcntl.h>
#include <log/log.h>
Expand All @@ -46,7 +51,7 @@ namespace gralloc1 {

bool IonAlloc::Init() {
if (ion_dev_fd_ == FD_INIT) {
ion_dev_fd_ = open(kIonDevice, O_RDONLY);
ion_dev_fd_ = OpenIonDevice();
}

if (ion_dev_fd_ < 0) {
Expand All @@ -58,6 +63,103 @@ bool IonAlloc::Init() {
return true;
}

#if TARGET_ION_ABI_VERSION >= 2 // Use libion APIs for new ion

int IonAlloc::OpenIonDevice() {
return ion_open();
}

void IonAlloc::CloseIonDevice() {
if (ion_dev_fd_ > FD_INIT) {
ion_close(ion_dev_fd_);
}

ion_dev_fd_ = FD_INIT;
}

int IonAlloc::AllocBuffer(AllocData *data) {
ATRACE_CALL();
int err = 0;
int fd = -1;
unsigned int flags = data->flags;

flags |= data->uncached ? 0 : ION_FLAG_CACHED;

std::string tag_name{};
if (ATRACE_ENABLED()) {
tag_name = "libion alloc size: " + std::to_string(data->size);
}

ATRACE_BEGIN(tag_name.c_str());
err = ion_alloc_fd(ion_dev_fd_, data->size, data->align, data->heap_id, flags, &fd);
ATRACE_END();
if (err) {
ALOGE("libion alloc failed");
return err;
}

data->fd = fd;
data->ion_handle = fd; // For new ion api ion_handle does not exists so reusing fd for now
ALOGD_IF(DEBUG, "libion: Allocated buffer size:%u fd:%d", data->size, data->fd);

return 0;
}

int IonAlloc::FreeBuffer(void *base, unsigned int size, unsigned int offset, int fd,
int /*ion_handle*/) {
ATRACE_CALL();
int err = 0;
ALOGD_IF(DEBUG, "libion: Freeing buffer base:%p size:%u fd:%d", base, size, fd);

if (base) {
err = UnmapBuffer(base, size, offset);
}

close(fd);
return err;
}

int IonAlloc::ImportBuffer(int fd) {
// For new ion api ion_handle does not exists so reusing fd for now
return fd;
}

int IonAlloc::CleanBuffer(void */*base*/, unsigned int /*size*/, unsigned int /*offset*/,
int /*handle*/, int op, int dma_buf_fd) {
ATRACE_CALL();
ATRACE_INT("operation id", op);

struct dma_buf_sync sync;
int err = 0;

switch (op) {
case CACHE_CLEAN:
sync.flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_RW;
break;
case CACHE_INVALIDATE:
sync.flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_RW;
break;
default:
ALOGE("%s: Invalid operation %d", __FUNCTION__, op);
return -1;
}

if (ioctl(dma_buf_fd, INT(DMA_BUF_IOCTL_SYNC), &sync)) {
err = -errno;
ALOGE("%s: DMA_BUF_IOCTL_SYNC failed with error - %s", __FUNCTION__, strerror(errno));
return err;
}

return 0;
}

#else
#ifndef TARGET_ION_ABI_VERSION // Use old ion apis directly

int IonAlloc::OpenIonDevice() {
return open(kIonDevice, O_RDONLY);
}

void IonAlloc::CloseIonDevice() {
if (ion_dev_fd_ > FD_INIT) {
close(ion_dev_fd_);
Expand Down Expand Up @@ -122,25 +224,6 @@ int IonAlloc::FreeBuffer(void *base, unsigned int size, unsigned int offset, int
return err;
}

int IonAlloc::MapBuffer(void **base, unsigned int size, unsigned int offset, int fd) {
ATRACE_CALL();
int err = 0;
void *addr = 0;

// It is a (quirky) requirement of ION to have opened the
// ion fd in the process that is doing the mapping
addr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
*base = addr;
if (addr == MAP_FAILED) {
err = -errno;
ALOGE("ion: Failed to map memory in the client: %s", strerror(errno));
} else {
ALOGD_IF(DEBUG, "ion: Mapped buffer base:%p size:%u offset:%u fd:%d", addr, size, offset, fd);
}

return err;
}

int IonAlloc::ImportBuffer(int fd) {
struct ion_fd_data fd_data;
int err = 0;
Expand All @@ -153,20 +236,8 @@ int IonAlloc::ImportBuffer(int fd) {
return fd_data.handle;
}

int IonAlloc::UnmapBuffer(void *base, unsigned int size, unsigned int /*offset*/) {
ATRACE_CALL();
ALOGD_IF(DEBUG, "ion: Unmapping buffer base:%p size:%u", base, size);

int err = 0;
if (munmap(base, size)) {
err = -errno;
ALOGE("ion: Failed to unmap memory at %p : %s", base, strerror(errno));
}

return err;
}

int IonAlloc::CleanBuffer(void *base, unsigned int size, unsigned int offset, int handle, int op) {
int IonAlloc::CleanBuffer(void *base, unsigned int size, unsigned int offset, int handle, int op,
int /*fd*/) {
ATRACE_CALL();
ATRACE_INT("operation id", op);
struct ion_flush_data flush_data;
Expand Down Expand Up @@ -201,4 +272,65 @@ int IonAlloc::CleanBuffer(void *base, unsigned int size, unsigned int offset, in
return 0;
}

#else // This ion version is not supported

int IonAlloc::OpenIonDevice() {
return -EINVAL;
}

void IonAlloc::CloseIonDevice() {
}

int IonAlloc::AllocBuffer(AllocData * /*data*/) {
return -EINVAL;
}

int IonAlloc::FreeBuffer(void * /*base*/, unsigned int /*size*/, unsigned int /*offset*/,
int /*fd*/, int /*ion_handle*/) {
return -EINVAL;
}

int IonAlloc::ImportBuffer(int /*fd*/) {
return -EINVAL;
}

int IonAlloc::CleanBuffer(void * /*base*/, unsigned int /*size*/, unsigned int /*offset*/,
int /*handle*/, int /*op*/, int /*fd*/) {
return -EINVAL;
}

#endif
#endif // TARGET_ION_ABI_VERSION


int IonAlloc::MapBuffer(void **base, unsigned int size, unsigned int offset, int fd) {
ATRACE_CALL();
int err = 0;
void *addr = 0;

addr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
*base = addr;
if (addr == MAP_FAILED) {
err = -errno;
ALOGE("ion: Failed to map memory in the client: %s", strerror(errno));
} else {
ALOGD_IF(DEBUG, "ion: Mapped buffer base:%p size:%u offset:%u fd:%d", addr, size, offset, fd);
}

return err;
}

int IonAlloc::UnmapBuffer(void *base, unsigned int size, unsigned int /*offset*/) {
ATRACE_CALL();
ALOGD_IF(DEBUG, "ion: Unmapping buffer base:%p size:%u", base, size);

int err = 0;
if (munmap(base, size)) {
err = -errno;
ALOGE("ion: Failed to unmap memory at %p : %s", base, strerror(errno));
}

return err;
}

} // namespace gralloc1
7 changes: 4 additions & 3 deletions gralloc/gr_ion_alloc.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
* Copyright (c) 2011-2019, The Linux Foundation. All rights reserved.

* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
Expand Down Expand Up @@ -68,10 +68,11 @@ class IonAlloc {
int MapBuffer(void **base, unsigned int size, unsigned int offset, int fd);
int ImportBuffer(int fd);
int UnmapBuffer(void *base, unsigned int size, unsigned int offset);
int CleanBuffer(void *base, unsigned int size, unsigned int offset, int handle, int op);

int CleanBuffer(void *base, unsigned int size, unsigned int offset, int handle, int op, int fd);
private:
#ifndef TARGET_ION_ABI_VERSION
const char *kIonDevice = "/dev/ion";
#endif

int OpenIonDevice();
void CloseIonDevice();
Expand Down

0 comments on commit bb98d30

Please sign in to comment.