commonsys-intf: display: Add display folders

Add libdisplayconfig and libqdmetadata to support
Single system image

CRs-Fixed: 2251141
Change-Id: Ie988c6d23bcc7f8e8f8f4313d8c3255f55d200ce
This commit is contained in:
Uday Kiran Pichika
2018-06-04 16:42:13 +05:30
parent 619cdf786c
commit 2d3a307cd3
224 changed files with 142 additions and 49487 deletions

View File

@@ -1,101 +0,0 @@
# Gralloc module
LOCAL_PATH := $(call my-dir)
include $(LOCAL_PATH)/../common.mk
include $(CLEAR_VARS)
LOCAL_MODULE := gralloc.$(TARGET_BOARD_PLATFORM)
LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := $(common_includes)
LOCAL_HEADER_LIBRARIES := display_headers
LOCAL_SHARED_LIBRARIES := $(common_libs) libqdMetaData libsync libgrallocutils \
libgralloccore android.hardware.graphics.mapper@2.0
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdgralloc\" -Wall -std=c++14 -Werror
LOCAL_CFLAGS += -isystem $(kernel_includes)
LOCAL_CLANG := true
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
LOCAL_SRC_FILES := gr_device_impl.cpp
LOCAL_COPY_HEADERS_TO := $(common_header_export_path)
LOCAL_COPY_HEADERS := gr_device_impl.h gralloc_priv.h gr_priv_handle.h
include $(BUILD_SHARED_LIBRARY)
#libgrallocutils
include $(CLEAR_VARS)
LOCAL_MODULE := libgrallocutils
LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
LOCAL_HEADER_LIBRARIES := display_headers
LOCAL_SHARED_LIBRARIES := $(common_libs) libqdMetaData libdl \
android.hardware.graphics.mapper@2.0
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdgralloc\" -Wno-sign-conversion
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
LOCAL_SRC_FILES := gr_utils.cpp gr_adreno_info.cpp
include $(BUILD_SHARED_LIBRARY)
#libgralloccore
include $(CLEAR_VARS)
LOCAL_MODULE := libgralloccore
LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
LOCAL_HEADER_LIBRARIES := display_headers
LOCAL_SHARED_LIBRARIES := $(common_libs) libqdMetaData libdl libgrallocutils \
android.hardware.graphics.mapper@2.0
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdgralloc\" -Wno-sign-conversion
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
LOCAL_SRC_FILES := gr_allocator.cpp gr_buf_mgr.cpp gr_ion_alloc.cpp
include $(BUILD_SHARED_LIBRARY)
qti_mapper_version := $(shell \
if [ -d "$(TOP)/vendor/qcom/opensource/interfaces/display/mapper/1.0" ];\
then echo QTI_MAPPER_1_0; fi)
qti_allocator_version := $(shell \
if [ -d "$(TOP)/vendor/qcom/opensource/interfaces/display/allocator/1.0" ];\
then echo QTI_ALLOCATOR_1_0; fi)
#mapper
include $(CLEAR_VARS)
LOCAL_MODULE := android.hardware.graphics.mapper@2.0-impl-qti-display
LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
LOCAL_HEADER_LIBRARIES := display_headers
LOCAL_SHARED_LIBRARIES := $(common_libs) \
libhidlbase \
libhidltransport \
libqdMetaData \
libgrallocutils \
libgralloccore \
libsync \
android.hardware.graphics.mapper@2.0
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdgralloc\" -Wno-sign-conversion
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
LOCAL_SRC_FILES := QtiMapper.cpp
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := vendor.qti.hardware.display.allocator@1.0-service
LOCAL_VENDOR_MODULE := true
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_MODULE_TAGS := optional
LOCAL_HEADER_LIBRARIES := display_headers
LOCAL_SHARED_LIBRARIES := $(common_libs) \
libhidlbase \
libhidltransport\
libqdMetaData \
libgrallocutils \
libgralloccore \
android.hardware.graphics.allocator@2.0
LOCAL_CFLAGS := -DLOG_TAG=\"qdgralloc\" $(common_flags)
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
LOCAL_SRC_FILES := QtiAllocator.cpp service.cpp
LOCAL_INIT_RC := vendor.qti.hardware.display.allocator@1.0-service.rc
include $(BUILD_EXECUTABLE)

View File

@@ -1,113 +0,0 @@
/*
* Copyright (c) 2018, 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:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define DEBUG 0
#include "QtiAllocator.h"
#include <log/log.h>
#include <vector>
#include "gr_utils.h"
namespace vendor {
namespace qti {
namespace hardware {
namespace display {
namespace allocator {
namespace V1_0 {
namespace implementation {
using android::hardware::hidl_handle;
using gralloc::BufferDescriptor;
QtiAllocator::QtiAllocator() {
buf_mgr_ = BufferManager::GetInstance();
}
// Methods from ::android::hardware::graphics::allocator::V2_0::IAllocator follow.
Return<void> QtiAllocator::dumpDebugInfo(dumpDebugInfo_cb hidl_cb) {
std::ostringstream os;
buf_mgr_->Dump(&os);
hidl_string reply;
reply.setToExternal(os.str().c_str(), os.str().length());
hidl_cb(reply);
return Void();
}
Return<void> QtiAllocator::allocate(const hidl_vec<uint32_t> &descriptor, uint32_t count,
allocate_cb hidl_cb) {
ALOGD_IF(DEBUG, "Allocating buffers count: %d", count);
gralloc::BufferDescriptor desc;
auto err = desc.Decode(descriptor);
if (err != Error::NONE) {
hidl_cb(err, 0, hidl_vec<hidl_handle>());
return Void();
}
std::vector<hidl_handle> buffers;
buffers.reserve(count);
for (uint32_t i = 0; i < count; i++) {
buffer_handle_t buffer;
ALOGD_IF(DEBUG, "buffer: %p", &buffer);
err = buf_mgr_->AllocateBuffer(desc, &buffer);
if (err != Error::NONE) {
break;
}
buffers.emplace_back(hidl_handle(buffer));
}
uint32_t stride = 0;
hidl_vec<hidl_handle> hidl_buffers;
if (err == Error::NONE && buffers.size() > 0) {
stride = static_cast<uint32_t>(PRIV_HANDLE_CONST(buffers[0].getNativeHandle())->width);
hidl_buffers.setToExternal(buffers.data(), buffers.size());
}
hidl_cb(err, stride, hidl_buffers);
for (const auto &b : buffers) {
buf_mgr_->ReleaseBuffer(PRIV_HANDLE_CONST(b.getNativeHandle()));
}
return Void();
}
// Methods from ::android::hidl::base::V1_0::IBase follow.
IAllocator *HIDL_FETCH_IAllocator(const char * /* name */) {
return new QtiAllocator();
}
} // namespace implementation
} // namespace V1_0
} // namespace allocator
} // namespace display
} // namespace hardware
} // namespace qti
} // namespace vendor

View File

@@ -1,83 +0,0 @@
/*
* Copyright (c) 2018, 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:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __QTIALLOCATOR_H__
#define __QTIALLOCATOR_H__
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
#include "gr_buf_mgr.h"
namespace vendor {
namespace qti {
namespace hardware {
namespace display {
namespace allocator {
namespace V1_0 {
namespace implementation {
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::graphics::allocator::V2_0::IAllocator;
using ::android::hardware::graphics::mapper::V2_0::Error;
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_memory;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hidl::base::V1_0::DebugInfo;
using ::android::hidl::base::V1_0::IBase;
using ::android::sp;
using gralloc::BufferManager;
class QtiAllocator : public IAllocator {
public:
QtiAllocator();
// Methods from ::android::hardware::graphics::allocator::V2_0::IAllocator follow.
Return<void> dumpDebugInfo(dumpDebugInfo_cb _hidl_cb) override;
Return<void> allocate(const hidl_vec<uint32_t> &descriptor, uint32_t count,
allocate_cb _hidl_cb) override;
// Methods from ::android::hidl::base::V1_0::IBase follow.
private:
BufferManager *buf_mgr_ = nullptr;
};
extern "C" IAllocator *HIDL_FETCH_IAllocator(const char *name);
} // namespace implementation
} // namespace V1_0
} // namespace allocator
} // namespace display
} // namespace hardware
} // namespace qti
} // namespace vendor
#endif // __QTIALLOCATOR_H__

View File

@@ -1,345 +0,0 @@
/*
* Copyright (c) 2018, 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:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
#define DEBUG 0
#include "QtiMapper.h"
#include <cutils/trace.h>
#include <qdMetaData.h>
#include <sync/sync.h>
#include "gr_utils.h"
namespace vendor {
namespace qti {
namespace hardware {
namespace display {
namespace mapper {
namespace V1_0 {
namespace implementation {
using gralloc::BufferInfo;
QtiMapper::QtiMapper() {
buf_mgr_ = BufferManager::GetInstance();
ALOGD_IF(DEBUG, "Created QtiMapper instance");
}
bool QtiMapper::ValidDescriptor(const IMapper::BufferDescriptorInfo &bd) {
if (bd.width == 0 || bd.height == 0 || (static_cast<int32_t>(bd.format) <= 0) ||
bd.layerCount <= 0) {
return false;
}
return true;
}
// Methods from ::android::hardware::graphics::mapper::V2_0::IMapper follow.
Return<void> QtiMapper::createDescriptor(const IMapper::BufferDescriptorInfo &descriptor_info,
createDescriptor_cb hidl_cb) {
ALOGD_IF(DEBUG,
"BufferDescriptorInfo: wxh: %dx%d usage: 0x%" PRIu64 " format: %d layer_count: %d",
descriptor_info.width, descriptor_info.height, descriptor_info.usage,
static_cast<uint32_t>(descriptor_info.format), descriptor_info.layerCount);
if (ValidDescriptor(descriptor_info)) {
auto vec = gralloc::BufferDescriptor::Encode(descriptor_info);
hidl_cb(Error::NONE, vec);
} else {
hidl_cb(Error::BAD_VALUE, hidl_vec<uint32_t>());
}
return Void();
}
Return<void> QtiMapper::importBuffer(const hidl_handle &raw_handle, importBuffer_cb hidl_cb) {
if (!raw_handle.getNativeHandle()) {
ALOGE("%s: Unable to import handle", __FUNCTION__);
hidl_cb(Error::BAD_BUFFER, nullptr);
return Void();
}
native_handle_t *buffer_handle = native_handle_clone(raw_handle.getNativeHandle());
if (!buffer_handle) {
ALOGE("%s: Unable to clone handle", __FUNCTION__);
hidl_cb(Error::NO_RESOURCES, nullptr);
return Void();
}
auto error = buf_mgr_->RetainBuffer(PRIV_HANDLE_CONST(buffer_handle));
if (error != Error::NONE) {
ALOGE("%s: Unable to retain handle: %p", __FUNCTION__, buffer_handle);
native_handle_close(buffer_handle);
native_handle_delete(buffer_handle);
hidl_cb(error, nullptr);
return Void();
}
ALOGD_IF(DEBUG, "Imported handle: %p id: %" PRIu64, buffer_handle,
PRIV_HANDLE_CONST(buffer_handle)->id);
hidl_cb(Error::NONE, buffer_handle);
return Void();
}
Return<Error> QtiMapper::freeBuffer(void *buffer) {
if (!buffer) {
return Error::BAD_BUFFER;
}
return buf_mgr_->ReleaseBuffer(PRIV_HANDLE_CONST(buffer));
}
bool QtiMapper::GetFenceFd(const hidl_handle &fence_handle, int *outFenceFd) {
auto handle = fence_handle.getNativeHandle();
if (handle && handle->numFds > 1) {
ALOGE("invalid fence handle with %d fds", handle->numFds);
return false;
}
*outFenceFd = (handle && handle->numFds == 1) ? handle->data[0] : -1;
return true;
}
void QtiMapper::WaitFenceFd(int fence_fd) {
if (fence_fd < 0) {
return;
}
const int timeout = 3000;
ATRACE_BEGIN("fence wait");
const int error = sync_wait(fence_fd, timeout);
ATRACE_END();
if (error < 0) {
ALOGE("QtiMapper: lock fence %d didn't signal in %u ms - error: %s", fence_fd, timeout,
strerror(errno));
}
}
Error QtiMapper::LockBuffer(void *buffer, uint64_t usage, const hidl_handle &acquire_fence) {
if (!buffer) {
return Error::BAD_BUFFER;
}
int fence_fd;
if (!GetFenceFd(acquire_fence, &fence_fd)) {
return Error::BAD_VALUE;
}
if (fence_fd > 0) {
WaitFenceFd(fence_fd);
}
auto hnd = PRIV_HANDLE_CONST(buffer);
return buf_mgr_->LockBuffer(hnd, usage);
}
Return<void> QtiMapper::lock(void *buffer, uint64_t cpu_usage,
const IMapper::Rect & /*access_region*/,
const hidl_handle &acquire_fence, lock_cb hidl_cb) {
auto err = LockBuffer(buffer, cpu_usage, acquire_fence);
if (err != Error::NONE) {
hidl_cb(err, nullptr);
return Void();
}
auto hnd = PRIV_HANDLE_CONST(buffer);
auto *out_data = reinterpret_cast<void *>(hnd->base);
hidl_cb(Error::NONE, out_data);
return Void();
}
Return<void> QtiMapper::lockYCbCr(void *buffer, uint64_t cpu_usage,
const IMapper::Rect & /*access_region*/,
const hidl_handle &acquire_fence, lockYCbCr_cb hidl_cb) {
YCbCrLayout layout = {};
auto err = LockBuffer(buffer, cpu_usage, acquire_fence);
if (err != Error::NONE) {
hidl_cb(err, layout);
return Void();
}
auto hnd = PRIV_HANDLE_CONST(buffer);
android_ycbcr yuv_plane_info[2];
if (gralloc::GetYUVPlaneInfo(hnd, yuv_plane_info) != 0) {
hidl_cb(Error::BAD_VALUE, layout);
}
layout.y = yuv_plane_info[0].y;
layout.cr = yuv_plane_info[0].cr;
layout.cb = yuv_plane_info[0].cb;
layout.yStride = static_cast<uint32_t>(yuv_plane_info[0].ystride);
layout.cStride = static_cast<uint32_t>(yuv_plane_info[0].cstride);
layout.chromaStep = static_cast<uint32_t>(yuv_plane_info[0].chroma_step);
hidl_cb(Error::NONE, layout);
return Void();
}
Return<void> QtiMapper::unlock(void *buffer, unlock_cb hidl_cb) {
auto err = Error::BAD_BUFFER;
if (buffer != nullptr) {
err = buf_mgr_->UnlockBuffer(PRIV_HANDLE_CONST(buffer));
}
// We don't have a release fence
hidl_cb(err, hidl_handle(nullptr));
return Void();
}
#ifdef ENABLE_QTI_MAPPER_EXTENSION
Return<void> QtiMapper::getMapSecureBufferFlag(void *buffer, getMapSecureBufferFlag_cb hidl_cb) {
auto err = Error::BAD_BUFFER;
auto hnd = static_cast<private_handle_t *>(buffer);
int *map_secure_buffer = 0;
if (buffer != nullptr && private_handle_t::validate(hnd) != 0) {
if (getMetaData(hnd, GET_MAP_SECURE_BUFFER, map_secure_buffer) != 0) {
*map_secure_buffer = 0;
} else {
err = Error::NONE;
}
}
hidl_cb(err, *map_secure_buffer != 0);
return Void();
}
Return<void> QtiMapper::getInterlacedFlag(void *buffer, getInterlacedFlag_cb hidl_cb) {
auto err = Error::BAD_BUFFER;
auto hnd = static_cast<private_handle_t *>(buffer);
int *interlaced_flag = nullptr;
if (buffer != nullptr && private_handle_t::validate(hnd) != 0) {
if (getMetaData(hnd, GET_PP_PARAM_INTERLACED, interlaced_flag) != 0) {
*interlaced_flag = 0;
} else {
err = Error::NONE;
}
}
hidl_cb(err, *interlaced_flag != 0);
return Void();
}
Return<void> QtiMapper::getCustomDimensions(void *buffer, getCustomDimensions_cb hidl_cb) {
auto err = Error::BAD_BUFFER;
auto hnd = static_cast<private_handle_t *>(buffer);
int stride = 0;
int height = 0;
if (buffer != nullptr && private_handle_t::validate(hnd) != 0) {
stride = hnd->width;
height = hnd->height;
gralloc::GetCustomDimensions(hnd, &stride, &height);
err = Error::NONE;
}
hidl_cb(err, stride, height);
return Void();
}
Return<void> QtiMapper::getRgbDataAddress(void *buffer, getRgbDataAddress_cb hidl_cb) {
auto err = Error::BAD_BUFFER;
auto hnd = static_cast<private_handle_t *>(buffer);
void *rgb_data = nullptr;
if (buffer != nullptr && private_handle_t::validate(hnd) != 0) {
if (gralloc::GetRgbDataAddress(hnd, &rgb_data) == 0) {
err = Error::NONE;
}
}
hidl_cb(err, rgb_data);
return Void();
}
Return<void> QtiMapper::calculateBufferAttributes(int32_t width, int32_t height, int32_t format,
uint64_t usage,
calculateBufferAttributes_cb hidl_cb) {
unsigned int alignedw, alignedh;
BufferInfo info(width, height, format, usage);
gralloc::GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
bool ubwc_enabled = gralloc::IsUBwcEnabled(format, usage);
hidl_cb(Error::NONE, alignedw, alignedh, ubwc_enabled);
return Void();
}
Return<void> QtiMapper::getColorSpace(void *buffer, getColorSpace_cb hidl_cb) {
auto err = Error::BAD_BUFFER;
auto hnd = static_cast<private_handle_t *>(buffer);
int color_space = 0;
if (buffer != nullptr && private_handle_t::validate(hnd) != 0) {
gralloc::GetColorSpaceFromMetadata(hnd, &color_space);
err = Error::NONE;
}
hidl_cb(err, color_space);
return Void();
}
Return<void> QtiMapper::getYuvPlaneInfo(void *buffer, getYuvPlaneInfo_cb hidl_cb) {
auto err = Error::BAD_BUFFER;
auto hnd = static_cast<private_handle_t *>(buffer);
hidl_vec<YCbCrLayout> layout;
layout.resize(2);
android_ycbcr yuv_plane_info[2];
if (buffer != nullptr && private_handle_t::validate(hnd) != 0) {
if (gralloc::GetYUVPlaneInfo(hnd, yuv_plane_info) == 0) {
err = Error::NONE;
for (int i=0; i < 2; i++) {
layout[i].y = yuv_plane_info[i].y;
layout[i].cr = yuv_plane_info[i].cr;
layout[i].cb = yuv_plane_info[i].cb;
layout[i].yStride = static_cast<uint32_t>(yuv_plane_info[i].ystride);
layout[i].cStride = static_cast<uint32_t>(yuv_plane_info[i].cstride);
layout[i].chromaStep = static_cast<uint32_t>(yuv_plane_info[i].chroma_step);
}
}
}
hidl_cb(err, layout);
return Void();
}
Return<Error> QtiMapper::setSingleBufferMode(void *buffer, bool enable) {
auto err = Error::BAD_BUFFER;
auto hnd = static_cast<private_handle_t *>(buffer);
if (buffer != nullptr && private_handle_t::validate(hnd) != 0) {
if (setMetaData(hnd, SET_SINGLE_BUFFER_MODE, &enable) != 0) {
err = Error::UNSUPPORTED;
} else {
err = Error::NONE;
}
}
return err;
}
#endif
// Methods from ::android::hidl::base::V1_0::IBase follow.
// When we are in passthrough mode, this method is used
// by hidl to obtain the SP HAL object
IMapper *HIDL_FETCH_IMapper(const char * /* name */) {
ALOGD_IF(DEBUG, "Fetching IMapper from QtiMapper");
auto mapper = new QtiMapper();
return static_cast<IMapper *>(mapper);
}
} // namespace implementation
} // namespace V1_0
} // namespace mapper
} // namespace display
} // namespace hardware
} // namespace qti
} // namespace vendor

