Merge "gralloc1: Fix RAW10 stride"
diff --git a/libgralloc1/gr_allocator.cpp b/libgralloc1/gr_allocator.cpp
index aba6dc5..4b20fc3 100644
--- a/libgralloc1/gr_allocator.cpp
+++ b/libgralloc1/gr_allocator.cpp
@@ -129,6 +129,13 @@
return -EINVAL;
}
+int Allocator::ImportBuffer(int fd) {
+ if (ion_allocator_) {
+ return ion_allocator_->ImportBuffer(fd);
+ }
+ return -EINVAL;
+}
+
int Allocator::FreeBuffer(void *base, unsigned int size, unsigned int offset, int fd,
int handle) {
if (ion_allocator_) {
@@ -138,9 +145,9 @@
return -EINVAL;
}
-int Allocator::CleanBuffer(void *base, unsigned int size, unsigned int offset, int fd, int op) {
+int Allocator::CleanBuffer(void *base, unsigned int size, unsigned int offset, int handle, int op) {
if (ion_allocator_) {
- return ion_allocator_->CleanBuffer(base, size, offset, fd, op);
+ return ion_allocator_->CleanBuffer(base, size, offset, handle, op);
}
return -EINVAL;
@@ -777,7 +784,7 @@
aligned_w = ALIGN(width, 16);
break;
case HAL_PIXEL_FORMAT_RAW10:
- aligned_w = ALIGN(width * 10 / 8, 16);
+ aligned_w = ALIGN(width * 10 / 8, 8);
break;
case HAL_PIXEL_FORMAT_RAW8:
aligned_w = ALIGN(width, 8);
diff --git a/libgralloc1/gr_allocator.h b/libgralloc1/gr_allocator.h
index e73bd8c..df1a30c 100644
--- a/libgralloc1/gr_allocator.h
+++ b/libgralloc1/gr_allocator.h
@@ -51,8 +51,9 @@
~Allocator();
bool Init();
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 fd, int op);
+ int CleanBuffer(void *base, unsigned int size, unsigned int offset, int handle, int op);
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
diff --git a/libgralloc1/gr_buf_mgr.cpp b/libgralloc1/gr_buf_mgr.cpp
index e2cfdd4..b471764 100644
--- a/libgralloc1/gr_buf_mgr.cpp
+++ b/libgralloc1/gr_buf_mgr.cpp
@@ -155,6 +155,7 @@
void BufferManager::CreateSharedHandle(buffer_handle_t inbuffer, const BufferDescriptor &descriptor,
buffer_handle_t *outbuffer) {
+ // TODO(user): This path is not verified
private_handle_t const *input = reinterpret_cast<private_handle_t const *>(inbuffer);
// Get Buffer attributes or dimension
@@ -182,8 +183,7 @@
descriptor.GetConsumerUsage());
out_hnd->id = ++next_id_;
// TODO(user): Base address of shared handle and ion handles
- auto buffer = std::make_shared<Buffer>(out_hnd);
- handles_map_.emplace(std::make_pair(out_hnd, buffer));
+ RegisterHandle(out_hnd, -1, -1);
*outbuffer = out_hnd;
}
@@ -201,10 +201,49 @@
}
// TODO(user): delete handle once framework bug around this is confirmed
- // to be resolved
+ // to be resolved. This is tracked in bug 36355756
+ private_handle_t * handle = const_cast<private_handle_t *>(hnd);
+ handle->fd = -1;
+ handle->fd_metadata = -1;
return GRALLOC1_ERROR_NONE;
}
+void BufferManager::RegisterHandle(const private_handle_t *hnd,
+ int ion_handle,
+ int ion_handle_meta) {
+ auto buffer = std::make_shared<Buffer>(hnd, ion_handle, ion_handle_meta);
+ handles_map_.emplace(std::make_pair(hnd, buffer));
+}
+
+gralloc1_error_t BufferManager::ImportHandle(private_handle_t* hnd) {
+ int ion_handle = allocator_->ImportBuffer(hnd->fd);
+ if (ion_handle < 0) {
+ ALOGE("Failed to import ion buffer: hnd: %p, fd:%d, id:%" PRIu64, hnd, hnd->fd, hnd->id);
+ return GRALLOC1_ERROR_BAD_HANDLE;
+ }
+ int ion_handle_meta = allocator_->ImportBuffer(hnd->fd_metadata);
+ if (ion_handle_meta < 0) {
+ ALOGE("Failed to import ion metadata buffer: hnd: %p, fd:%d, id:%" PRIu64, hnd,
+ hnd->fd, hnd->id);
+ return GRALLOC1_ERROR_BAD_HANDLE;
+ }
+ // Set base pointers to NULL since the data here was received over binder
+ hnd->base = 0;
+ hnd->base_metadata = 0;
+ RegisterHandle(hnd, ion_handle, ion_handle_meta);
+ return GRALLOC1_ERROR_NONE;
+}
+
+std::shared_ptr<BufferManager::Buffer>
+BufferManager::GetBufferFromHandle(const private_handle_t *hnd) {
+ auto it = handles_map_.find(hnd);
+ if (it != handles_map_.end()) {
+ return it->second;
+ } else {
+ return nullptr;
+ }
+}
+
gralloc1_error_t BufferManager::MapBuffer(private_handle_t const *handle) {
private_handle_t *hnd = const_cast<private_handle_t *>(handle);
@@ -215,7 +254,7 @@
return GRALLOC1_ERROR_BAD_HANDLE;
}
- unsigned int size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE);
+ unsigned int size = ALIGN((unsigned int)sizeof(MetaData_t), getpagesize());
if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base_metadata), size,
hnd->offset_metadata, hnd->fd_metadata) != 0) {
return GRALLOC1_ERROR_BAD_HANDLE;
@@ -227,39 +266,32 @@
gralloc1_error_t BufferManager::RetainBuffer(private_handle_t const *hnd) {
std::lock_guard<std::mutex> lock(locker_);
ALOGD_IF(DEBUG, "Retain buffer handle:%p id: %" PRIu64, hnd, hnd->id);
-
- // find if this handle is already in map
- auto it = handles_map_.find(hnd);
- if (it != handles_map_.end()) {
- // It's already in map, Just increment refcnt
- // No need to mmap the memory.
- auto buf = it->second;
- buf->ref_count++;
+ gralloc1_error_t err = GRALLOC1_ERROR_NONE;
+ auto buf = GetBufferFromHandle(hnd);
+ if (buf != nullptr) {
+ buf->IncRef();
} else {
- // not present in the map. mmap and then add entry to map
- if (MapBuffer(hnd) == GRALLOC1_ERROR_NONE) {
- auto buffer = std::make_shared<Buffer>(hnd);
- handles_map_.emplace(std::make_pair(hnd, buffer));
+ private_handle_t *handle = const_cast<private_handle_t *>(hnd);
+ err = ImportHandle(handle);
+ if (err == GRALLOC1_ERROR_NONE) {
+ // TODO(user): Do not map here, map should be in lock()
+ err = MapBuffer(hnd);
}
}
-
- return GRALLOC1_ERROR_NONE;
+ return err;
}
gralloc1_error_t BufferManager::ReleaseBuffer(private_handle_t const *hnd) {
std::lock_guard<std::mutex> lock(locker_);
ALOGD_IF(DEBUG, "Release buffer handle:%p id: %" PRIu64, hnd, hnd->id);
- // find if this handle is already in map
- auto it = handles_map_.find(hnd);
- if (it == handles_map_.end()) {
- // Corrupt handle or map.
- ALOGE("Could not find handle");
+ auto buf = GetBufferFromHandle(hnd);
+ if (buf == nullptr) {
+ ALOGE("Could not find handle: %p id: %" PRIu64, hnd, hnd->id);
return GRALLOC1_ERROR_BAD_HANDLE;
} else {
- auto buf = it->second;
- buf->ref_count--;
- if (buf->ref_count == 0) {
- handles_map_.erase(it);
+ if (buf->DecRef()) {
+ handles_map_.erase(hnd);
+ // Unmap, close ion handle and close fd
FreeBuffer(buf);
}
}
@@ -269,6 +301,7 @@
gralloc1_error_t BufferManager::LockBuffer(const private_handle_t *hnd,
gralloc1_producer_usage_t prod_usage,
gralloc1_consumer_usage_t cons_usage) {
+ std::lock_guard<std::mutex> lock(locker_);
gralloc1_error_t err = GRALLOC1_ERROR_NONE;
// If buffer is not meant for CPU return err
@@ -278,18 +311,23 @@
if (hnd->base == 0) {
// we need to map for real
- locker_.lock();
err = MapBuffer(hnd);
- locker_.unlock();
+ }
+
+ auto buf = GetBufferFromHandle(hnd);
+ if (buf == nullptr) {
+ return GRALLOC1_ERROR_BAD_HANDLE;
}
// Invalidate if CPU reads in software and there are non-CPU
// writers. No need to do this for the metadata buffer as it is
// only read/written in software.
+
+ // todo use handle here
if (!err && (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) &&
(hnd->flags & private_handle_t::PRIV_FLAGS_CACHED)) {
if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
- hnd->fd, CACHE_INVALIDATE)) {
+ buf->ion_handle_main, CACHE_INVALIDATE)) {
return GRALLOC1_ERROR_BAD_HANDLE;
}
}
@@ -304,20 +342,23 @@
}
gralloc1_error_t BufferManager::UnlockBuffer(const private_handle_t *handle) {
+ std::lock_guard<std::mutex> lock(locker_);
gralloc1_error_t status = GRALLOC1_ERROR_NONE;
- locker_.lock();
private_handle_t *hnd = const_cast<private_handle_t *>(handle);
+ auto buf = GetBufferFromHandle(hnd);
+ if (buf == nullptr) {
+ return GRALLOC1_ERROR_BAD_HANDLE;
+ }
if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
- hnd->fd, CACHE_CLEAN) != 0) {
+ buf->ion_handle_main, CACHE_CLEAN) != 0) {
status = GRALLOC1_ERROR_BAD_HANDLE;
}
hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
}
- locker_.unlock();
return status;
}
@@ -459,8 +500,7 @@
ColorSpace_t colorSpace = ITU_R_601;
setMetaData(hnd, UPDATE_COLOR_SPACE, reinterpret_cast<void *>(&colorSpace));
*handle = hnd;
- auto buffer = std::make_shared<Buffer>(hnd, data.ion_handle, e_data.ion_handle);
- handles_map_.emplace(std::make_pair(hnd, buffer));
+ RegisterHandle(hnd, data.ion_handle, e_data.ion_handle);
ALOGD_IF(DEBUG, "Allocated buffer handle: %p id: %" PRIu64, hnd, hnd->id);
if (DEBUG) {
private_handle_t::Dump(hnd);
diff --git a/libgralloc1/gr_buf_mgr.h b/libgralloc1/gr_buf_mgr.h
index 95b64ef..0677d96 100644
--- a/libgralloc1/gr_buf_mgr.h
+++ b/libgralloc1/gr_buf_mgr.h
@@ -86,6 +86,12 @@
void CreateSharedHandle(buffer_handle_t inbuffer, const BufferDescriptor &descriptor,
buffer_handle_t *out_buffer);
+ // Imports the ion fds into the current process. Returns an error for invalid handles
+ gralloc1_error_t ImportHandle(private_handle_t* hnd);
+
+ // Creates a Buffer from the valid private handle and adds it to the map
+ void RegisterHandle(const private_handle_t *hnd, int ion_handle, int ion_handle_meta);
+
// Wrapper structure over private handle
// Values associated with the private handle
// that do not need to go over IPC can be placed here
@@ -106,9 +112,15 @@
ion_handle_main(ih_main),
ion_handle_meta(ih_meta) {
}
+ void IncRef() { ++ref_count; }
+ bool DecRef() { return --ref_count == 0; }
};
+
gralloc1_error_t FreeBuffer(std::shared_ptr<Buffer> buf);
+ // Get the wrapper Buffer object from the handle, returns nullptr if handle is not found
+ std::shared_ptr<Buffer> GetBufferFromHandle(const private_handle_t *hnd);
+
bool map_fb_mem_ = false;
bool ubwc_for_fb_ = false;
Allocator *allocator_ = NULL;
diff --git a/libgralloc1/gr_ion_alloc.cpp b/libgralloc1/gr_ion_alloc.cpp
index b76fa9f..25792e5 100644
--- a/libgralloc1/gr_ion_alloc.cpp
+++ b/libgralloc1/gr_ion_alloc.cpp
@@ -123,11 +123,13 @@
if (base) {
err = UnmapBuffer(base, size, offset);
}
- struct ion_handle_data handle_data;
- handle_data.handle = ion_handle;
- ioctl(ion_dev_fd_, INT(ION_IOC_FREE), &handle_data);
- close(fd);
+ if (ion_handle > 0) {
+ struct ion_handle_data handle_data;
+ handle_data.handle = ion_handle;
+ ioctl(ion_dev_fd_, INT(ION_IOC_FREE), &handle_data);
+ }
+ close(fd);
return err;
}
@@ -150,6 +152,18 @@
return err;
}
+int IonAlloc::ImportBuffer(int fd) {
+ struct ion_fd_data fd_data;
+ int err = 0;
+ fd_data.fd = fd;
+ if (ioctl(ion_dev_fd_, INT(ION_IOC_IMPORT), &fd_data)) {
+ err = -errno;
+ ALOGE("%s: ION_IOC_IMPORT failed with error - %s", __FUNCTION__, strerror(errno));
+ return err;
+ }
+ 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);
@@ -163,23 +177,13 @@
return err;
}
-int IonAlloc::CleanBuffer(void *base, unsigned int size, unsigned int offset, int fd, int op) {
+int IonAlloc::CleanBuffer(void *base, unsigned int size, unsigned int offset, int handle, int op) {
ATRACE_CALL();
ATRACE_INT("operation id", op);
struct ion_flush_data flush_data;
- struct ion_fd_data fd_data;
- struct ion_handle_data handle_data;
int err = 0;
- fd_data.fd = fd;
- if (ioctl(ion_dev_fd_, INT(ION_IOC_IMPORT), &fd_data)) {
- err = -errno;
- ALOGE("%s: ION_IOC_IMPORT failed with error - %s", __FUNCTION__, strerror(errno));
- return err;
- }
-
- handle_data.handle = fd_data.handle;
- flush_data.handle = fd_data.handle;
+ flush_data.handle = handle;
flush_data.vaddr = base;
// offset and length are unsigned int
flush_data.offset = offset;
@@ -202,12 +206,9 @@
if (ioctl(ion_dev_fd_, INT(ION_IOC_CUSTOM), &d)) {
err = -errno;
ALOGE("%s: ION_IOC_CLEAN_INV_CACHES failed with error - %s", __FUNCTION__, strerror(errno));
- ioctl(ion_dev_fd_, INT(ION_IOC_FREE), &handle_data);
return err;
}
- ioctl(ion_dev_fd_, INT(ION_IOC_FREE), &handle_data);
-
return 0;
}
diff --git a/libgralloc1/gr_ion_alloc.h b/libgralloc1/gr_ion_alloc.h
index 68f453c..b25f509 100644
--- a/libgralloc1/gr_ion_alloc.h
+++ b/libgralloc1/gr_ion_alloc.h
@@ -66,8 +66,9 @@
int AllocBuffer(AllocData *data);
int FreeBuffer(void *base, unsigned int size, unsigned int offset, int fd, int ion_handle);
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 fd, int op);
+ int CleanBuffer(void *base, unsigned int size, unsigned int offset, int handle, int op);
private:
const char *kIonDevice = "/dev/ion";
diff --git a/sdm/libs/hwc2/hwc_buffer_allocator.cpp b/sdm/libs/hwc2/hwc_buffer_allocator.cpp
index 5e3cd86..29963a6 100644
--- a/sdm/libs/hwc2/hwc_buffer_allocator.cpp
+++ b/sdm/libs/hwc2/hwc_buffer_allocator.cpp
@@ -106,6 +106,11 @@
alloc_buffer_info->fd = -1;
alloc_buffer_info->stride = 0;
alloc_buffer_info->size = 0;
+ // Works around b/36355756
+ if (hnd != nullptr) {
+ delete hnd;
+ }
+ buffer_info->private_data = NULL;
return err;
}