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:
@@ -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)
|
||||
@@ -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
|
||||
@@ -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__
|
||||
@@ -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
|
||||
@@ -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__
|
||||
@@ -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
|
||||
@@ -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__
|
||||
@@ -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
|
||||
@@ -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__
|
||||
@@ -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__
|
||||
@@ -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
|
||||
@@ -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__
|
||||
@@ -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
|
||||
@@ -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__
|
||||
@@ -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
|
||||
@@ -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__
|
||||
@@ -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
|
||||
@@ -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__
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user