View File

@@ -1,104 +0,0 @@
/*
* Copyright (c) 2018, 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:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __QTIMAPPER_H__
#define __QTIMAPPER_H__
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
#include "gr_buf_mgr.h"
namespace vendor {
namespace qti {
namespace hardware {
namespace display {
namespace mapper {
namespace V1_0 {
namespace implementation {
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::graphics::mapper::V2_0::Error;
using ::android::hardware::graphics::mapper::V2_0::IMapper;
using ::android::hardware::graphics::mapper::V2_0::YCbCrLayout;
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_handle;
using ::android::hardware::hidl_memory;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hidl::base::V1_0::DebugInfo;
using ::android::hidl::base::V1_0::IBase;
using ::android::sp;
using gralloc::BufferManager;
class QtiMapper : public IMapper {
public:
QtiMapper();
// Methods from ::android::hardware::graphics::mapper::V2_0::IMapper follow.
Return<void> createDescriptor(const IMapper::BufferDescriptorInfo &descriptor_info,
createDescriptor_cb hidl_cb) override;
Return<void> importBuffer(const hidl_handle &raw_handle, importBuffer_cb hidl_cb) override;
Return<Error> freeBuffer(void *buffer) override;
Return<void> lock(void *buffer, uint64_t cpu_usage, const IMapper::Rect &access_region,
const hidl_handle &acquire_fence, lock_cb hidl_cb) override;
Return<void> lockYCbCr(void *buffer, uint64_t cpu_usage, const IMapper::Rect &access_region,
const hidl_handle &acquire_fence, lockYCbCr_cb hidl_cb) override;
Return<void> unlock(void *buffer, unlock_cb hidl_cb) override;
#ifdef ENABLE_QTI_MAPPER_EXTENSION
Return<void> getMapSecureBufferFlag(void *buffer, getMapSecureBufferFlag_cb _hidl_cb) override;
Return<void> getInterlacedFlag(void *buffer, getInterlacedFlag_cb _hidl_cb) override;
Return<void> getCustomDimensions(void *buffer, getCustomDimensions_cb _hidl_cb) override;
Return<void> getRgbDataAddress(void *buffer, getRgbDataAddress_cb _hidl_cb) override;
Return<void> calculateBufferAttributes(int32_t width, int32_t height, int32_t format,
uint64_t usage,
calculateBufferAttributes_cb _hidl_cb) override;
Return<void> getColorSpace(void *buffer, getColorSpace_cb _hidl_cb) override;
Return<void> getYuvPlaneInfo(void *buffer, getYuvPlaneInfo_cb _hidl_cb) override;
Return<Error> setSingleBufferMode(void *buffer, bool enable) override;
#endif
private:
BufferManager *buf_mgr_ = nullptr;
bool ValidDescriptor(const IMapper::BufferDescriptorInfo &bd);
bool GetFenceFd(const hidl_handle &fence_handle, int *outFenceFd);
void WaitFenceFd(int fence_fd);
Error LockBuffer(void *buffer, uint64_t usage, const hidl_handle &acquire_fence);
};
extern "C" IMapper *HIDL_FETCH_IMapper(const char *name);
} // namespace implementation
} // namespace V1_0
} // namespace mapper
} // namespace display
} // namespace hardware
} // namespace qti
} // namespace vendor
#endif // __QTIMAPPER_H__

View File

@@ -1,223 +0,0 @@
/*
* Copyright (c) 2011-2018, 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:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <log/log.h>
#include <cutils/properties.h>
#include <dlfcn.h>
#include <mutex>
#include "gr_adreno_info.h"
#include "gr_utils.h"
#include "gralloc_priv.h"
using std::lock_guard;
using std::mutex;
namespace gralloc {
AdrenoMemInfo *AdrenoMemInfo::s_instance = nullptr;
AdrenoMemInfo *AdrenoMemInfo::GetInstance() {
static mutex s_lock;
lock_guard<mutex> obj(s_lock);
if (!s_instance) {
s_instance = new AdrenoMemInfo();
}
return s_instance;
}
AdrenoMemInfo::AdrenoMemInfo() {
libadreno_utils_ = ::dlopen("libadreno_utils.so", RTLD_NOW);
if (libadreno_utils_) {
*reinterpret_cast<void **>(&LINK_adreno_compute_aligned_width_and_height) =
::dlsym(libadreno_utils_, "compute_aligned_width_and_height");
*reinterpret_cast<void **>(&LINK_adreno_compute_fmt_aligned_width_and_height) =
::dlsym(libadreno_utils_, "compute_fmt_aligned_width_and_height");
*reinterpret_cast<void **>(&LINK_adreno_compute_padding) =
::dlsym(libadreno_utils_, "compute_surface_padding");
*reinterpret_cast<void **>(&LINK_adreno_compute_compressedfmt_aligned_width_and_height) =
::dlsym(libadreno_utils_, "compute_compressedfmt_aligned_width_and_height");
*reinterpret_cast<void **>(&LINK_adreno_isUBWCSupportedByGpu) =
::dlsym(libadreno_utils_, "isUBWCSupportedByGpu");
*reinterpret_cast<void **>(&LINK_adreno_get_gpu_pixel_alignment) =
::dlsym(libadreno_utils_, "get_gpu_pixel_alignment");
} else {
ALOGE(" Failed to load libadreno_utils.so");
}
// Check if the overriding property debug.gralloc.gfx_ubwc_disable
// that disables UBWC allocations for the graphics stack is set
char property[PROPERTY_VALUE_MAX];
property_get(DISABLE_UBWC_PROP, property, "0");
if (!(strncmp(property, "1", PROPERTY_VALUE_MAX)) ||
!(strncmp(property, "true", PROPERTY_VALUE_MAX))) {
gfx_ubwc_disable_ = true;
}
}
AdrenoMemInfo::~AdrenoMemInfo() {
if (libadreno_utils_) {
::dlclose(libadreno_utils_);
}
}
void AdrenoMemInfo::AlignUnCompressedRGB(int width, int height, int format, int tile_enabled,
unsigned int *aligned_w, unsigned int *aligned_h) {
*aligned_w = (unsigned int)ALIGN(width, 32);
*aligned_h = (unsigned int)ALIGN(height, 32);
int bpp = 4;
switch (format) {
case HAL_PIXEL_FORMAT_RGB_888:
case HAL_PIXEL_FORMAT_BGR_888:
bpp = 3;
break;
case HAL_PIXEL_FORMAT_RGB_565:
case HAL_PIXEL_FORMAT_BGR_565:
case HAL_PIXEL_FORMAT_RGBA_5551:
case HAL_PIXEL_FORMAT_RGBA_4444:
bpp = 2;
break;
default:
break;
}
int raster_mode = 0; // Adreno unknown raster mode.
int padding_threshold = 512; // Threshold for padding surfaces.
// the function below computes aligned width and aligned height
// based on linear or macro tile mode selected.
if (LINK_adreno_compute_fmt_aligned_width_and_height) {
// We call into adreno_utils only for RGB formats. So plane_id is 0 and
// num_samples is 1 always. We may have to add uitility function to
// find out these if there is a need to call this API for YUV formats.
LINK_adreno_compute_fmt_aligned_width_and_height(
width, height, 0 /*plane_id*/, GetGpuPixelFormat(format), 1 /*num_samples*/, tile_enabled,
raster_mode, padding_threshold, reinterpret_cast<int *>(aligned_w),
reinterpret_cast<int *>(aligned_h));
} else if (LINK_adreno_compute_aligned_width_and_height) {
LINK_adreno_compute_aligned_width_and_height(
width, height, bpp, tile_enabled, raster_mode, padding_threshold,
reinterpret_cast<int *>(aligned_w), reinterpret_cast<int *>(aligned_h));
} else if (LINK_adreno_compute_padding) {
int surface_tile_height = 1; // Linear surface
*aligned_w = UINT(LINK_adreno_compute_padding(width, bpp, surface_tile_height, raster_mode,
padding_threshold));
ALOGW("%s: Warning!! Old GFX API is used to calculate stride", __FUNCTION__);
} else {
ALOGW(
"%s: Warning!! Symbols compute_surface_padding and "
"compute_fmt_aligned_width_and_height and "
"compute_aligned_width_and_height not found",
__FUNCTION__);
}
}
void AdrenoMemInfo::AlignCompressedRGB(int width, int height, int format, unsigned int *aligned_w,
unsigned int *aligned_h) {
if (LINK_adreno_compute_compressedfmt_aligned_width_and_height) {
int bytesPerPixel = 0;
int raster_mode = 0; // Adreno unknown raster mode.
int padding_threshold = 512; // Threshold for padding
// surfaces.
LINK_adreno_compute_compressedfmt_aligned_width_and_height(
width, height, format, 0, raster_mode, padding_threshold,
reinterpret_cast<int *>(aligned_w), reinterpret_cast<int *>(aligned_h), &bytesPerPixel);
} else {
*aligned_w = (unsigned int)ALIGN(width, 32);
*aligned_h = (unsigned int)ALIGN(height, 32);
ALOGW("%s: Warning!! compute_compressedfmt_aligned_width_and_height not found", __FUNCTION__);
}
}
bool AdrenoMemInfo::IsUBWCSupportedByGPU(int format) {
if (!gfx_ubwc_disable_ && LINK_adreno_isUBWCSupportedByGpu) {
ADRENOPIXELFORMAT gpu_format = GetGpuPixelFormat(format);
return LINK_adreno_isUBWCSupportedByGpu(gpu_format);
}
return false;
}
uint32_t AdrenoMemInfo::GetGpuPixelAlignment() {
if (LINK_adreno_get_gpu_pixel_alignment) {
return LINK_adreno_get_gpu_pixel_alignment();
}
return 1;
}
ADRENOPIXELFORMAT AdrenoMemInfo::GetGpuPixelFormat(int hal_format) {
switch (hal_format) {
case HAL_PIXEL_FORMAT_RGBA_8888:
return ADRENO_PIXELFORMAT_R8G8B8A8;
case HAL_PIXEL_FORMAT_RGBX_8888:
return ADRENO_PIXELFORMAT_R8G8B8X8;
case HAL_PIXEL_FORMAT_BGRA_8888:
return ADRENO_PIXELFORMAT_B8G8R8A8;
case HAL_PIXEL_FORMAT_RGB_888:
return ADRENO_PIXELFORMAT_R8G8B8;
case HAL_PIXEL_FORMAT_RGB_565:
return ADRENO_PIXELFORMAT_B5G6R5;
case HAL_PIXEL_FORMAT_BGR_565:
return ADRENO_PIXELFORMAT_R5G6B5;
case HAL_PIXEL_FORMAT_RGBA_5551:
return ADRENO_PIXELFORMAT_R5G5B5A1;
case HAL_PIXEL_FORMAT_RGBA_4444:
return ADRENO_PIXELFORMAT_R4G4B4A4;
case HAL_PIXEL_FORMAT_RGBA_1010102:
return ADRENO_PIXELFORMAT_R10G10B10A2_UNORM;
case HAL_PIXEL_FORMAT_RGBX_1010102:
return ADRENO_PIXELFORMAT_R10G10B10X2_UNORM;
case HAL_PIXEL_FORMAT_ABGR_2101010:
return ADRENO_PIXELFORMAT_A2B10G10R10_UNORM;
case HAL_PIXEL_FORMAT_RGBA_FP16:
return ADRENO_PIXELFORMAT_R16G16B16A16_FLOAT;
case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
return ADRENO_PIXELFORMAT_NV12;
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
return ADRENO_PIXELFORMAT_NV12_EXT;
case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
return ADRENO_PIXELFORMAT_TP10;
case HAL_PIXEL_FORMAT_YCbCr_420_P010:
case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
return ADRENO_PIXELFORMAT_P010;
default:
ALOGE("%s: No map for format: 0x%x", __FUNCTION__, hal_format);
break;
}
return ADRENO_PIXELFORMAT_UNKNOWN;
}
} // namespace gralloc

View File

@@ -1,153 +0,0 @@
/*
* Copyright (c) 2011-2018, 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:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __GR_ADRENO_INFO_H__
#define __GR_ADRENO_INFO_H__
#include <media/msm_media_info.h>
namespace gralloc {
// Adreno Pixel Formats
typedef enum {
ADRENO_PIXELFORMAT_UNKNOWN = 0,
ADRENO_PIXELFORMAT_R16G16B16A16_FLOAT = 10,
ADRENO_PIXELFORMAT_R10G10B10A2_UNORM = 24, // Vertex, Normalized GL_UNSIGNED_INT_10_10_10_2_OES
ADRENO_PIXELFORMAT_R8G8B8A8 = 28,
ADRENO_PIXELFORMAT_R8G8B8A8_SRGB = 29,
ADRENO_PIXELFORMAT_B5G6R5 = 85,
ADRENO_PIXELFORMAT_B5G5R5A1 = 86,
ADRENO_PIXELFORMAT_B8G8R8A8 = 90,
ADRENO_PIXELFORMAT_B8G8R8A8_SRGB = 91,
ADRENO_PIXELFORMAT_B8G8R8X8_SRGB = 93,
ADRENO_PIXELFORMAT_NV12 = 103,
ADRENO_PIXELFORMAT_P010 = 104,
ADRENO_PIXELFORMAT_YUY2 = 107,
ADRENO_PIXELFORMAT_B4G4R4A4 = 115,
ADRENO_PIXELFORMAT_NV12_EXT = 506, // NV12 with non-std alignment and offsets
ADRENO_PIXELFORMAT_R8G8B8X8 = 507, // GL_RGB8 (Internal)
ADRENO_PIXELFORMAT_R8G8B8 = 508, // GL_RGB8
ADRENO_PIXELFORMAT_A1B5G5R5 = 519, // GL_RGB5_A1
ADRENO_PIXELFORMAT_R8G8B8X8_SRGB = 520, // GL_SRGB8
ADRENO_PIXELFORMAT_R8G8B8_SRGB = 521, // GL_SRGB8
ADRENO_PIXELFORMAT_A2B10G10R10_UNORM = 532,
// Vertex, Normalized GL_UNSIGNED_INT_10_10_10_2_OES
ADRENO_PIXELFORMAT_R10G10B10X2_UNORM = 537,
// Vertex, Normalized GL_UNSIGNED_INT_10_10_10_2_OES
ADRENO_PIXELFORMAT_R5G6B5 = 610, // RGBA version of B5G6R5
ADRENO_PIXELFORMAT_R5G5B5A1 = 611, // RGBA version of B5G5R5A1
ADRENO_PIXELFORMAT_R4G4B4A4 = 612, // RGBA version of B4G4R4A4
ADRENO_PIXELFORMAT_UYVY = 614, // YUV 4:2:2 packed progressive (1 plane)
ADRENO_PIXELFORMAT_NV21 = 619,
ADRENO_PIXELFORMAT_Y8U8V8A8 = 620, // YUV 4:4:4 packed (1 plane)
ADRENO_PIXELFORMAT_Y8 = 625, // Single 8-bit luma only channel YUV format
ADRENO_PIXELFORMAT_TP10 = 654, // YUV 4:2:0 planar 10 bits/comp (2 planes)
} ADRENOPIXELFORMAT;
class AdrenoMemInfo {
public:
/*
* Function to compute aligned width and aligned height based on
* width, height, format and usage flags.
*
* @return aligned width, aligned height
*/
void GetAlignedWidthAndHeight(int width, int height, int format, int usage,
unsigned int *aligned_w, unsigned int *aligned_h, bool ubwc_enabled,
bool tile_enabled);
/*
* Function to compute the adreno aligned width and aligned height
* based on the width and format.
*
* @return aligned width, aligned height
*/
void AlignUnCompressedRGB(int width, int height, int format, int tileEnabled,
unsigned int *aligned_w, unsigned int *aligned_h);
/*
* Function to compute the adreno aligned width and aligned height
* based on the width and format.
*
* @return aligned width, aligned height
*/
void AlignCompressedRGB(int width, int height, int format, unsigned int *aligned_w,
unsigned int *aligned_h);
/*
* Function to compute the pixel alignment requirement.
*
* @return alignment
*/
uint32_t GetGpuPixelAlignment();
/*
* Function to query whether GPU supports UBWC for given HAL format
* @return > 0 : supported
* 0 : not supported
*/
bool IsUBWCSupportedByGPU(int format);
/*
* Function to get the corresponding Adreno format for given HAL format
*/
ADRENOPIXELFORMAT GetGpuPixelFormat(int hal_format);
static AdrenoMemInfo *GetInstance();
private:
AdrenoMemInfo();
~AdrenoMemInfo();
// link(s)to adreno surface padding library.
int (*LINK_adreno_compute_padding)(int width, int bpp, int surface_tile_height,
int screen_tile_height, int padding_threshold) = NULL;
void (*LINK_adreno_compute_aligned_width_and_height)(int width, int height, int bpp,
int tile_mode, int raster_mode,
int padding_threshold, int *aligned_w,
int *aligned_h) = NULL;
void (*LINK_adreno_compute_fmt_aligned_width_and_height)(int width, int height, int plane_id,
int format, int num_samples,
int tile_mode, int raster_mode,
int padding_threshold, int *aligned_w,
int *aligned_h) = NULL;
void (*LINK_adreno_compute_compressedfmt_aligned_width_and_height)(
int width, int height, int format, int tile_mode, int raster_mode, int padding_threshold,
int *aligned_w, int *aligned_h, int *bpp) = NULL;
int (*LINK_adreno_isUBWCSupportedByGpu)(ADRENOPIXELFORMAT format) = NULL;
unsigned int (*LINK_adreno_get_gpu_pixel_alignment)() = NULL;
bool gfx_ubwc_disable_ = false;
void *libadreno_utils_ = NULL;
static AdrenoMemInfo *s_instance;
};
} // namespace gralloc
#endif // __GR_ADRENO_INFO_H__

View File

@@ -1,301 +0,0 @@
/*
* Copyright (c) 2011-2018, 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:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <log/log.h>
#include <algorithm>
#include <vector>
#include "gr_allocator.h"
#include "gr_utils.h"
#include "gralloc_priv.h"
#include "qd_utils.h"
#ifndef ION_FLAG_CP_PIXEL
#define ION_FLAG_CP_PIXEL 0
#endif
#ifndef ION_FLAG_ALLOW_NON_CONTIG
#define ION_FLAG_ALLOW_NON_CONTIG 0
#endif
#ifndef ION_FLAG_CP_CAMERA_PREVIEW
#define ION_FLAG_CP_CAMERA_PREVIEW 0
#endif
#ifdef MASTER_SIDE_CP
#define CP_HEAP_ID ION_SECURE_HEAP_ID
#define SD_HEAP_ID ION_SECURE_DISPLAY_HEAP_ID
#define ION_CP_FLAGS (ION_SECURE | ION_FLAG_CP_PIXEL)
#define ION_SD_FLAGS (ION_SECURE | ION_FLAG_CP_SEC_DISPLAY)
#define ION_SC_FLAGS (ION_SECURE | ION_FLAG_CP_CAMERA)
#define ION_SC_PREVIEW_FLAGS (ION_SECURE | ION_FLAG_CP_CAMERA_PREVIEW)
#else // SLAVE_SIDE_CP
#define CP_HEAP_ID ION_CP_MM_HEAP_ID
#define SD_HEAP_ID CP_HEAP_ID
#define ION_CP_FLAGS (ION_SECURE | ION_FLAG_ALLOW_NON_CONTIG)
#define ION_SD_FLAGS ION_SECURE
#define ION_SC_FLAGS ION_SECURE
#define ION_SC_PREVIEW_FLAGS ION_SECURE
#endif
using std::shared_ptr;
using std::vector;
namespace gralloc {
static BufferInfo GetBufferInfo(const BufferDescriptor &descriptor) {
return BufferInfo(descriptor.GetWidth(), descriptor.GetHeight(), descriptor.GetFormat(),
descriptor.GetUsage());
}
Allocator::Allocator() : ion_allocator_(nullptr) {}
bool Allocator::Init() {
ion_allocator_ = new IonAlloc();
if (!ion_allocator_->Init()) {
return false;
}
return true;
}
Allocator::~Allocator() {
if (ion_allocator_) {
delete ion_allocator_;
}
}
int Allocator::AllocateMem(AllocData *alloc_data, uint64_t usage) {
int ret;
alloc_data->uncached = UseUncached(usage);
// After this point we should have the right heap set, there is no fallback
GetIonHeapInfo(usage, &alloc_data->heap_id, &alloc_data->alloc_type, &alloc_data->flags);
ret = ion_allocator_->AllocBuffer(alloc_data);
if (ret >= 0) {
alloc_data->alloc_type |= private_handle_t::PRIV_FLAGS_USES_ION;
} else {
ALOGE("%s: Failed to allocate buffer - heap: 0x%x flags: 0x%x", __FUNCTION__,
alloc_data->heap_id, alloc_data->flags);
}
return ret;
}
int Allocator::MapBuffer(void **base, unsigned int size, unsigned int offset, int fd) {
if (ion_allocator_) {
return ion_allocator_->MapBuffer(base, size, offset, fd);
}
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_) {
return ion_allocator_->FreeBuffer(base, size, offset, fd, handle);
}
return -EINVAL;
}
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, handle, op);
}
return -EINVAL;
}
bool Allocator::CheckForBufferSharing(uint32_t num_descriptors,
const vector<shared_ptr<BufferDescriptor>> &descriptors,
ssize_t *max_index) {
unsigned int cur_heap_id = 0, prev_heap_id = 0;
unsigned int cur_alloc_type = 0, prev_alloc_type = 0;
unsigned int cur_ion_flags = 0, prev_ion_flags = 0;
bool cur_uncached = false, prev_uncached = false;
unsigned int alignedw, alignedh;
unsigned int max_size = 0;
*max_index = -1;
for (uint32_t i = 0; i < num_descriptors; i++) {
// Check Cached vs non-cached and all the ION flags
cur_uncached = UseUncached(descriptors[i]->GetUsage());
GetIonHeapInfo(descriptors[i]->GetUsage(), &cur_heap_id, &cur_alloc_type, &cur_ion_flags);
if (i > 0 && (cur_heap_id != prev_heap_id || cur_alloc_type != prev_alloc_type ||
cur_ion_flags != prev_ion_flags)) {
return false;
}
// For same format type, find the descriptor with bigger size
GetAlignedWidthAndHeight(GetBufferInfo(*descriptors[i]), &alignedw, &alignedh);
unsigned int size = GetSize(GetBufferInfo(*descriptors[i]), alignedw, alignedh);
if (max_size < size) {
*max_index = INT(i);
max_size = size;
}
prev_heap_id = cur_heap_id;
prev_uncached = cur_uncached;
prev_ion_flags = cur_ion_flags;
prev_alloc_type = cur_alloc_type;
}
return true;
}
int Allocator::GetImplDefinedFormat(uint64_t usage, int format) {
int gr_format = format;
// If input format is HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED then based on
// the usage bits, gralloc assigns a format.
if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
if (usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) {
// Use of 10BIT_TP and 10BIT bits is supposed to be mutually exclusive.
// Each bit maps to only one format. Here we will check one of the bits
// and ignore the other.
if (usage & GRALLOC_USAGE_PRIVATE_10BIT_TP) {
gr_format = HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC;
} else if (usage & GRALLOC_USAGE_PRIVATE_10BIT) {
gr_format = HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC;
} else {
gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
}
} else if (usage & GRALLOC_USAGE_PRIVATE_10BIT) {
gr_format = HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS;
} else if (usage & BufferUsage::VIDEO_ENCODER) {
gr_format = HAL_PIXEL_FORMAT_NV12_ENCODEABLE; // NV12
} else if (usage & BufferUsage::CAMERA_INPUT) {
if (usage & BufferUsage::CAMERA_OUTPUT) {
// Assumed ZSL if both producer and consumer camera flags set
gr_format = HAL_PIXEL_FORMAT_NV21_ZSL; // NV21
} else {
gr_format = HAL_PIXEL_FORMAT_YCrCb_420_SP; // NV21
}
} else if (usage & BufferUsage::CAMERA_OUTPUT) {
if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
gr_format = HAL_PIXEL_FORMAT_NV21_ZSL; // NV21
} else {
gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS; // NV12 preview
}
} else if (usage & BufferUsage::COMPOSER_OVERLAY) {
// XXX: If we still haven't set a format, default to RGBA8888
gr_format = HAL_PIXEL_FORMAT_RGBA_8888;
} else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
// If no other usage flags are detected, default the
// flexible YUV format to NV21_ZSL
gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;
}
}
return gr_format;
}
/* The default policy is to return cached buffers unless the client explicity
* sets the PRIVATE_UNCACHED flag or indicates that the buffer will be rarely
* read or written in software. */
bool Allocator::UseUncached(uint64_t usage) {
if ((usage & GRALLOC_USAGE_PRIVATE_UNCACHED) || (usage & BufferUsage::PROTECTED)) {
return true;
}
// CPU read rarely
if ((usage & BufferUsage::CPU_READ_MASK) == static_cast<uint64_t>(BufferUsage::CPU_READ_RARELY)) {
return true;
}
// CPU write rarely
if ((usage & BufferUsage::CPU_WRITE_MASK) ==
static_cast<uint64_t>(BufferUsage::CPU_WRITE_RARELY)) {
return true;
}
if ((usage & BufferUsage::SENSOR_DIRECT_DATA) || (usage & BufferUsage::GPU_DATA_BUFFER)) {
return true;
}
return false;
}
void Allocator::GetIonHeapInfo(uint64_t usage, unsigned int *ion_heap_id, unsigned int *alloc_type,
unsigned int *ion_flags) {
unsigned int heap_id = 0;
unsigned int type = 0;
uint32_t flags = 0;
if (usage & GRALLOC_USAGE_PROTECTED) {
if (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) {
heap_id = ION_HEAP(SD_HEAP_ID);
/*
* There is currently no flag in ION for Secure Display
* VM. Please add it to the define once available.
*/
flags |= UINT(ION_SD_FLAGS);
} else if (usage & BufferUsage::CAMERA_OUTPUT) {
heap_id = ION_HEAP(SD_HEAP_ID);
if (usage & BufferUsage::COMPOSER_OVERLAY) {
flags |= UINT(ION_SC_PREVIEW_FLAGS);
} else {
flags |= UINT(ION_SC_FLAGS);
}
} else {
heap_id = ION_HEAP(CP_HEAP_ID);
flags |= UINT(ION_CP_FLAGS);
}
}
if (usage & BufferUsage::SENSOR_DIRECT_DATA) {
heap_id |= ION_HEAP(ION_ADSP_HEAP_ID);
}
if (flags & UINT(ION_SECURE)) {
type |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
}
// if no ion heap flags are set, default to system heap
if (!heap_id) {
heap_id = ION_HEAP(ION_SYSTEM_HEAP_ID);
}
*alloc_type = type;
*ion_flags = flags;
*ion_heap_id = heap_id;
return;
}
} // namespace gralloc

View File

@@ -1,73 +0,0 @@
/*
* Copyright (c) 2011-2018, 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:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __GR_ALLOCATOR_H__
#define __GR_ALLOCATOR_H__
#ifdef MASTER_SIDE_CP
#define SECURE_ALIGN SZ_4K
#else
#define SECURE_ALIGN SZ_1M
#endif
#include <vector>
#include "gr_buf_descriptor.h"
#include "gr_ion_alloc.h"
#include "gralloc_priv.h"
namespace gralloc {
class Allocator {
public:
Allocator();
~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 handle, int op);
int AllocateMem(AllocData *data, uint64_t usage);
// @return : index of the descriptor with maximum buffer size req
bool CheckForBufferSharing(uint32_t num_descriptors,
const std::vector<std::shared_ptr<BufferDescriptor>> &descriptors,
ssize_t *max_index);
int GetImplDefinedFormat(uint64_t usage, int format);
bool UseUncached(uint64_t usage);
private:
void GetIonHeapInfo(uint64_t usage, unsigned int *ion_heap_id, unsigned int *alloc_type,
unsigned int *ion_flags);
IonAlloc *ion_allocator_ = NULL;
};
} // namespace gralloc
#endif // __GR_ALLOCATOR_H__

View File

@@ -1,106 +0,0 @@
/*
* Copyright (c) 2016-2018, 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:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __GR_BUF_DESCRIPTOR_H__
#define __GR_BUF_DESCRIPTOR_H__
#include <android/hardware/graphics/mapper/2.0/IMapper.h>
#include <atomic>
namespace gralloc {
using android::hardware::graphics::mapper::V2_0::Error;
using android::hardware::graphics::mapper::V2_0::IMapper;
using android::hardware::hidl_vec;
const uint32_t kBufferDescriptorSize = 7;
const uint32_t kMagicVersion = 0x76312E30; // v1.0
class BufferDescriptor {
public:
BufferDescriptor() {}
explicit BufferDescriptor(uint64_t id) : id_(id) {}
static hidl_vec<uint32_t> Encode(const IMapper::BufferDescriptorInfo &bd_info) {
hidl_vec<uint32_t> out;
out.resize(kBufferDescriptorSize);
out[0] = kMagicVersion;
out[1] = bd_info.width;
out[2] = bd_info.height;
out[3] = bd_info.layerCount;
out[4] = static_cast<uint32_t>(bd_info.format);
out[5] = static_cast<uint32_t>(bd_info.usage);
out[6] = static_cast<uint32_t>(bd_info.usage >> 32);
return out;
}
Error Decode(const hidl_vec<uint32_t> &in) {
if (in.size() != kBufferDescriptorSize || in[0] != kMagicVersion) {
return Error::BAD_DESCRIPTOR;
}
width_ = static_cast<int32_t>(in[1]);
height_ = static_cast<int32_t>(in[2]);
layer_count_ = in[3];
format_ = static_cast<int32_t>(in[4]);
usage_ = static_cast<uint64_t>(in[6]) << 32 | in[5];
return Error::NONE;
}
void SetUsage(uint64_t usage) { usage_ |= usage; }
void SetDimensions(int w, int h) {
width_ = w;
height_ = h;
}
void SetColorFormat(int format) { format_ = format; }
void SetLayerCount(uint32_t layer_count) { layer_count_ = layer_count; }
uint64_t GetUsage() const { return usage_; }
int GetWidth() const { return width_; }
int GetHeight() const { return height_; }
int GetFormat() const { return format_; }
uint32_t GetLayerCount() const { return layer_count_; }
uint64_t GetId() const { return id_; }
private:
int width_ = -1;
int height_ = -1;
int format_ = -1;
uint32_t layer_count_ = 1;
uint64_t usage_ = 0;
const uint64_t id_ = 0;
};
}; // namespace gralloc
#endif // __GR_BUF_DESCRIPTOR_H__

View File

@@ -1,399 +0,0 @@
/*
* Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
* Not a Contribution
*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define DEBUG 0
#include <iomanip>
#include <sstream>
#include <utility>
#include <vector>
#include "gr_buf_descriptor.h"
#include "gr_buf_mgr.h"
#include "gr_priv_handle.h"
#include "gr_utils.h"
#include "qdMetaData.h"
#include "qd_utils.h"
namespace gralloc {
static BufferInfo GetBufferInfo(const BufferDescriptor &descriptor) {
return BufferInfo(descriptor.GetWidth(), descriptor.GetHeight(), descriptor.GetFormat(),
descriptor.GetUsage());
}
BufferManager::BufferManager() : next_id_(0) {
handles_map_.clear();
allocator_ = new Allocator();
allocator_->Init();
}
BufferManager *BufferManager::GetInstance() {
static BufferManager *instance = new BufferManager();
return instance;
}
BufferManager::~BufferManager() {
if (allocator_) {
delete allocator_;
}
}
Error BufferManager::FreeBuffer(std::shared_ptr<Buffer> buf) {
auto hnd = buf->handle;
ALOGD_IF(DEBUG, "FreeBuffer handle:%p", hnd);
if (private_handle_t::validate(hnd) != 0) {
ALOGE("FreeBuffer: Invalid handle: %p", hnd);
return Error::BAD_BUFFER;
}
if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset, hnd->fd,
buf->ion_handle_main) != 0) {
return Error::BAD_BUFFER;
}
unsigned int meta_size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE);
if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base_metadata), meta_size,
hnd->offset_metadata, hnd->fd_metadata, buf->ion_handle_meta) != 0) {
return Error::BAD_BUFFER;
}
private_handle_t *handle = const_cast<private_handle_t *>(hnd);
handle->fd = -1;
handle->fd_metadata = -1;
if (!(handle->flags & private_handle_t::PRIV_FLAGS_CLIENT_ALLOCATED)) {
delete handle;
}
return Error::NONE;
}
void BufferManager::RegisterHandleLocked(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));
}
Error BufferManager::ImportHandleLocked(private_handle_t *hnd) {
ALOGD_IF(DEBUG, "Importing handle:%p id: %" PRIu64, hnd, hnd->id);
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 Error::BAD_BUFFER;
}
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 Error::BAD_BUFFER;
}
// Set base pointers to NULL since the data here was received over binder
hnd->base = 0;
hnd->base_metadata = 0;
RegisterHandleLocked(hnd, ion_handle, ion_handle_meta);
return Error::NONE;
}
std::shared_ptr<BufferManager::Buffer> BufferManager::GetBufferFromHandleLocked(
const private_handle_t *hnd) {
auto it = handles_map_.find(hnd);
if (it != handles_map_.end()) {
return it->second;
} else {
return nullptr;
}
}
Error BufferManager::MapBuffer(private_handle_t const *handle) {
private_handle_t *hnd = const_cast<private_handle_t *>(handle);
ALOGD_IF(DEBUG, "Map buffer handle:%p id: %" PRIu64, hnd, hnd->id);
hnd->base = 0;
if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base), hnd->size, hnd->offset,
hnd->fd) != 0) {
return Error::BAD_BUFFER;
}
return Error::NONE;
}
Error BufferManager::RetainBuffer(private_handle_t const *hnd) {
ALOGD_IF(DEBUG, "Retain buffer handle:%p id: %" PRIu64, hnd, hnd->id);
auto err = Error::NONE;
std::lock_guard<std::mutex> lock(buffer_lock_);
auto buf = GetBufferFromHandleLocked(hnd);
if (buf != nullptr) {
buf->IncRef();
} else {
private_handle_t *handle = const_cast<private_handle_t *>(hnd);
err = ImportHandleLocked(handle);
}
return err;
}
Error BufferManager::ReleaseBuffer(private_handle_t const *hnd) {
ALOGD_IF(DEBUG, "Release buffer handle:%p", hnd);
std::lock_guard<std::mutex> lock(buffer_lock_);
auto buf = GetBufferFromHandleLocked(hnd);
if (buf == nullptr) {
ALOGE("Could not find handle: %p id: %" PRIu64, hnd, hnd->id);
return Error::BAD_BUFFER;
} else {
if (buf->DecRef()) {
handles_map_.erase(hnd);
// Unmap, close ion handle and close fd
FreeBuffer(buf);
}
}
return Error::NONE;
}
Error BufferManager::LockBuffer(const private_handle_t *hnd, uint64_t usage) {
std::lock_guard<std::mutex> lock(buffer_lock_);
auto err = Error::NONE;
ALOGD_IF(DEBUG, "LockBuffer buffer handle:%p id: %" PRIu64, hnd, hnd->id);
// If buffer is not meant for CPU return err
if (!CpuCanAccess(usage)) {
return Error::BAD_VALUE;
}
auto buf = GetBufferFromHandleLocked(hnd);
if (buf == nullptr) {
return Error::BAD_BUFFER;
}
if (hnd->base == 0) {
// we need to map for real
err = MapBuffer(hnd);
}
// 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 == Error::NONE && (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,
buf->ion_handle_main, CACHE_INVALIDATE)) {
return Error::BAD_BUFFER;
}
}
// Mark the buffer to be flushed after CPU write.
if (err == Error::NONE && CpuCanWrite(usage)) {
private_handle_t *handle = const_cast<private_handle_t *>(hnd);
handle->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
}
return err;
}
Error BufferManager::UnlockBuffer(const private_handle_t *handle) {
std::lock_guard<std::mutex> lock(buffer_lock_);
auto status = Error::NONE;
private_handle_t *hnd = const_cast<private_handle_t *>(handle);
auto buf = GetBufferFromHandleLocked(hnd);
if (buf == nullptr) {
return Error::BAD_BUFFER;
}
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) {
status = Error::BAD_BUFFER;
}
hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
}
return status;
}
uint32_t BufferManager::GetDataAlignment(int format, uint64_t usage) {
uint32_t align = UINT(getpagesize());
if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
align = 8192;
}
if (usage & BufferUsage::PROTECTED) {
if ((usage & BufferUsage::CAMERA_OUTPUT) || (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY)) {
// The alignment here reflects qsee mmu V7L/V8L requirement
align = SZ_2M;
} else {
align = SECURE_ALIGN;
}
}
return align;
}
int BufferManager::GetHandleFlags(int format, uint64_t usage) {
int flags = 0;
if (usage & BufferUsage::VIDEO_ENCODER) {
flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER;
}
if (usage & BufferUsage::CAMERA_OUTPUT) {
flags |= private_handle_t::PRIV_FLAGS_CAMERA_WRITE;
}
if (usage & BufferUsage::CAMERA_INPUT) {
flags |= private_handle_t::PRIV_FLAGS_CAMERA_READ;
}
if (usage & BufferUsage::COMPOSER_OVERLAY) {
flags |= private_handle_t::PRIV_FLAGS_DISP_CONSUMER;
}
if (usage & BufferUsage::GPU_TEXTURE) {
flags |= private_handle_t::PRIV_FLAGS_HW_TEXTURE;
}
if (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) {
flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
}
if (IsUBwcEnabled(format, usage)) {
flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
}
if (usage & (BufferUsage::CPU_READ_MASK | BufferUsage::CPU_WRITE_MASK)) {
flags |= private_handle_t::PRIV_FLAGS_CPU_RENDERED;
}
if ((usage & (BufferUsage::VIDEO_ENCODER | BufferUsage::VIDEO_DECODER |
BufferUsage::CAMERA_OUTPUT | BufferUsage::GPU_RENDER_TARGET))) {
flags |= private_handle_t::PRIV_FLAGS_NON_CPU_WRITER;
}
if (!allocator_->UseUncached(usage)) {
flags |= private_handle_t::PRIV_FLAGS_CACHED;
}
return flags;
}
int BufferManager::GetBufferType(int inputFormat) {
int buffer_type = BUFFER_TYPE_VIDEO;
if (IsUncompressedRGBFormat(inputFormat)) {
// RGB formats
buffer_type = BUFFER_TYPE_UI;
}
return buffer_type;
}
Error BufferManager::AllocateBuffer(const BufferDescriptor &descriptor, buffer_handle_t *handle,
unsigned int bufferSize) {
if (!handle)
return Error::BAD_BUFFER;
std::lock_guard<std::mutex> buffer_lock(buffer_lock_);
uint64_t usage = descriptor.GetUsage();
int format = allocator_->GetImplDefinedFormat(usage, descriptor.GetFormat());
uint32_t layer_count = descriptor.GetLayerCount();
unsigned int size;
unsigned int alignedw, alignedh;
int buffer_type = GetBufferType(format);
BufferInfo info = GetBufferInfo(descriptor);
info.format = format;
GetBufferSizeAndDimensions(info, &size, &alignedw, &alignedh);
size = (bufferSize >= size) ? bufferSize : size;
int err = 0;
int flags = 0;
auto page_size = UINT(getpagesize());
AllocData data;
data.align = GetDataAlignment(format, usage);
size = ALIGN(size, data.align) * layer_count;
data.size = size;
data.handle = (uintptr_t)handle;
data.uncached = allocator_->UseUncached(usage);
// Allocate buffer memory
err = allocator_->AllocateMem(&data, usage);
if (err) {
ALOGE("gralloc failed to allocate err=%s", strerror(-err));
return Error::NO_RESOURCES;
}
// Allocate memory for MetaData
AllocData e_data;
e_data.size = ALIGN(UINT(sizeof(MetaData_t)), page_size);
e_data.handle = data.handle;
e_data.align = page_size;
err = allocator_->AllocateMem(&e_data, 0);
if (err) {
ALOGE("gralloc failed to allocate metadata error=%s", strerror(-err));
return Error::NO_RESOURCES;
}
flags = GetHandleFlags(format, usage);
flags |= data.alloc_type;
// Create handle
private_handle_t *hnd = new private_handle_t(
data.fd, e_data.fd, flags, INT(alignedw), INT(alignedh), descriptor.GetWidth(),
descriptor.GetHeight(), format, buffer_type, data.size, usage);
hnd->id = ++next_id_;
hnd->base = 0;
hnd->base_metadata = 0;
hnd->layer_count = layer_count;
ColorSpace_t colorSpace = ITU_R_601;
setMetaData(hnd, UPDATE_COLOR_SPACE, reinterpret_cast<void *>(&colorSpace));
*handle = hnd;
RegisterHandleLocked(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);
}
return Error::NONE;
}
Error BufferManager::Dump(std::ostringstream *os) {
std::lock_guard<std::mutex> buffer_lock(buffer_lock_);
for (auto it : handles_map_) {
auto buf = it.second;
auto hnd = buf->handle;
*os << "handle id: " << std::setw(4) << hnd->id;
*os << " fd: " << std::setw(3) << hnd->fd;
*os << " fd_meta: " << std::setw(3) << hnd->fd_metadata;
*os << " wxh: " << std::setw(4) << hnd->width << " x " << std::setw(4) << hnd->height;
*os << " uwxuh: " << std::setw(4) << hnd->unaligned_width << " x ";
*os << std::setw(4) << hnd->unaligned_height;
*os << " size: " << std::setw(9) << hnd->size;
*os << std::hex << std::setfill('0');
*os << " priv_flags: "
<< "0x" << std::setw(8) << hnd->flags;
*os << " usage: "
<< "0x" << std::setw(8) << hnd->usage;
// TODO(user): get format string from qdutils
*os << " format: "
<< "0x" << std::setw(8) << hnd->format;
*os << std::dec << std::setfill(' ') << std::endl;
}
return Error::NONE;
}
} // namespace gralloc

View File

@@ -1,96 +0,0 @@
/*
* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
* Not a Contribution
*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __GR_BUF_MGR_H__
#define __GR_BUF_MGR_H__
#include <pthread.h>
#include <mutex>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include "gr_allocator.h"
#include "gr_buf_descriptor.h"
#include "gralloc_priv.h"
namespace gralloc {
using android::hardware::graphics::mapper::V2_0::Error;
class BufferManager {
public:
~BufferManager();
Error AllocateBuffer(const BufferDescriptor &descriptor, buffer_handle_t *handle,
unsigned int bufferSize = 0);
Error RetainBuffer(private_handle_t const *hnd);
Error ReleaseBuffer(private_handle_t const *hnd);
Error LockBuffer(const private_handle_t *hnd, uint64_t usage);
Error UnlockBuffer(const private_handle_t *hnd);
Error Dump(std::ostringstream *os);
static BufferManager *GetInstance();
private:
BufferManager();
Error MapBuffer(private_handle_t const *hnd);
int GetBufferType(int format);
uint32_t GetDataAlignment(int format, uint64_t usage);
int GetHandleFlags(int format, uint64_t usage);
// Imports the ion fds into the current process. Returns an error for invalid handles
Error ImportHandleLocked(private_handle_t *hnd);
// Creates a Buffer from the valid private handle and adds it to the map
void RegisterHandleLocked(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
// This structure is also not expected to be ABI stable
// unlike private_handle_t
struct Buffer {
const private_handle_t *handle = nullptr;
int ref_count = 1;
// Hold the main and metadata ion handles
// Freed from the allocator process
// and unused in the mapping process
int ion_handle_main = -1;
int ion_handle_meta = -1;
Buffer() = delete;
explicit Buffer(const private_handle_t *h, int ih_main = -1, int ih_meta = -1)
: handle(h), ion_handle_main(ih_main), ion_handle_meta(ih_meta) {}
void IncRef() { ++ref_count; }
bool DecRef() { return --ref_count == 0; }
};
Error 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> GetBufferFromHandleLocked(const private_handle_t *hnd);
Allocator *allocator_ = NULL;
std::mutex buffer_lock_;
std::unordered_map<const private_handle_t *, std::shared_ptr<Buffer>> handles_map_ = {};
std::atomic<uint64_t> next_id_;
};
} // namespace gralloc
#endif // __GR_BUF_MGR_H__

View File

@@ -1,869 +0,0 @@
/*
* Copyright (c) 2016-2018, 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:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
#include <log/log.h>
#include <cutils/trace.h>
#include <sync/sync.h>
#include <utils/Trace.h>
#include <algorithm>
#include <sstream>
#include <string>
#include "gr_buf_descriptor.h"
#include "gr_device_impl.h"
#include "gr_utils.h"
#include "gralloc_priv.h"
#include "qdMetaData.h"
#include "qd_utils.h"
int gralloc_device_open(const struct hw_module_t *module, const char *name, hw_device_t **device);
int gralloc_device_close(struct hw_device_t *device);
static struct hw_module_methods_t gralloc_module_methods = {.open = gralloc_device_open};
struct gralloc_module_t HAL_MODULE_INFO_SYM = {
// clang-format off
.common = {
.tag = HARDWARE_MODULE_TAG,
.module_api_version = GRALLOC_MODULE_API_VERSION_1_0,
.hal_api_version = HARDWARE_HAL_API_VERSION,
.id = GRALLOC_HARDWARE_MODULE_ID,
.name = "Graphics Memory Module",
.author = "Code Aurora Forum",
.methods = &gralloc_module_methods,
.dso = 0,
.reserved = {0},
},
// clang-format on
};
int gralloc_device_open(const struct hw_module_t *module, const char *name, hw_device_t **device) {
int status = -EINVAL;
if (module && device && !strcmp(name, GRALLOC_HARDWARE_MODULE_ID)) {
gralloc::GrallocImpl * /*gralloc1_device_t*/ dev = gralloc::GrallocImpl::GetInstance(module);
*device = reinterpret_cast<hw_device_t *>(dev);
if (dev) {
status = 0;
} else {
ALOGE("Fatal error opening gralloc1 device");
}
}
return status;
}
namespace gralloc {
std::atomic<uint64_t> GrallocImpl::next_descriptor_id_(1);
GrallocImpl::GrallocImpl(const hw_module_t *module) {
common.tag = HARDWARE_DEVICE_TAG;
common.version = GRALLOC_MODULE_API_VERSION_1_0;
common.module = const_cast<hw_module_t *>(module);
common.close = CloseDevice;
getFunction = GetFunction;
getCapabilities = GetCapabilities;
initialized_ = Init();
}
inline gralloc1_error_t ToError(Error error) {
switch (error) {
case Error::NONE:
return GRALLOC1_ERROR_NONE;
case Error::BAD_DESCRIPTOR:
return GRALLOC1_ERROR_BAD_DESCRIPTOR;
case Error::BAD_BUFFER:
return GRALLOC1_ERROR_BAD_HANDLE;
case Error::BAD_VALUE:
return GRALLOC1_ERROR_BAD_VALUE;
case Error::NO_RESOURCES:
return GRALLOC1_ERROR_NO_RESOURCES;
case Error::UNSUPPORTED:
default:
return GRALLOC1_ERROR_UNSUPPORTED;
}
}
static uint64_t ProducerUsageToBufferUsage(gralloc1_producer_usage_t producer_usage) {
uint64_t usage = producer_usage & ~(GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN |
GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN);
if ((producer_usage & GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN) ==
GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN) {
usage |= BufferUsage::CPU_READ_OFTEN;
} else if ((producer_usage & GRALLOC1_PRODUCER_USAGE_CPU_READ) ==
GRALLOC1_PRODUCER_USAGE_CPU_READ) {
usage |= BufferUsage::CPU_READ_RARELY;
}
if ((producer_usage & GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN) ==
GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN) {
usage |= BufferUsage::CPU_WRITE_OFTEN;
} else if ((producer_usage & GRALLOC1_PRODUCER_USAGE_CPU_WRITE) ==
GRALLOC1_PRODUCER_USAGE_CPU_WRITE) {
usage |= BufferUsage::CPU_WRITE_RARELY;
}
return usage;
}
static uint64_t ConsumerUsageToBufferUsage(gralloc1_consumer_usage_t consumer_usage) {
uint64_t usage = consumer_usage & ~(GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN);
if ((consumer_usage & GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN) ==
GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN) {
usage |= BufferUsage::CPU_READ_OFTEN;
} else if ((consumer_usage & GRALLOC1_CONSUMER_USAGE_CPU_READ) ==
GRALLOC1_CONSUMER_USAGE_CPU_READ) {
usage |= BufferUsage::CPU_READ_RARELY;
}
return usage;
}
bool GrallocImpl::Init() {
buf_mgr_ = BufferManager::GetInstance();
return buf_mgr_ != nullptr;
}
GrallocImpl::~GrallocImpl() {}
gralloc1_error_t GrallocImpl::CreateBufferDescriptorLocked(
gralloc1_buffer_descriptor_t *descriptor_id) {
std::lock_guard<std::mutex> lock(descriptor_lock_);
auto descriptor = std::make_shared<BufferDescriptor>(next_descriptor_id_++);
*descriptor_id = static_cast<gralloc1_buffer_descriptor_t>(descriptor->GetId());
descriptors_map_.emplace(*descriptor_id, descriptor);
return GRALLOC1_ERROR_NONE;
}
gralloc1_error_t GrallocImpl::DestroyBufferDescriptorLocked(
gralloc1_buffer_descriptor_t descriptor_id) {
std::lock_guard<std::mutex> lock(descriptor_lock_);
const auto descriptor = descriptors_map_.find(descriptor_id);
if (descriptor == descriptors_map_.end()) {
return GRALLOC1_ERROR_BAD_DESCRIPTOR;
}
descriptors_map_.erase(descriptor);
return GRALLOC1_ERROR_NONE;
}
int GrallocImpl::CloseDevice(hw_device_t *device __unused) {
// No-op since the gralloc device is a singleton
return 0;
}
void GrallocImpl::GetCapabilities(struct gralloc1_device *device, uint32_t *out_count,
int32_t /*gralloc1_capability_t*/ *out_capabilities) {
if (device != nullptr && out_count != nullptr) {
if (out_capabilities != nullptr && *out_count >= 3) {
out_capabilities[0] = GRALLOC1_CAPABILITY_TEST_ALLOCATE;
out_capabilities[1] = GRALLOC1_CAPABILITY_LAYERED_BUFFERS;
out_capabilities[2] = GRALLOC1_CAPABILITY_RELEASE_IMPLY_DELETE;
}
*out_count = 3;
}
return;
}
gralloc1_function_pointer_t GrallocImpl::GetFunction(gralloc1_device_t *device, int32_t function) {
if (!device) {
return NULL;
}
switch (function) {
case GRALLOC1_FUNCTION_DUMP:
return reinterpret_cast<gralloc1_function_pointer_t>(Dump);
case GRALLOC1_FUNCTION_CREATE_DESCRIPTOR:
return reinterpret_cast<gralloc1_function_pointer_t>(CreateBufferDescriptor);
case GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR:
return reinterpret_cast<gralloc1_function_pointer_t>(DestroyBufferDescriptor);
case GRALLOC1_FUNCTION_SET_CONSUMER_USAGE:
return reinterpret_cast<gralloc1_function_pointer_t>(SetConsumerUsage);
case GRALLOC1_FUNCTION_SET_DIMENSIONS:
return reinterpret_cast<gralloc1_function_pointer_t>(SetBufferDimensions);
case GRALLOC1_FUNCTION_SET_FORMAT:
return reinterpret_cast<gralloc1_function_pointer_t>(SetColorFormat);
case GRALLOC1_FUNCTION_SET_LAYER_COUNT:
return reinterpret_cast<gralloc1_function_pointer_t>(SetLayerCount);
case GRALLOC1_FUNCTION_SET_PRODUCER_USAGE:
return reinterpret_cast<gralloc1_function_pointer_t>(SetProducerUsage);
case GRALLOC1_FUNCTION_GET_BACKING_STORE:
return reinterpret_cast<gralloc1_function_pointer_t>(GetBackingStore);
case GRALLOC1_FUNCTION_GET_CONSUMER_USAGE:
return reinterpret_cast<gralloc1_function_pointer_t>(GetConsumerUsage);
case GRALLOC1_FUNCTION_GET_DIMENSIONS:
return reinterpret_cast<gralloc1_function_pointer_t>(GetBufferDimensions);
case GRALLOC1_FUNCTION_GET_FORMAT:
return reinterpret_cast<gralloc1_function_pointer_t>(GetColorFormat);
case GRALLOC1_FUNCTION_GET_LAYER_COUNT:
return reinterpret_cast<gralloc1_function_pointer_t>(GetLayerCount);
case GRALLOC1_FUNCTION_GET_PRODUCER_USAGE:
return reinterpret_cast<gralloc1_function_pointer_t>(GetProducerUsage);
case GRALLOC1_FUNCTION_GET_STRIDE:
return reinterpret_cast<gralloc1_function_pointer_t>(GetBufferStride);
case GRALLOC1_FUNCTION_ALLOCATE:
return reinterpret_cast<gralloc1_function_pointer_t>(AllocateBuffers);
case GRALLOC1_FUNCTION_RETAIN:
return reinterpret_cast<gralloc1_function_pointer_t>(RetainBuffer);
case GRALLOC1_FUNCTION_RELEASE:
return reinterpret_cast<gralloc1_function_pointer_t>(ReleaseBuffer);
case GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES:
return reinterpret_cast<gralloc1_function_pointer_t>(GetNumFlexPlanes);
case GRALLOC1_FUNCTION_LOCK:
return reinterpret_cast<gralloc1_function_pointer_t>(LockBuffer);
case GRALLOC1_FUNCTION_LOCK_FLEX:
return reinterpret_cast<gralloc1_function_pointer_t>(LockFlex);
case GRALLOC1_FUNCTION_UNLOCK:
return reinterpret_cast<gralloc1_function_pointer_t>(UnlockBuffer);
case GRALLOC1_FUNCTION_PERFORM:
return reinterpret_cast<gralloc1_function_pointer_t>(Gralloc1Perform);
default:
ALOGE("%s:Gralloc Error. Client Requested for unsupported function", __FUNCTION__);
return NULL;
}
return NULL;
}
gralloc1_error_t GrallocImpl::Dump(gralloc1_device_t *device, uint32_t *out_size,
char *out_buffer) {
if (!device || !out_size) {
ALOGE("Gralloc Error : device=%p", (void *)device);
return GRALLOC1_ERROR_BAD_DESCRIPTOR;
}
const size_t max_dump_size = 8192;
if (out_buffer == nullptr) {
*out_size = max_dump_size;
} else {
std::ostringstream os;
os << "-------------------------------" << std::endl;
os << "QTI gralloc dump:" << std::endl;
os << "-------------------------------" << std::endl;
GrallocImpl const *dev = GRALLOC_IMPL(device);
dev->buf_mgr_->Dump(&os);
os << "-------------------------------" << std::endl;
auto copied = os.str().copy(out_buffer, std::min(os.str().size(), max_dump_size), 0);
*out_size = UINT(copied);
}
return GRALLOC1_ERROR_NONE;
}
gralloc1_error_t GrallocImpl::CheckDeviceAndHandle(gralloc1_device_t *device,
buffer_handle_t buffer) {
const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
if (!device || (private_handle_t::validate(hnd) != 0)) {
ALOGE("Gralloc Error : device= %p, buffer-handle=%p", (void *)device, (void *)buffer);
return GRALLOC1_ERROR_BAD_HANDLE;
}
return GRALLOC1_ERROR_NONE;
}
gralloc1_error_t GrallocImpl::CreateBufferDescriptor(gralloc1_device_t *device,
gralloc1_buffer_descriptor_t *out_descriptor) {
if (!device || !out_descriptor) {
return GRALLOC1_ERROR_BAD_DESCRIPTOR;
}
auto *dev = reinterpret_cast<GrallocImpl *>(device);
return dev->CreateBufferDescriptorLocked(out_descriptor);
}
gralloc1_error_t GrallocImpl::DestroyBufferDescriptor(gralloc1_device_t *device,
gralloc1_buffer_descriptor_t descriptor) {
if (!device) {
return GRALLOC1_ERROR_BAD_DESCRIPTOR;
}
auto *dev = reinterpret_cast<GrallocImpl *>(device);
return dev->DestroyBufferDescriptorLocked(descriptor);
}
gralloc1_error_t GrallocImpl::SetConsumerUsage(gralloc1_device_t *device,
gralloc1_buffer_descriptor_t descriptor,
gralloc1_consumer_usage_t usage) {
if (!device) {
return GRALLOC1_ERROR_BAD_DESCRIPTOR;
} else {
auto *dev = reinterpret_cast<GrallocImpl *>(device);
return dev->CallBufferDescriptorFunction(descriptor, &BufferDescriptor::SetUsage,
ConsumerUsageToBufferUsage(usage));
}
}
gralloc1_error_t GrallocImpl::SetBufferDimensions(gralloc1_device_t *device,
gralloc1_buffer_descriptor_t descriptor,
uint32_t width, uint32_t height) {
if (!device) {
return GRALLOC1_ERROR_BAD_DESCRIPTOR;
} else {
auto *dev = reinterpret_cast<GrallocImpl *>(device);
return dev->CallBufferDescriptorFunction(descriptor, &BufferDescriptor::SetDimensions,
INT(width), INT(height));
}
}
gralloc1_error_t GrallocImpl::SetColorFormat(gralloc1_device_t *device,
gralloc1_buffer_descriptor_t descriptor,
int32_t format) {
if (!device) {
return GRALLOC1_ERROR_BAD_DESCRIPTOR;
} else {
auto *dev = reinterpret_cast<GrallocImpl *>(device);
return dev->CallBufferDescriptorFunction(descriptor, &BufferDescriptor::SetColorFormat, format);
}
}
gralloc1_error_t GrallocImpl::SetLayerCount(gralloc1_device_t *device,
gralloc1_buffer_descriptor_t descriptor,
uint32_t layer_count) {
if (!device) {
return GRALLOC1_ERROR_BAD_DESCRIPTOR;
} else {
auto *dev = reinterpret_cast<GrallocImpl *>(device);
return dev->CallBufferDescriptorFunction(descriptor, &BufferDescriptor::SetLayerCount,
layer_count);
}
}
gralloc1_error_t GrallocImpl::SetProducerUsage(gralloc1_device_t *device,
gralloc1_buffer_descriptor_t descriptor,
gralloc1_producer_usage_t usage) {
if (!device) {
return GRALLOC1_ERROR_BAD_DESCRIPTOR;
} else {
auto *dev = reinterpret_cast<GrallocImpl *>(device);
return dev->CallBufferDescriptorFunction(descriptor, &BufferDescriptor::SetUsage,
ProducerUsageToBufferUsage(usage));
}
}
gralloc1_error_t GrallocImpl::GetBackingStore(gralloc1_device_t *device, buffer_handle_t buffer,
gralloc1_backing_store_t *out_backstore) {
if (!device || !buffer) {
return GRALLOC1_ERROR_BAD_HANDLE;
}
*out_backstore =
static_cast<gralloc1_backing_store_t>(PRIV_HANDLE_CONST(buffer)->GetBackingstore());
return GRALLOC1_ERROR_NONE;
}
gralloc1_error_t GrallocImpl::GetConsumerUsage(gralloc1_device_t *device, buffer_handle_t buffer,
gralloc1_consumer_usage_t *outUsage) {
gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
if (status == GRALLOC1_ERROR_NONE) {
*outUsage = static_cast<gralloc1_consumer_usage_t>(PRIV_HANDLE_CONST(buffer)->GetUsage());
}
return status;
}
gralloc1_error_t GrallocImpl::GetBufferDimensions(gralloc1_device_t *device, buffer_handle_t buffer,
uint32_t *outWidth, uint32_t *outHeight) {
gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
if (status == GRALLOC1_ERROR_NONE) {
const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
*outWidth = UINT(hnd->GetUnalignedWidth());
*outHeight = UINT(hnd->GetUnalignedHeight());
}
return status;
}
gralloc1_error_t GrallocImpl::GetColorFormat(gralloc1_device_t *device, buffer_handle_t buffer,
int32_t *outFormat) {
gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
if (status == GRALLOC1_ERROR_NONE) {
*outFormat = PRIV_HANDLE_CONST(buffer)->GetColorFormat();
}
return status;
}
gralloc1_error_t GrallocImpl::GetLayerCount(gralloc1_device_t *device, buffer_handle_t buffer,
uint32_t *outLayerCount) {
gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
if (status == GRALLOC1_ERROR_NONE) {
*outLayerCount = PRIV_HANDLE_CONST(buffer)->GetLayerCount();
}
return status;
}
gralloc1_error_t GrallocImpl::GetProducerUsage(gralloc1_device_t *device, buffer_handle_t buffer,
gralloc1_producer_usage_t *outUsage) {
if (!outUsage) {
return GRALLOC1_ERROR_BAD_VALUE;
}
gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
if (status == GRALLOC1_ERROR_NONE) {
*outUsage = static_cast<gralloc1_producer_usage_t>(PRIV_HANDLE_CONST(buffer)->GetUsage());
}
return status;
}
gralloc1_error_t GrallocImpl::GetBufferStride(gralloc1_device_t *device, buffer_handle_t buffer,
uint32_t *outStride) {
if (!outStride) {
return GRALLOC1_ERROR_BAD_VALUE;
}
gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
if (status == GRALLOC1_ERROR_NONE) {
*outStride = UINT(PRIV_HANDLE_CONST(buffer)->GetStride());
}
return status;
}
gralloc1_error_t GrallocImpl::AllocateBuffer(const gralloc1_buffer_descriptor_t *descriptor_ids,
buffer_handle_t *out_buffers) {
gralloc1_error_t status = GRALLOC1_ERROR_NONE;
// Validate descriptor
std::lock_guard<std::mutex> descriptor_lock(descriptor_lock_);
std::shared_ptr<gralloc::BufferDescriptor> descriptor;
const auto map_descriptor = descriptors_map_.find(descriptor_ids[0]);
if (map_descriptor == descriptors_map_.end()) {
return GRALLOC1_ERROR_BAD_DESCRIPTOR;
} else {
descriptor = map_descriptor->second;
}
// Allocate separate buffer for each descriptor
if (buf_mgr_->AllocateBuffer(*descriptor, &out_buffers[0]) != Error::NONE) {
return GRALLOC1_ERROR_NO_RESOURCES;
}
return status;
}
gralloc1_error_t GrallocImpl::AllocateBuffers(gralloc1_device_t *device, uint32_t num_descriptors,
const gralloc1_buffer_descriptor_t *descriptors,
buffer_handle_t *out_buffers) {
if (!num_descriptors || !descriptors) {
return GRALLOC1_ERROR_BAD_DESCRIPTOR;
}
if (!device) {
return GRALLOC1_ERROR_BAD_VALUE;
}
if (num_descriptors != 1) {
return GRALLOC1_ERROR_UNSUPPORTED;
}
auto *dev = reinterpret_cast<GrallocImpl *>(device);
gralloc1_error_t status = dev->AllocateBuffer(descriptors, out_buffers);
return status;
}
gralloc1_error_t GrallocImpl::RetainBuffer(gralloc1_device_t *device, buffer_handle_t buffer) {
gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
if (status == GRALLOC1_ERROR_NONE) {
const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
GrallocImpl const *dev = GRALLOC_IMPL(device);
status = ToError(dev->buf_mgr_->RetainBuffer(hnd));
}
return status;
}
gralloc1_error_t GrallocImpl::ReleaseBuffer(gralloc1_device_t *device, buffer_handle_t buffer) {
if (!device || !buffer) {
return GRALLOC1_ERROR_BAD_DESCRIPTOR;
}
const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
GrallocImpl const *dev = GRALLOC_IMPL(device);
return ToError(dev->buf_mgr_->ReleaseBuffer(hnd));
}
gralloc1_error_t GrallocImpl::GetFlexLayout(const private_handle_t *hnd,
struct android_flex_layout *layout) {
if (!IsYuvFormat(hnd)) {
return GRALLOC1_ERROR_UNSUPPORTED;
}
android_ycbcr yuvPlaneInfo[2];
int err = GetYUVPlaneInfo(hnd, yuvPlaneInfo);
if (err != 0) {
return GRALLOC1_ERROR_BAD_HANDLE;
}
layout->format = FLEX_FORMAT_YCbCr;
layout->num_planes = 3;
for (uint32_t i = 0; i < layout->num_planes; i++) {
layout->planes[i].bits_per_component = 8;
layout->planes[i].bits_used = 8;
layout->planes[i].h_increment = 1;
layout->planes[i].v_increment = 1;
layout->planes[i].h_subsampling = 2;
layout->planes[i].v_subsampling = 2;
}
// We are only returning flex layout for progressive or single field formats.
struct android_ycbcr ycbcr = yuvPlaneInfo[0];
layout->planes[0].top_left = static_cast<uint8_t *>(ycbcr.y);
layout->planes[0].component = FLEX_COMPONENT_Y;
layout->planes[0].v_increment = static_cast<int32_t>(ycbcr.ystride);
layout->planes[1].top_left = static_cast<uint8_t *>(ycbcr.cb);
layout->planes[1].component = FLEX_COMPONENT_Cb;
layout->planes[1].h_increment = static_cast<int32_t>(ycbcr.chroma_step);
layout->planes[1].v_increment = static_cast<int32_t>(ycbcr.cstride);
layout->planes[2].top_left = static_cast<uint8_t *>(ycbcr.cr);
layout->planes[2].component = FLEX_COMPONENT_Cr;
layout->planes[2].h_increment = static_cast<int32_t>(ycbcr.chroma_step);
layout->planes[2].v_increment = static_cast<int32_t>(ycbcr.cstride);
return GRALLOC1_ERROR_NONE;
}
gralloc1_error_t GrallocImpl::GetNumFlexPlanes(gralloc1_device_t *device, buffer_handle_t buffer,
uint32_t *out_num_planes) {
if (!out_num_planes) {
return GRALLOC1_ERROR_BAD_VALUE;
}
gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
if (status == GRALLOC1_ERROR_NONE) {
const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
if (!IsYuvFormat(hnd)) {
status = GRALLOC1_ERROR_UNSUPPORTED;
} else {
*out_num_planes = 3;
}
}
return status;
}
static inline void CloseFdIfValid(int fd) {
if (fd > 0) {
close(fd);
}
}
gralloc1_error_t GrallocImpl::LockBuffer(gralloc1_device_t *device, buffer_handle_t buffer,
gralloc1_producer_usage_t prod_usage,
gralloc1_consumer_usage_t cons_usage,
const gralloc1_rect_t *region, void **out_data,
int32_t acquire_fence) {
ATRACE_CALL();
gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
if (status != GRALLOC1_ERROR_NONE || !out_data ||
!region) { // currently we ignore the region/rect client wants to lock
CloseFdIfValid(acquire_fence);
return status;
}
if (acquire_fence > 0) {
ATRACE_BEGIN("fence wait");
int error = sync_wait(acquire_fence, 1000);
ATRACE_END();
CloseFdIfValid(acquire_fence);
if (error < 0) {
ALOGE("%s: sync_wait timedout! error = %s", __FUNCTION__, strerror(errno));
return GRALLOC1_ERROR_UNDEFINED;
}
}
const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
GrallocImpl const *dev = GRALLOC_IMPL(device);
// Either producer usage or consumer usage must be *_USAGE_NONE
if ((prod_usage != GRALLOC1_PRODUCER_USAGE_NONE) &&
(cons_usage != GRALLOC1_CONSUMER_USAGE_NONE)) {
// Current gralloc1 clients do not satisfy this restriction.
// See b/33588773 for details
// return GRALLOC1_ERROR_BAD_VALUE;
}
status = ToError(dev->buf_mgr_->LockBuffer(
hnd, ProducerUsageToBufferUsage(prod_usage) | ConsumerUsageToBufferUsage(cons_usage)));
*out_data = reinterpret_cast<void *>(hnd->base);
return status;
}
gralloc1_error_t GrallocImpl::LockFlex(gralloc1_device_t *device, buffer_handle_t buffer,
gralloc1_producer_usage_t prod_usage,
gralloc1_consumer_usage_t cons_usage,
const gralloc1_rect_t *region,
struct android_flex_layout *out_flex_layout,
int32_t acquire_fence) {
if (!out_flex_layout) {
CloseFdIfValid(acquire_fence);
return GRALLOC1_ERROR_BAD_VALUE;
}
void *out_data{};
gralloc1_error_t status = GrallocImpl::LockBuffer(device, buffer, prod_usage, cons_usage, region,
&out_data, acquire_fence);
if (status != GRALLOC1_ERROR_NONE) {
return status;
}
auto *dev = reinterpret_cast<GrallocImpl *>(device);
const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
dev->GetFlexLayout(hnd, out_flex_layout);
return status;
}
gralloc1_error_t GrallocImpl::UnlockBuffer(gralloc1_device_t *device, buffer_handle_t buffer,
int32_t *release_fence) {
gralloc1_error_t status = CheckDeviceAndHandle(device, buffer);
if (status != GRALLOC1_ERROR_NONE) {
return status;
}
if (!release_fence) {
return GRALLOC1_ERROR_BAD_VALUE;
}
const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer);
GrallocImpl const *dev = GRALLOC_IMPL(device);
*release_fence = -1;
return ToError(dev->buf_mgr_->UnlockBuffer(hnd));
}
static gralloc1_error_t Perform(int operation, va_list args) {
switch (operation) {
case GRALLOC_MODULE_PERFORM_GET_STRIDE: {
int width = va_arg(args, int);
int format = va_arg(args, int);
int *stride = va_arg(args, int *);
unsigned int alignedw = 0, alignedh = 0;
if (!stride) {
return GRALLOC1_ERROR_BAD_VALUE;
}
BufferInfo info(width, width, format);
GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
*stride = INT(alignedw);
} break;
case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE: {
private_handle_t *hnd = va_arg(args, private_handle_t *);
int *stride = va_arg(args, int *);
if (private_handle_t::validate(hnd) != 0) {
return GRALLOC1_ERROR_BAD_HANDLE;
}
if (!stride) {
return GRALLOC1_ERROR_BAD_VALUE;
}
BufferDim_t buffer_dim;
if (getMetaData(hnd, GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
*stride = buffer_dim.sliceWidth;
} else {
*stride = hnd->width;
}
} break;
case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE: {
private_handle_t *hnd = va_arg(args, private_handle_t *);
int *stride = va_arg(args, int *);
int *height = va_arg(args, int *);
if (private_handle_t::validate(hnd) != 0) {
return GRALLOC1_ERROR_BAD_HANDLE;
}
if (!stride || !height) {
return GRALLOC1_ERROR_BAD_VALUE;
}
GetCustomDimensions(hnd, stride, height);
} break;
case GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES: {
int width = va_arg(args, int);
int height = va_arg(args, int);
int format = va_arg(args, int);
uint64_t usage = va_arg(args, uint64_t);
usage |= va_arg(args, uint64_t);
int *aligned_width = va_arg(args, int *);
int *aligned_height = va_arg(args, int *);
int *tile_enabled = va_arg(args, int *);
if (!aligned_width || !aligned_height || !tile_enabled) {
return GRALLOC1_ERROR_BAD_VALUE;
}
unsigned int alignedw, alignedh;
BufferInfo info(width, height, format, usage);
*tile_enabled = IsUBwcEnabled(format, usage);
GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
*aligned_width = INT(alignedw);
*aligned_height = INT(alignedh);
} break;
case GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE: {
private_handle_t *hnd = va_arg(args, private_handle_t *);
int *color_space = va_arg(args, int *);
if (private_handle_t::validate(hnd) != 0) {
return GRALLOC1_ERROR_BAD_HANDLE;
}
if (!color_space) {
return GRALLOC1_ERROR_BAD_VALUE;
}
*color_space = 0;
GetColorSpaceFromMetadata(hnd, color_space);
} break;
case GRALLOC_MODULE_PERFORM_GET_YUV_PLANE_INFO: {
private_handle_t *hnd = va_arg(args, private_handle_t *);
android_ycbcr *ycbcr = va_arg(args, struct android_ycbcr *);
if (private_handle_t::validate(hnd) != 0) {
return GRALLOC1_ERROR_BAD_HANDLE;
}
if (!ycbcr) {
return GRALLOC1_ERROR_BAD_VALUE;
}
if (GetYUVPlaneInfo(hnd, ycbcr)) {
return GRALLOC1_ERROR_UNDEFINED;
}
} break;
case GRALLOC_MODULE_PERFORM_GET_MAP_SECURE_BUFFER_INFO: {
private_handle_t *hnd = va_arg(args, private_handle_t *);
int *map_secure_buffer = va_arg(args, int *);
if (private_handle_t::validate(hnd) != 0) {
return GRALLOC1_ERROR_BAD_HANDLE;
}
if (!map_secure_buffer) {
return GRALLOC1_ERROR_BAD_VALUE;
}
if (getMetaData(hnd, GET_MAP_SECURE_BUFFER, map_secure_buffer) != 0) {
*map_secure_buffer = 0;
}
} break;
case GRALLOC_MODULE_PERFORM_GET_UBWC_FLAG: {
private_handle_t *hnd = va_arg(args, private_handle_t *);
int *flag = va_arg(args, int *);
if (private_handle_t::validate(hnd) != 0) {
return GRALLOC1_ERROR_BAD_HANDLE;
}
if (!flag) {
return GRALLOC1_ERROR_BAD_VALUE;
}
*flag = hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
int linear_format = 0;
if (getMetaData(hnd, GET_LINEAR_FORMAT, &linear_format) == 0) {
if (linear_format) {
*flag = 0;
}
}
} break;
case GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS: {
private_handle_t *hnd = va_arg(args, private_handle_t *);
void **rgb_data = va_arg(args, void **);
if (private_handle_t::validate(hnd) != 0) {
return GRALLOC1_ERROR_BAD_HANDLE;
}
if (!rgb_data) {
return GRALLOC1_ERROR_BAD_VALUE;
}
if (GetRgbDataAddress(hnd, rgb_data)) {
return GRALLOC1_ERROR_UNDEFINED;
}
} break;
case GRALLOC1_MODULE_PERFORM_GET_INTERLACE_FLAG: {
private_handle_t *hnd = va_arg(args, private_handle_t *);
int *flag = va_arg(args, int *);
if (private_handle_t::validate(hnd) != 0) {
return GRALLOC1_ERROR_BAD_HANDLE;
}
if (!flag) {
return GRALLOC1_ERROR_BAD_VALUE;
}
if (getMetaData(hnd, GET_PP_PARAM_INTERLACED, flag) != 0) {
*flag = 0;
}
} break;
case GRALLOC_MODULE_PERFORM_SET_SINGLE_BUFFER_MODE: {
private_handle_t *hnd = va_arg(args, private_handle_t *);
uint32_t *enable = va_arg(args, uint32_t *);
if (private_handle_t::validate(hnd) != 0) {
return GRALLOC1_ERROR_BAD_HANDLE;
}
if (setMetaData(hnd, SET_SINGLE_BUFFER_MODE, enable) != 0) {
return GRALLOC1_ERROR_UNSUPPORTED;
}
} break;
default:
break;
}
return GRALLOC1_ERROR_NONE;
}
gralloc1_error_t GrallocImpl::Gralloc1Perform(gralloc1_device_t *device, int operation, ...) {
if (!device) {
return GRALLOC1_ERROR_BAD_VALUE;
}
va_list args;
va_start(args, operation);
gralloc1_error_t err = Perform(operation, args);
va_end(args);
return err;
}
} // namespace gralloc

View File

@@ -1,157 +0,0 @@
/*
* Copyright (c) 2016-2018, 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:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __GR_DEVICE_IMPL_H__
#define __GR_DEVICE_IMPL_H__
#include <hardware/gralloc1.h>
#include <hardware/hardware.h>
#include "gr_buf_mgr.h"
struct private_module_t {
hw_module_t base;
};
#define GRALLOC_IMPL(exp) reinterpret_cast<GrallocImpl const *>(exp)
namespace gralloc {
class GrallocImpl : public gralloc1_device_t {
public:
static int CloseDevice(hw_device_t *device);
static void GetCapabilities(struct gralloc1_device *device, uint32_t *out_count,
int32_t * /*gralloc1_capability_t*/ out_capabilities);
static gralloc1_function_pointer_t GetFunction(
struct gralloc1_device *device, int32_t /*gralloc1_function_descriptor_t*/ descriptor);
static GrallocImpl *GetInstance(const struct hw_module_t *module) {
static GrallocImpl *instance = new GrallocImpl(module);
if (instance->IsInitialized()) {
return instance;
} else {
return nullptr;
}
}
private:
static inline gralloc1_error_t Dump(gralloc1_device_t *device, uint32_t *out_size,
char *out_buffer);
static inline gralloc1_error_t CheckDeviceAndHandle(gralloc1_device_t *device,
buffer_handle_t buffer);
static gralloc1_error_t CreateBufferDescriptor(gralloc1_device_t *device,
gralloc1_buffer_descriptor_t *out_descriptor);
static gralloc1_error_t DestroyBufferDescriptor(gralloc1_device_t *device,
gralloc1_buffer_descriptor_t descriptor);
static gralloc1_error_t SetConsumerUsage(gralloc1_device_t *device,
gralloc1_buffer_descriptor_t descriptor,
gralloc1_consumer_usage_t usage);
static gralloc1_error_t SetBufferDimensions(gralloc1_device_t *device,
gralloc1_buffer_descriptor_t descriptor,
uint32_t width, uint32_t height);
static gralloc1_error_t SetColorFormat(gralloc1_device_t *device,
gralloc1_buffer_descriptor_t descriptor, int32_t format);
static gralloc1_error_t SetLayerCount(gralloc1_device_t *device,
gralloc1_buffer_descriptor_t descriptor,
uint32_t layer_count);
static gralloc1_error_t SetProducerUsage(gralloc1_device_t *device,
gralloc1_buffer_descriptor_t descriptor,
gralloc1_producer_usage_t usage);
static gralloc1_error_t GetBackingStore(gralloc1_device_t *device, buffer_handle_t buffer,
gralloc1_backing_store_t *out_store);
static gralloc1_error_t GetConsumerUsage(gralloc1_device_t *device, buffer_handle_t buffer,
gralloc1_consumer_usage_t *out_usage);
static gralloc1_error_t GetBufferDimensions(gralloc1_device_t *device, buffer_handle_t buffer,
uint32_t *out_width, uint32_t *out_height);
static gralloc1_error_t GetColorFormat(gralloc1_device_t *device, buffer_handle_t descriptor,
int32_t *outFormat);
static gralloc1_error_t GetLayerCount(gralloc1_device_t *device, buffer_handle_t buffer,
uint32_t *out_layer_count);
static gralloc1_error_t GetProducerUsage(gralloc1_device_t *device, buffer_handle_t buffer,
gralloc1_producer_usage_t *out_usage);
static gralloc1_error_t GetBufferStride(gralloc1_device_t *device, buffer_handle_t buffer,
uint32_t *out_stride);
static gralloc1_error_t AllocateBuffers(gralloc1_device_t *device, uint32_t num_dptors,
const gralloc1_buffer_descriptor_t *descriptors,
buffer_handle_t *out_buffers);
static gralloc1_error_t RetainBuffer(gralloc1_device_t *device, buffer_handle_t buffer);
static gralloc1_error_t ReleaseBuffer(gralloc1_device_t *device, buffer_handle_t buffer);
static gralloc1_error_t GetNumFlexPlanes(gralloc1_device_t *device, buffer_handle_t buffer,
uint32_t *out_num_planes);
static gralloc1_error_t LockBuffer(gralloc1_device_t *device, buffer_handle_t buffer,
gralloc1_producer_usage_t prod_usage,
gralloc1_consumer_usage_t cons_usage,
const gralloc1_rect_t *region, void **out_data,
int32_t acquire_fence);
static gralloc1_error_t LockFlex(gralloc1_device_t *device, buffer_handle_t buffer,
gralloc1_producer_usage_t prod_usage,
gralloc1_consumer_usage_t cons_usage,
const gralloc1_rect_t *region,
struct android_flex_layout *out_flex_layout,
int32_t acquire_fence);
static gralloc1_error_t UnlockBuffer(gralloc1_device_t *device, buffer_handle_t buffer,
int32_t *release_fence);
static gralloc1_error_t Gralloc1Perform(gralloc1_device_t *device, int operation, ...);
gralloc1_error_t CreateBufferDescriptorLocked(gralloc1_buffer_descriptor_t *descriptor_id);
gralloc1_error_t DestroyBufferDescriptorLocked(gralloc1_buffer_descriptor_t descriptor_id);
gralloc1_error_t AllocateBuffer(const gralloc1_buffer_descriptor_t *descriptor_ids,
buffer_handle_t *out_buffers);
gralloc1_error_t GetFlexLayout(const private_handle_t *hnd, struct android_flex_layout *layout);
template <typename... Args>
gralloc1_error_t CallBufferDescriptorFunction(gralloc1_buffer_descriptor_t descriptor_id,
void (BufferDescriptor::*member)(Args...),
Args... args) {
std::lock_guard<std::mutex> lock(descriptor_lock_);
const auto map_descriptor = descriptors_map_.find(descriptor_id);
if (map_descriptor == descriptors_map_.end()) {
return GRALLOC1_ERROR_BAD_DESCRIPTOR;
}
const auto descriptor = map_descriptor->second;
(descriptor.get()->*member)(std::forward<Args>(args)...);
return GRALLOC1_ERROR_NONE;
}
explicit GrallocImpl(const hw_module_t *module);
~GrallocImpl();
bool Init();
bool IsInitialized() const { return initialized_; }
BufferManager *buf_mgr_ = NULL;
bool initialized_ = false;
std::mutex descriptor_lock_;
std::unordered_map<gralloc1_buffer_descriptor_t, std::shared_ptr<gralloc::BufferDescriptor>>
descriptors_map_ = {};
static std::atomic<uint64_t> next_descriptor_id_;
};
} // namespace gralloc
#endif // __GR_DEVICE_IMPL_H__

View File

@@ -1,213 +0,0 @@
/*
* Copyright (c) 2011-2018, 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:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define DEBUG 0
#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
#include <log/log.h>
#include <cutils/trace.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <utils/Trace.h>
#include <string>
#include "gr_ion_alloc.h"
#include "gr_utils.h"
#include "gralloc_priv.h"
namespace gralloc {
bool IonAlloc::Init() {
if (ion_dev_fd_ == FD_INIT) {
ion_dev_fd_ = open(kIonDevice, O_RDONLY);
}
if (ion_dev_fd_ < 0) {
ALOGE("%s: Failed to open ion device - %s", __FUNCTION__, strerror(errno));
ion_dev_fd_ = FD_INIT;
return false;
}
return true;
}
void IonAlloc::CloseIonDevice() {
if (ion_dev_fd_ > FD_INIT) {
close(ion_dev_fd_);
}
ion_dev_fd_ = FD_INIT;
}
int IonAlloc::AllocBuffer(AllocData *data) {
ATRACE_CALL();
int err = 0;
struct ion_handle_data handle_data;
struct ion_fd_data fd_data;
struct ion_allocation_data ion_alloc_data;
ion_alloc_data.len = data->size;
ion_alloc_data.align = data->align;
ion_alloc_data.heap_id_mask = data->heap_id;
ion_alloc_data.flags = data->flags;
ion_alloc_data.flags |= data->uncached ? 0 : ION_FLAG_CACHED;
std::string tag_name{};
if (ATRACE_ENABLED()) {
tag_name = "ION_IOC_ALLOC size: " + std::to_string(data->size);
}
ATRACE_BEGIN(tag_name.c_str());
if (ioctl(ion_dev_fd_, INT(ION_IOC_ALLOC), &ion_alloc_data)) {
err = -errno;
ALOGE("ION_IOC_ALLOC failed with error - %s", strerror(errno));
return err;
}
ATRACE_END();
fd_data.handle = ion_alloc_data.handle;
handle_data.handle = ion_alloc_data.handle;
ATRACE_BEGIN("ION_IOC_MAP");
if (ioctl(ion_dev_fd_, INT(ION_IOC_MAP), &fd_data)) {
err = -errno;
ALOGE("%s: ION_IOC_MAP failed with error - %s", __FUNCTION__, strerror(errno));
ioctl(ion_dev_fd_, INT(ION_IOC_FREE), &handle_data);
return err;
}
ATRACE_END();
data->fd = fd_data.fd;
data->ion_handle = handle_data.handle;
ALOGD_IF(DEBUG, "ion: Allocated buffer size:%zu fd:%d handle:0x%x", ion_alloc_data.len, data->fd,
data->ion_handle);
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, "ion: Freeing buffer base:%p size:%u fd:%d handle:0x%x", base, size, fd,
ion_handle);
if (base) {
err = UnmapBuffer(base, size, offset);
}
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;
}
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;
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);
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) {
ATRACE_CALL();
ATRACE_INT("operation id", op);
struct ion_flush_data flush_data;
int err = 0;
flush_data.handle = handle;
flush_data.vaddr = base;
// offset and length are unsigned int
flush_data.offset = offset;
flush_data.length = size;
struct ion_custom_data d;
switch (op) {
case CACHE_CLEAN:
d.cmd = ION_IOC_CLEAN_CACHES;
break;
case CACHE_INVALIDATE:
d.cmd = ION_IOC_INV_CACHES;
break;
case CACHE_CLEAN_AND_INVALIDATE:
default:
d.cmd = ION_IOC_CLEAN_INV_CACHES;
}
d.arg = (unsigned long)(&flush_data); // NOLINT
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));
return err;
}
return 0;
}
} // namespace gralloc

View File

@@ -1,84 +0,0 @@
/*
* Copyright (c) 2011-2018, 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:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __GR_ION_ALLOC_H__
#define __GR_ION_ALLOC_H__
#include <linux/msm_ion.h>
#define FD_INIT -1
namespace gralloc {
enum {
CACHE_CLEAN = 0x1,
CACHE_INVALIDATE,
CACHE_CLEAN_AND_INVALIDATE,
};
struct AllocData {
void *base = NULL;
int fd = -1;
int ion_handle = -1;
unsigned int offset = 0;
unsigned int size = 0;
unsigned int align = 1;
uintptr_t handle = 0;
bool uncached = false;
unsigned int flags = 0x0;
unsigned int heap_id = 0x0;
unsigned int alloc_type = 0x0;
};
class IonAlloc {
public:
IonAlloc() { ion_dev_fd_ = FD_INIT; }
~IonAlloc() { CloseIonDevice(); }
bool Init();
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 handle, int op);
private:
const char *kIonDevice = "/dev/ion";
int OpenIonDevice();
void CloseIonDevice();
int ion_dev_fd_;
};
} // namespace gralloc
#endif // __GR_ION_ALLOC_H__

View File

@@ -1,933 +0,0 @@
/*
* Copyright (c) 2011-2018, 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:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <media/msm_media_info.h>
#include <algorithm>
#include "gr_adreno_info.h"
#include "gr_utils.h"
#include "qdMetaData.h"
#define ASTC_BLOCK_SIZE 16
#ifndef COLOR_FMT_P010_UBWC
#define COLOR_FMT_P010_UBWC 9
#endif
namespace gralloc {
bool IsYuvFormat(const private_handle_t *hnd) {
switch (hnd->format) {
case HAL_PIXEL_FORMAT_YCbCr_420_SP:
case HAL_PIXEL_FORMAT_YCbCr_422_SP:
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: // Same as YCbCr_420_SP_VENUS
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
case HAL_PIXEL_FORMAT_YCrCb_422_SP:
case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
case HAL_PIXEL_FORMAT_NV21_ZSL:
case HAL_PIXEL_FORMAT_RAW16:
case HAL_PIXEL_FORMAT_Y16:
case HAL_PIXEL_FORMAT_RAW12:
case HAL_PIXEL_FORMAT_RAW10:
case HAL_PIXEL_FORMAT_YV12:
case HAL_PIXEL_FORMAT_Y8:
case HAL_PIXEL_FORMAT_YCbCr_420_P010:
case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
return true;
default:
return false;
}
}
bool IsUncompressedRGBFormat(int format) {
switch (format) {
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
case HAL_PIXEL_FORMAT_RGB_888:
case HAL_PIXEL_FORMAT_RGB_565:
case HAL_PIXEL_FORMAT_BGR_565:
case HAL_PIXEL_FORMAT_BGRA_8888:
case HAL_PIXEL_FORMAT_RGBA_5551:
case HAL_PIXEL_FORMAT_RGBA_4444:
case HAL_PIXEL_FORMAT_R_8:
case HAL_PIXEL_FORMAT_RG_88:
case HAL_PIXEL_FORMAT_BGRX_8888:
case HAL_PIXEL_FORMAT_RGBA_1010102:
case HAL_PIXEL_FORMAT_ARGB_2101010:
case HAL_PIXEL_FORMAT_RGBX_1010102:
case HAL_PIXEL_FORMAT_XRGB_2101010:
case HAL_PIXEL_FORMAT_BGRA_1010102:
case HAL_PIXEL_FORMAT_ABGR_2101010:
case HAL_PIXEL_FORMAT_BGRX_1010102:
case HAL_PIXEL_FORMAT_XBGR_2101010:
case HAL_PIXEL_FORMAT_RGBA_FP16:
case HAL_PIXEL_FORMAT_BGR_888:
return true;
default:
break;
}
return false;
}
bool IsCompressedRGBFormat(int format) {
switch (format) {
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
return true;
default:
break;
}
return false;
}
uint32_t GetBppForUncompressedRGB(int format) {
uint32_t bpp = 0;
switch (format) {
case HAL_PIXEL_FORMAT_RGBA_FP16:
bpp = 8;
break;
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
case HAL_PIXEL_FORMAT_BGRA_8888:
case HAL_PIXEL_FORMAT_BGRX_8888:
case HAL_PIXEL_FORMAT_RGBA_1010102:
case HAL_PIXEL_FORMAT_ARGB_2101010:
case HAL_PIXEL_FORMAT_RGBX_1010102:
case HAL_PIXEL_FORMAT_XRGB_2101010:
case HAL_PIXEL_FORMAT_BGRA_1010102:
case HAL_PIXEL_FORMAT_ABGR_2101010:
case HAL_PIXEL_FORMAT_BGRX_1010102:
case HAL_PIXEL_FORMAT_XBGR_2101010:
bpp = 4;
break;
case HAL_PIXEL_FORMAT_RGB_888:
case HAL_PIXEL_FORMAT_BGR_888:
bpp = 3;
break;
case HAL_PIXEL_FORMAT_RGB_565:
case HAL_PIXEL_FORMAT_BGR_565:
case HAL_PIXEL_FORMAT_RGBA_5551:
case HAL_PIXEL_FORMAT_RGBA_4444:
bpp = 2;
break;
default:
ALOGE("Error : %s New format request = 0x%x", __FUNCTION__, format);
break;
}
return bpp;
}
bool CpuCanAccess(uint64_t usage) {
return CpuCanRead(usage) || CpuCanWrite(usage);
}
bool CpuCanRead(uint64_t usage) {
if (usage & BufferUsage::CPU_READ_MASK) {
return true;
}
return false;
}
bool CpuCanWrite(uint64_t usage) {
if (usage & BufferUsage::CPU_WRITE_MASK) {
// Application intends to use CPU for rendering
return true;
}
return false;
}
unsigned int GetSize(const BufferInfo &info, unsigned int alignedw, unsigned int alignedh) {
unsigned int size = 0;
int format = info.format;
int width = info.width;
int height = info.height;
uint64_t usage = info.usage;
if (IsUBwcEnabled(format, usage)) {
return GetUBwcSize(width, height, format, alignedw, alignedh);
}
if (IsUncompressedRGBFormat(format)) {
uint32_t bpp = GetBppForUncompressedRGB(format);
size = alignedw * alignedh * bpp;
return size;
}
if (IsCompressedRGBFormat(format)) {
size = alignedw * alignedh * ASTC_BLOCK_SIZE;
return size;
}
// Below switch should be for only YUV/custom formats
switch (format) {
case HAL_PIXEL_FORMAT_RAW16:
case HAL_PIXEL_FORMAT_Y16:
size = alignedw * alignedh * 2;
break;
case HAL_PIXEL_FORMAT_RAW10:
case HAL_PIXEL_FORMAT_RAW12:
size = ALIGN(alignedw * alignedh, SIZE_4K);
break;
case HAL_PIXEL_FORMAT_RAW8:
case HAL_PIXEL_FORMAT_Y8:
size = alignedw * alignedh * 1;
break;
// adreno formats
case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: // NV21
size = ALIGN(alignedw * alignedh, SIZE_4K);
size += (unsigned int)ALIGN(2 * ALIGN(width / 2, 32) * ALIGN(height / 2, 32), SIZE_4K);
break;
case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: // NV12
// The chroma plane is subsampled,
// but the pitch in bytes is unchanged
// The GPU needs 4K alignment, but the video decoder needs 8K
size = ALIGN(alignedw * alignedh, SIZE_8K);
size += ALIGN(alignedw * (unsigned int)ALIGN(height / 2, 32), SIZE_8K);
break;
case HAL_PIXEL_FORMAT_YV12:
if ((format == HAL_PIXEL_FORMAT_YV12) && ((width & 1) || (height & 1))) {
ALOGE("w or h is odd for the YV12 format");
return 0;
}
size = alignedw * alignedh + (ALIGN(alignedw / 2, 16) * (alignedh / 2)) * 2;
size = ALIGN(size, (unsigned int)SIZE_4K);
break;
case HAL_PIXEL_FORMAT_YCbCr_420_SP:
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2 + 1, SIZE_4K);
break;
case HAL_PIXEL_FORMAT_YCbCr_420_P010:
size = ALIGN((alignedw * alignedh * 2) + (alignedw * alignedh) + 1, SIZE_4K);
break;
case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
size = VENUS_BUFFER_SIZE(COLOR_FMT_P010, width, height);
break;
case HAL_PIXEL_FORMAT_YCbCr_422_SP:
case HAL_PIXEL_FORMAT_YCrCb_422_SP:
case HAL_PIXEL_FORMAT_YCbCr_422_I:
case HAL_PIXEL_FORMAT_YCrCb_422_I:
case HAL_PIXEL_FORMAT_CbYCrY_422_I:
if (width & 1) {
ALOGE("width is odd for the YUV422_SP format");
return 0;
}
size = ALIGN(alignedw * alignedh * 2, SIZE_4K);
break;
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
break;
case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
size = VENUS_BUFFER_SIZE(COLOR_FMT_NV21, width, height);
break;
case HAL_PIXEL_FORMAT_BLOB:
case HAL_PIXEL_FORMAT_RAW_OPAQUE:
if (height != 1) {
ALOGE("%s: Buffers with HAL_PIXEL_FORMAT_BLOB must have height 1 ", __FUNCTION__);
return 0;
}
size = (unsigned int)width;
break;
case HAL_PIXEL_FORMAT_NV21_ZSL:
size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2, SIZE_4K);
break;
default:
ALOGE("%s: Unrecognized pixel format: 0x%x", __FUNCTION__, format);
return 0;
}
return size;
}
void GetBufferSizeAndDimensions(const BufferInfo &info, unsigned int *size, unsigned int *alignedw,
unsigned int *alignedh) {
GetAlignedWidthAndHeight(info, alignedw, alignedh);
*size = GetSize(info, *alignedw, *alignedh);
}
void GetYuvUbwcSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, int color_format,
struct android_ycbcr *ycbcr) {
// UBWC buffer has these 4 planes in the following sequence:
// Y_Meta_Plane, Y_Plane, UV_Meta_Plane, UV_Plane
unsigned int y_meta_stride, y_meta_height, y_meta_size;
unsigned int y_stride, y_height, y_size;
unsigned int c_meta_stride, c_meta_height, c_meta_size;
unsigned int alignment = 4096;
y_meta_stride = VENUS_Y_META_STRIDE(color_format, INT(width));
y_meta_height = VENUS_Y_META_SCANLINES(color_format, INT(height));
y_meta_size = ALIGN((y_meta_stride * y_meta_height), alignment);
y_stride = VENUS_Y_STRIDE(color_format, INT(width));
y_height = VENUS_Y_SCANLINES(color_format, INT(height));
y_size = ALIGN((y_stride * y_height), alignment);
c_meta_stride = VENUS_UV_META_STRIDE(color_format, INT(width));
c_meta_height = VENUS_UV_META_SCANLINES(color_format, INT(height));
c_meta_size = ALIGN((c_meta_stride * c_meta_height), alignment);
ycbcr->y = reinterpret_cast<void *>(base + y_meta_size);
ycbcr->cb = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size);
ycbcr->cr = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size + 1);
ycbcr->ystride = y_stride;
ycbcr->cstride = VENUS_UV_STRIDE(color_format, INT(width));
}
void GetYuvUbwcInterlacedSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height,
int color_format, struct android_ycbcr ycbcr[2]) {
unsigned int uv_stride, uv_height, uv_size;
unsigned int alignment = 4096;
uint64_t field_base;
// UBWC interlaced has top-bottom field layout with each field as
// 4-plane NV12_UBWC with width = image_width & height = image_height / 2.
// Client passed ycbcr argument is ptr to struct android_ycbcr[2].
// Plane info to be filled for each field separately.
height = (height + 1) >> 1;
uv_stride = VENUS_UV_STRIDE(color_format, INT(width));
uv_height = VENUS_UV_SCANLINES(color_format, INT(height));
uv_size = ALIGN((uv_stride * uv_height), alignment);
field_base = base;
GetYuvUbwcSPPlaneInfo(field_base, width, height, COLOR_FMT_NV12_UBWC, &ycbcr[0]);
memset(ycbcr[1].reserved, 0, sizeof(ycbcr[1].reserved));
field_base = reinterpret_cast<uint64_t>(ycbcr[0].cb) + uv_size;
GetYuvUbwcSPPlaneInfo(field_base, width, height, COLOR_FMT_NV12_UBWC, &ycbcr[1]);
}
void GetYuvSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, uint32_t bpp,
struct android_ycbcr *ycbcr) {
unsigned int ystride, cstride;
ystride = cstride = UINT(width) * bpp;
ycbcr->y = reinterpret_cast<void *>(base);
ycbcr->cb = reinterpret_cast<void *>(base + ystride * UINT(height));
ycbcr->cr = reinterpret_cast<void *>(base + ystride * UINT(height) + 1);
ycbcr->ystride = ystride;
ycbcr->cstride = cstride;
ycbcr->chroma_step = 2 * bpp;
}
int GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr ycbcr[2]) {
int err = 0;
uint32_t width = UINT(hnd->width);
uint32_t height = UINT(hnd->height);
int format = hnd->format;
uint64_t usage = hnd->usage;
unsigned int ystride, cstride;
bool interlaced = false;
memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
// Check if UBWC buffer has been rendered in linear format.
int linear_format = 0;
if (getMetaData(const_cast<private_handle_t *>(hnd), GET_LINEAR_FORMAT, &linear_format) == 0) {
format = INT(linear_format);
}
// Check metadata if the geometry has been updated.
BufferDim_t buffer_dim;
if (getMetaData(const_cast<private_handle_t *>(hnd), GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
BufferInfo info(buffer_dim.sliceWidth, buffer_dim.sliceHeight, format, usage);
GetAlignedWidthAndHeight(info, &width, &height);
}
// Check metadata for interlaced content.
int interlace_flag = 0;
if (getMetaData(const_cast<private_handle_t *>(hnd), GET_PP_PARAM_INTERLACED, &interlace_flag) ==
0) {
interlaced = interlace_flag;
}
// Get the chroma offsets from the handle width/height. We take advantage
// of the fact the width _is_ the stride
switch (format) {
// Semiplanar
case HAL_PIXEL_FORMAT_YCbCr_420_SP:
case HAL_PIXEL_FORMAT_YCbCr_422_SP:
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
// Same as YCbCr_420_SP_VENUS
GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
break;
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
if (!interlaced) {
GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_UBWC, ycbcr);
} else {
GetYuvUbwcInterlacedSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_UBWC, ycbcr);
}
ycbcr->chroma_step = 2;
break;
case HAL_PIXEL_FORMAT_YCbCr_420_P010:
GetYuvSPPlaneInfo(hnd->base, width, height, 2, ycbcr);
break;
case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_BPP10_UBWC, ycbcr);
ycbcr->chroma_step = 3;
break;
case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_P010_UBWC, ycbcr);
ycbcr->chroma_step = 4;
break;
case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
ystride = VENUS_Y_STRIDE(COLOR_FMT_P010, width);
cstride = VENUS_UV_STRIDE(COLOR_FMT_P010, width);
ycbcr->y = reinterpret_cast<void *>(hnd->base);
ycbcr->cb =
reinterpret_cast<void *>(hnd->base + ystride * VENUS_Y_SCANLINES(COLOR_FMT_P010, height));
ycbcr->cr = reinterpret_cast<void *>(hnd->base +
ystride * VENUS_Y_SCANLINES(COLOR_FMT_P010, height) + 1);
ycbcr->ystride = ystride;
ycbcr->cstride = cstride;
ycbcr->chroma_step = 4;
break;
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
case HAL_PIXEL_FORMAT_YCrCb_422_SP:
case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
case HAL_PIXEL_FORMAT_NV21_ZSL:
case HAL_PIXEL_FORMAT_RAW16:
case HAL_PIXEL_FORMAT_Y16:
case HAL_PIXEL_FORMAT_RAW10:
case HAL_PIXEL_FORMAT_RAW8:
case HAL_PIXEL_FORMAT_Y8:
GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
std::swap(ycbcr->cb, ycbcr->cr);
break;
// Planar
case HAL_PIXEL_FORMAT_YV12:
ystride = width;
cstride = ALIGN(width / 2, 16);
ycbcr->y = reinterpret_cast<void *>(hnd->base);
ycbcr->cr = reinterpret_cast<void *>(hnd->base + ystride * height);
ycbcr->cb = reinterpret_cast<void *>(hnd->base + ystride * height + cstride * height / 2);
ycbcr->ystride = ystride;
ycbcr->cstride = cstride;
ycbcr->chroma_step = 1;
break;
case HAL_PIXEL_FORMAT_CbYCrY_422_I:
ystride = width * 2;
cstride = 0;
ycbcr->y = reinterpret_cast<void *>(hnd->base);
ycbcr->cr = NULL;
ycbcr->cb = NULL;
ycbcr->ystride = ystride;
ycbcr->cstride = 0;
ycbcr->chroma_step = 0;
break;
// Unsupported formats
case HAL_PIXEL_FORMAT_YCbCr_422_I:
case HAL_PIXEL_FORMAT_YCrCb_422_I:
case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
default:
ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, format);
err = -EINVAL;
}
return err;
}
// Explicitly defined UBWC formats
bool IsUBwcFormat(int format) {
switch (format) {
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
return true;
default:
return false;
}
}
bool IsUBwcSupported(int format) {
// Existing HAL formats with UBWC support
switch (format) {
case HAL_PIXEL_FORMAT_BGR_565:
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
case HAL_PIXEL_FORMAT_RGBA_1010102:
case HAL_PIXEL_FORMAT_RGBX_1010102:
return true;
default:
break;
}
return false;
}
bool IsUBwcEnabled(int format, uint64_t usage) {
// Allow UBWC, if client is using an explicitly defined UBWC pixel format.
if (IsUBwcFormat(format)) {
return true;
}
// Allow UBWC, if an OpenGL client sets UBWC usage flag and GPU plus MDP
// support the format. OR if a non-OpenGL client like Rotator, sets UBWC
// usage flag and MDP supports the format.
if ((usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) && IsUBwcSupported(format)) {
bool enable = true;
// Query GPU for UBWC only if buffer is intended to be used by GPU.
if ((usage & BufferUsage::GPU_TEXTURE) || (usage & BufferUsage::GPU_RENDER_TARGET)) {
if (AdrenoMemInfo::GetInstance()) {
enable = AdrenoMemInfo::GetInstance()->IsUBWCSupportedByGPU(format);
}
}
// Allow UBWC, only if CPU usage flags are not set
if (enable && !(CpuCanAccess(usage))) {
return true;
}
}
return false;
}
void GetYuvUBwcWidthAndHeight(int width, int height, int format, unsigned int *aligned_w,
unsigned int *aligned_h) {
switch (format) {
case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
*aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width);
*aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height);
break;
case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
// The macro returns the stride which is 4/3 times the width, hence * 3/4
*aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, width) * 3) / 4;
*aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, height);
break;
case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
// The macro returns the stride which is 2 times the width, hence / 2
*aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_P010_UBWC, width) / 2);
*aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_P010_UBWC, height);
break;
default:
ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
*aligned_w = 0;
*aligned_h = 0;
break;
}
}
void GetRgbUBwcBlockSize(uint32_t bpp, int *block_width, int *block_height) {
*block_width = 0;
*block_height = 0;
switch (bpp) {
case 2:
case 4:
*block_width = 16;
*block_height = 4;
break;
case 8:
*block_width = 8;
*block_height = 4;
break;
case 16:
*block_width = 4;
*block_height = 4;
break;
default:
ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
break;
}
}
unsigned int GetRgbUBwcMetaBufferSize(int width, int height, uint32_t bpp) {
unsigned int size = 0;
int meta_width, meta_height;
int block_width, block_height;
GetRgbUBwcBlockSize(bpp, &block_width, &block_height);
if (!block_width || !block_height) {
ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
return size;
}
// Align meta buffer height to 16 blocks
meta_height = ALIGN(((height + block_height - 1) / block_height), 16);
// Align meta buffer width to 64 blocks
meta_width = ALIGN(((width + block_width - 1) / block_width), 64);
// Align meta buffer size to 4K
size = (unsigned int)ALIGN((meta_width * meta_height), 4096);
return size;
}
unsigned int GetUBwcSize(int width, int height, int format, unsigned int alignedw,
unsigned int alignedh) {
unsigned int size = 0;
uint32_t bpp = 0;
switch (format) {
case HAL_PIXEL_FORMAT_BGR_565:
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
case HAL_PIXEL_FORMAT_RGBA_1010102:
case HAL_PIXEL_FORMAT_RGBX_1010102:
bpp = GetBppForUncompressedRGB(format);
size = alignedw * alignedh * bpp;
size += GetRgbUBwcMetaBufferSize(width, height, bpp);
break;
case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height);
break;
case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_BPP10_UBWC, width, height);
break;
case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
size = VENUS_BUFFER_SIZE(COLOR_FMT_P010_UBWC, width, height);
break;
default:
ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
break;
}
return size;
}
int GetRgbDataAddress(private_handle_t *hnd, void **rgb_data) {
int err = 0;
// This api is for RGB* formats
if (!IsUncompressedRGBFormat(hnd->format)) {
return -EINVAL;
}
// linear buffer, nothing to do further
if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) {
*rgb_data = reinterpret_cast<void *>(hnd->base);
return err;
}
unsigned int meta_size = 0;
uint32_t bpp = GetBppForUncompressedRGB(hnd->format);
switch (hnd->format) {
case HAL_PIXEL_FORMAT_BGR_565:
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
case HAL_PIXEL_FORMAT_RGBA_1010102:
case HAL_PIXEL_FORMAT_RGBX_1010102:
meta_size = GetRgbUBwcMetaBufferSize(hnd->width, hnd->height, bpp);
break;
default:
ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, hnd->format);
err = -EINVAL;
break;
}
*rgb_data = reinterpret_cast<void *>(hnd->base + meta_size);
return err;
}
void GetCustomDimensions(private_handle_t *hnd, int *stride, int *height) {
BufferDim_t buffer_dim;
int interlaced = 0;
*stride = hnd->width;
*height = hnd->height;
if (getMetaData(hnd, GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
*stride = buffer_dim.sliceWidth;
*height = buffer_dim.sliceHeight;
} else if (getMetaData(hnd, GET_PP_PARAM_INTERLACED, &interlaced) == 0) {
if (interlaced && IsUBwcFormat(hnd->format)) {
unsigned int alignedw = 0, alignedh = 0;
// Get re-aligned height for single ubwc interlaced field and
// multiply by 2 to get frame height.
BufferInfo info(hnd->width, ((hnd->height + 1) >> 1), hnd->format);
GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
*stride = static_cast<int>(alignedw);
*height = static_cast<int>(alignedh * 2);
}
}
}
void GetColorSpaceFromMetadata(private_handle_t *hnd, int *color_space) {
ColorMetaData color_metadata;
if (getMetaData(hnd, GET_COLOR_METADATA, &color_metadata) == 0) {
switch (color_metadata.colorPrimaries) {
case ColorPrimaries_BT709_5:
*color_space = HAL_CSC_ITU_R_709;
break;
case ColorPrimaries_BT601_6_525:
case ColorPrimaries_BT601_6_625:
*color_space = ((color_metadata.range) ? HAL_CSC_ITU_R_601_FR : HAL_CSC_ITU_R_601);
break;
case ColorPrimaries_BT2020:
*color_space = (color_metadata.range) ? HAL_CSC_ITU_R_2020_FR : HAL_CSC_ITU_R_2020;
break;
default:
ALOGE("Unknown Color Space = %d", color_metadata.colorPrimaries);
break;
}
} else if (getMetaData(hnd, GET_COLOR_SPACE, color_space) != 0) {
*color_space = 0;
}
}
void GetAlignedWidthAndHeight(const BufferInfo &info, unsigned int *alignedw,
unsigned int *alignedh) {
int width = info.width;
int height = info.height;
int format = info.format;
uint64_t usage = info.usage;
// Currently surface padding is only computed for RGB* surfaces.
bool ubwc_enabled = IsUBwcEnabled(format, usage);
int tile = ubwc_enabled;
if (IsUncompressedRGBFormat(format)) {
if (AdrenoMemInfo::GetInstance()) {
AdrenoMemInfo::GetInstance()->AlignUnCompressedRGB(width, height, format, tile, alignedw,
alignedh);
}
return;
}
if (ubwc_enabled) {
GetYuvUBwcWidthAndHeight(width, height, format, alignedw, alignedh);
return;
}
if (IsCompressedRGBFormat(format)) {
if (AdrenoMemInfo::GetInstance()) {
AdrenoMemInfo::GetInstance()->AlignCompressedRGB(width, height, format, alignedw, alignedh);
}
return;
}
int aligned_w = width;
int aligned_h = height;
unsigned int alignment = 32;
// Below should be only YUV family
switch (format) {
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
case HAL_PIXEL_FORMAT_YCbCr_420_SP:
if (AdrenoMemInfo::GetInstance() == nullptr) {
return;
}
alignment = AdrenoMemInfo::GetInstance()->GetGpuPixelAlignment();
aligned_w = ALIGN(width, alignment);
break;
case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
aligned_w = ALIGN(width, alignment);
break;
case HAL_PIXEL_FORMAT_RAW16:
case HAL_PIXEL_FORMAT_Y16:
case HAL_PIXEL_FORMAT_Y8:
aligned_w = ALIGN(width, 16);
break;
case HAL_PIXEL_FORMAT_RAW12:
aligned_w = ALIGN(width * 12 / 8, 16);
break;
case HAL_PIXEL_FORMAT_RAW10:
aligned_w = ALIGN(width * 10 / 8, 16);
break;
case HAL_PIXEL_FORMAT_RAW8:
aligned_w = ALIGN(width, 16);
break;
case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
aligned_w = ALIGN(width, 128);
break;
case HAL_PIXEL_FORMAT_YV12:
case HAL_PIXEL_FORMAT_YCbCr_422_SP:
case HAL_PIXEL_FORMAT_YCrCb_422_SP:
case HAL_PIXEL_FORMAT_YCbCr_422_I:
case HAL_PIXEL_FORMAT_YCrCb_422_I:
case HAL_PIXEL_FORMAT_YCbCr_420_P010:
aligned_w = ALIGN(width, 16);
break;
case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_P010, width) / 2);
aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_P010, height));
break;
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV12, width));
aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV12, height));
break;
case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV21, width));
aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV21, height));
break;
case HAL_PIXEL_FORMAT_BLOB:
case HAL_PIXEL_FORMAT_RAW_OPAQUE:
break;
case HAL_PIXEL_FORMAT_NV21_ZSL:
aligned_w = ALIGN(width, 64);
aligned_h = ALIGN(height, 64);
break;
default:
break;
}
*alignedw = (unsigned int)aligned_w;
*alignedh = (unsigned int)aligned_h;
}
int GetBufferLayout(private_handle_t *hnd, uint32_t stride[4], uint32_t offset[4],
uint32_t *num_planes) {
if (!hnd || !stride || !offset || !num_planes) {
return -EINVAL;
}
struct android_ycbcr yuvPlaneInfo[2] = {};
*num_planes = 1;
stride[0] = 0;
switch (hnd->format) {
case HAL_PIXEL_FORMAT_RGB_565:
case HAL_PIXEL_FORMAT_BGR_565:
case HAL_PIXEL_FORMAT_RGBA_5551:
case HAL_PIXEL_FORMAT_RGBA_4444:
stride[0] = static_cast<uint32_t>(hnd->width * 2);
break;
case HAL_PIXEL_FORMAT_RGB_888:
stride[0] = static_cast<uint32_t>(hnd->width * 3);
break;
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_BGRA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
case HAL_PIXEL_FORMAT_BGRX_8888:
case HAL_PIXEL_FORMAT_RGBA_1010102:
case HAL_PIXEL_FORMAT_ARGB_2101010:
case HAL_PIXEL_FORMAT_RGBX_1010102:
case HAL_PIXEL_FORMAT_XRGB_2101010:
case HAL_PIXEL_FORMAT_BGRA_1010102:
case HAL_PIXEL_FORMAT_ABGR_2101010:
case HAL_PIXEL_FORMAT_BGRX_1010102:
case HAL_PIXEL_FORMAT_XBGR_2101010:
stride[0] = static_cast<uint32_t>(hnd->width * 4);
break;
}
// Format is RGB
if (stride[0]) {
return 0;
}
(*num_planes)++;
int ret = GetYUVPlaneInfo(hnd, yuvPlaneInfo);
if (ret < 0) {
ALOGE("%s failed", __FUNCTION__);
return ret;
}
// We are only returning buffer layout for progressive or single field formats.
struct android_ycbcr yuvInfo = yuvPlaneInfo[0];
stride[0] = static_cast<uint32_t>(yuvInfo.ystride);
offset[0] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.y) - hnd->base);
stride[1] = static_cast<uint32_t>(yuvInfo.cstride);
switch (hnd->format) {
case HAL_PIXEL_FORMAT_YCbCr_420_SP:
case HAL_PIXEL_FORMAT_YCbCr_422_SP:
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
case HAL_PIXEL_FORMAT_YCbCr_420_P010:
case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base);
break;
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
case HAL_PIXEL_FORMAT_YCrCb_422_SP:
offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base);
break;
case HAL_PIXEL_FORMAT_YV12:
offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base);
stride[2] = static_cast<uint32_t>(yuvInfo.cstride);
offset[2] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base);
(*num_planes)++;
break;
default:
ALOGW("%s: Unsupported format", __FUNCTION__);
ret = -EINVAL;
}
if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
std::fill(offset, offset + 4, 0);
}
return 0;
}
} // namespace gralloc

View File

@@ -1,99 +0,0 @@
/*
* Copyright (c) 2011-2016,2018, 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:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __GR_UTILS_H__
#define __GR_UTILS_H__
#include <android/hardware/graphics/common/1.0/types.h>
#include "gralloc_priv.h"
#define SZ_2M 0x200000
#define SZ_1M 0x100000
#define SZ_4K 0x1000
#define SIZE_4K 4096
#define SIZE_8K 4096
#define INT(exp) static_cast<int>(exp)
#define UINT(exp) static_cast<unsigned int>(exp)
using android::hardware::graphics::common::V1_0::BufferUsage;
namespace gralloc {
struct BufferInfo {
BufferInfo(int w, int h, int f, uint64_t usage = 0)
: width(w), height(h), format(f), usage(usage) {}
int width;
int height;
int format;
uint64_t usage;
};
template <class Type1, class Type2>
inline Type1 ALIGN(Type1 x, Type2 align) {
return (Type1)((x + (Type1)align - 1) & ~((Type1)align - 1));
}
bool IsYuvFormat(const private_handle_t *hnd);
bool IsCompressedRGBFormat(int format);
bool IsUncompressedRGBFormat(int format);
uint32_t GetBppForUncompressedRGB(int format);
bool CpuCanAccess(uint64_t usage);
bool CpuCanRead(uint64_t usage);
bool CpuCanWrite(uint64_t usage);
unsigned int GetSize(const BufferInfo &d, unsigned int alignedw, unsigned int alignedh);
void GetBufferSizeAndDimensions(const BufferInfo &d, unsigned int *size, unsigned int *alignedw,
unsigned int *alignedh);
void GetCustomDimensions(private_handle_t *hnd, int *stride, int *height);
void GetColorSpaceFromMetadata(private_handle_t *hnd, int *color_space);
void GetAlignedWidthAndHeight(const BufferInfo &d, unsigned int *aligned_w,
unsigned int *aligned_h);
int GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr ycbcr[2]);
int GetRgbDataAddress(private_handle_t *hnd, void **rgb_data);
bool IsUBwcFormat(int format);
bool IsUBwcSupported(int format);
bool IsUBwcEnabled(int format, uint64_t usage);
void GetYuvUBwcWidthAndHeight(int width, int height, int format, unsigned int *aligned_w,
unsigned int *aligned_h);
void GetYuvSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, uint32_t bpp,
struct android_ycbcr *ycbcr);
void GetYuvUbwcSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, int color_format,
struct android_ycbcr *ycbcr);
void GetYuvUbwcInterlacedSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height,
int color_format, struct android_ycbcr ycbcr[2]);
void GetRgbUBwcBlockSize(uint32_t bpp, int *block_width, int *block_height);
unsigned int GetRgbUBwcMetaBufferSize(int width, int height, uint32_t bpp);
unsigned int GetUBwcSize(int width, int height, int format, unsigned int alignedw,
unsigned int alignedh);
int GetBufferLayout(private_handle_t *hnd, uint32_t stride[4], uint32_t offset[4],
uint32_t *num_planes);
} // namespace gralloc
#endif // __GR_UTILS_H__

View File

@@ -1,47 +0,0 @@
/*
* Copyright (c) 2018, 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:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <hidl/LegacySupport.h>
#include "QtiAllocator.h"
using android::hardware::configureRpcThreadpool;
using android::hardware::joinRpcThreadpool;
using vendor::qti::hardware::display::allocator::V1_0::implementation::QtiAllocator;
using android::hardware::graphics::allocator::V2_0::IAllocator;
int main(int, char **) {
android::sp<IAllocator> service = new QtiAllocator();
configureRpcThreadpool(4, true /*callerWillJoin*/);
if (service->registerAsService() != android::OK) {
ALOGE("Cannot register QTI Allocator service");
return -EINVAL;
}
ALOGI("Initialized qti-allocator");
joinRpcThreadpool();
return 0;
}

View File

@@ -1,6 +0,0 @@
service vendor.qti.hardware.display.allocator /vendor/bin/hw/vendor.qti.hardware.display.allocator@1.0-service
class hal animation
user system
group graphics drmrpc
capabilities SYS_NICE
onrestart restart surfaceflinger