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:
38
Android.bp
38
Android.bp
@@ -1,40 +1,10 @@
|
||||
cc_defaults {
|
||||
name: "display_defaults",
|
||||
cflags: [
|
||||
"-Wno-missing-field-initializers",
|
||||
"-Wconversion",
|
||||
"-Wall",
|
||||
"-Werror",
|
||||
"-std=c++14",
|
||||
],
|
||||
shared_libs: [
|
||||
"liblog",
|
||||
"libcutils",
|
||||
"libutils",
|
||||
],
|
||||
header_libs: ["display_headers"],
|
||||
clang: true,
|
||||
}
|
||||
|
||||
cc_library_headers {
|
||||
name: "display_headers",
|
||||
name: "display_intf_headers",
|
||||
vendor_available: true,
|
||||
export_include_dirs: [
|
||||
"include",
|
||||
"libcopybit",
|
||||
"libdrmutils",
|
||||
"libqdutils",
|
||||
"libqservice",
|
||||
"gpu_tonemapper",
|
||||
"sdm/include",
|
||||
"gralloc",
|
||||
"libdebug",
|
||||
"include",
|
||||
"libdisplayconfig",
|
||||
"libqdmetadata",
|
||||
],
|
||||
header_libs: ["libhardware_headers"],
|
||||
export_header_lib_headers: ["libhardware_headers"],
|
||||
}
|
||||
|
||||
subdirs = [
|
||||
"libqservice",
|
||||
"libqdutils",
|
||||
]
|
||||
|
||||
19
Android.mk
19
Android.mk
@@ -1,19 +0,0 @@
|
||||
ifneq ($(TARGET_DISABLE_DISPLAY),true)
|
||||
sdm-libs := sdm/libs
|
||||
display-hals := include libdebug $(sdm-libs)/utils $(sdm-libs)/core
|
||||
|
||||
ifneq ($(TARGET_IS_HEADLESS), true)
|
||||
display-hals += libcopybit liblight libmemtrack hdmi_cec \
|
||||
$(sdm-libs)/hwc2 gpu_tonemapper libdrmutils libdisplayconfig
|
||||
endif
|
||||
|
||||
display-hals += gralloc
|
||||
|
||||
ifeq ($(call is-vendor-board-platform,QCOM),true)
|
||||
include $(call all-named-subdir-makefiles,$(display-hals))
|
||||
else
|
||||
ifneq ($(filter msm% apq%,$(TARGET_BOARD_PLATFORM)),)
|
||||
include $(call all-named-subdir-makefiles,$(display-hals))
|
||||
endif
|
||||
endif
|
||||
endif #TARGET_DISABLE_DISPLAY
|
||||
@@ -1,5 +0,0 @@
|
||||
# Makefile.am - Automake script for sdm
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
SUBDIRS = libqservice libqdutils sdm/libs/utils sdm/libs/core
|
||||
86
common.mk
86
common.mk
@@ -1,86 +0,0 @@
|
||||
#Common headers
|
||||
display_top := $(call my-dir)
|
||||
display_config_version := $(shell \
|
||||
if [ -d "$(TOP)/vendor/qcom/opensource/interfaces/display/config/1.1" ];\
|
||||
then echo DISPLAY_CONFIG_1_1; fi)
|
||||
|
||||
#Common C flags
|
||||
common_flags := -Wno-missing-field-initializers
|
||||
common_flags += -Wconversion -Wall -Werror -std=c++14
|
||||
common_flags += -DUSE_GRALLOC1
|
||||
ifeq ($(TARGET_IS_HEADLESS), true)
|
||||
common_flags += -DTARGET_HEADLESS
|
||||
LOCAL_CLANG := false
|
||||
endif
|
||||
|
||||
ifeq ($(display_config_version), DISPLAY_CONFIG_1_1)
|
||||
common_flags += -DDISPLAY_CONFIG_1_1
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_USES_COLOR_METADATA), true)
|
||||
common_flags += -DUSE_COLOR_METADATA
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_USES_QCOM_BSP),true)
|
||||
common_flags += -DQTI_BSP
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH_ARM_HAVE_NEON),true)
|
||||
common_flags += -D__ARM_HAVE_NEON
|
||||
endif
|
||||
|
||||
ifeq ($(call is-board-platform-in-list, $(MASTER_SIDE_CP_TARGET_LIST)), true)
|
||||
common_flags += -DMASTER_SIDE_CP
|
||||
endif
|
||||
|
||||
use_hwc2 := false
|
||||
ifeq ($(TARGET_USES_HWC2), true)
|
||||
use_hwc2 := true
|
||||
common_flags += -DVIDEO_MODE_DEFER_RETIRE_FENCE
|
||||
endif
|
||||
|
||||
ifneq (,$(filter userdebug eng, $(TARGET_BUILD_VARIANT)))
|
||||
common_flags += -DUSER_DEBUG
|
||||
endif
|
||||
|
||||
ifeq ($(LLVM_SA), true)
|
||||
common_flags += --compile-and-analyze --analyzer-perf --analyzer-Werror
|
||||
endif
|
||||
|
||||
common_includes := system/core/base/include
|
||||
CHECK_VERSION_LE = $(shell if [ $(1) -le $(2) ] ; then echo true ; else echo false ; fi)
|
||||
PLATFORM_SDK_NOUGAT = 25
|
||||
ifeq "REL" "$(PLATFORM_VERSION_CODENAME)"
|
||||
ifeq ($(call CHECK_VERSION_LE, $(PLATFORM_SDK_VERSION), $(PLATFORM_SDK_NOUGAT)), true)
|
||||
version_flag := -D__NOUGAT__
|
||||
|
||||
# These include paths are deprecated post N
|
||||
common_includes += $(display_top)/libqdutils
|
||||
common_includes += $(display_top)/libqservice
|
||||
common_includes += $(display_top)/gpu_tonemapper
|
||||
ifneq ($(TARGET_IS_HEADLESS), true)
|
||||
common_includes += $(display_top)/libcopybit
|
||||
endif
|
||||
|
||||
common_includes += $(display_top)/include
|
||||
common_includes += $(display_top)/sdm/include
|
||||
common_flags += -isystem $(TARGET_OUT_HEADERS)/qcom/display
|
||||
endif
|
||||
endif
|
||||
|
||||
common_header_export_path := qcom/display
|
||||
|
||||
#Common libraries external to display HAL
|
||||
common_libs := liblog libutils libcutils libhardware
|
||||
common_deps :=
|
||||
kernel_includes :=
|
||||
|
||||
ifeq ($(TARGET_COMPILE_WITH_MSM_KERNEL),true)
|
||||
# This check is to pick the kernel headers from the right location.
|
||||
# If the macro above is defined, we make the assumption that we have the kernel
|
||||
# available in the build tree.
|
||||
# If the macro is not present, the headers are picked from hardware/qcom/msmXXXX
|
||||
# failing which, they are picked from bionic.
|
||||
common_deps += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
|
||||
kernel_includes += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
|
||||
endif
|
||||
@@ -1,43 +0,0 @@
|
||||
#Display related packages and configuration
|
||||
|
||||
PRODUCT_PACKAGES += \
|
||||
android.hardware.graphics.composer@2.1-impl \
|
||||
android.hardware.graphics.composer@2.1-service \
|
||||
android.hardware.graphics.mapper@2.0-impl-qti-display \
|
||||
vendor.qti.hardware.display.allocator@1.0-service \
|
||||
android.hardware.memtrack@1.0-impl \
|
||||
android.hardware.memtrack@1.0-service \
|
||||
android.hardware.light@2.0-impl \
|
||||
android.hardware.light@2.0-service \
|
||||
modetest \
|
||||
gralloc.sdm845 \
|
||||
lights.sdm845 \
|
||||
hwcomposer.sdm845 \
|
||||
memtrack.sdm845 \
|
||||
libqdutils \
|
||||
libqdMetaData \
|
||||
libqdMetaData.system
|
||||
|
||||
|
||||
TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS := true
|
||||
MAX_VIRTUAL_DISPLAY_DIMENSION := 4096
|
||||
NUM_FRAMEBUFFER_SURFACE_BUFFERS := 2
|
||||
#Enable Charging Icon
|
||||
TARGET_RECOVERY_PIXEL_FORMAT := RGBX_8888
|
||||
TARGET_USES_GRALLOC1 := true
|
||||
TARGET_USES_HWC2 := true
|
||||
TARGET_USES_QCOM_DISPLAY_BSP := true
|
||||
TARGET_USES_COLOR_METADATA := true
|
||||
TARGET_USES_DRM_PP := true
|
||||
|
||||
PRODUCT_PROPERTY_OVERRIDES += \
|
||||
debug.sf.enable_hwc_vds=1 \
|
||||
persist.demo.hdmirotationlock=false \
|
||||
ro.vendor.display.cabl=2 \
|
||||
debug.sf.hw=0 \
|
||||
debug.egl.hw=0 \
|
||||
debug.sf.latch_unsignaled=1
|
||||
|
||||
|
||||
|
||||
|
||||
56
configure.ac
56
configure.ac
@@ -1,56 +0,0 @@
|
||||
# -*- Autoconf -*-
|
||||
# configure.ac -- Autoconf script for sdm
|
||||
#
|
||||
|
||||
# Process this file with autoconf to produce a configure script
|
||||
|
||||
# Requires autoconf tool later than 2.61
|
||||
AC_PREREQ(2.61)
|
||||
# Initialize the display package version 1.0.0
|
||||
AC_INIT([display],1.0.0)
|
||||
# Does not strictly follow GNU Coding standards
|
||||
AM_INIT_AUTOMAKE([foreign])
|
||||
# Disables auto rebuilding of configure, Makefile.ins
|
||||
AM_MAINTAINER_MODE
|
||||
# defines some macros variable to be included by source
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_SUBST([COMMON_CFLAGS], [-Wall -Werror -Wno-sign-conversion -Wconversion -DDEBUG_CALC_FPS])
|
||||
AC_SUBST([AM_CPPFLAGS], [--std=c++11])
|
||||
|
||||
AC_ARG_WITH([core_includes],
|
||||
AC_HELP_STRING([--with-core-includes=@<:@dir@:>@],
|
||||
[Specify the location of the core headers]),
|
||||
[core_incdir=$withval],
|
||||
with_core_includes=no)
|
||||
|
||||
if test "x$with_core_includes" != "xno"; then
|
||||
CFLAGS="${CFLAGS} -I${core_incdir}"
|
||||
fi
|
||||
|
||||
AC_ARG_WITH(sanitized-headers,
|
||||
AS_HELP_STRING([--with-sanitized-headers=DIR],
|
||||
[Specify the location of the sanitized Linux headers]),
|
||||
[CPPFLAGS="$CPPFLAGS -idirafter $withval"])
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
AM_PROG_CC_C_O
|
||||
AC_PROG_CXX
|
||||
AC_PROG_LIBTOOL
|
||||
AC_PROG_AWK
|
||||
AC_PROG_CPP
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
AC_PROG_MAKE_SET
|
||||
|
||||
AC_SUBST([CFLAGS])
|
||||
AC_SUBST([CC])
|
||||
AC_CONFIG_FILES([ \
|
||||
Makefile \
|
||||
libqservice/Makefile \
|
||||
libqdutils/Makefile \
|
||||
sdm/libs/utils/Makefile \
|
||||
sdm/libs/core/Makefile
|
||||
])
|
||||
AC_OUTPUT
|
||||
@@ -1,28 +0,0 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(LOCAL_PATH)/../common.mk
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_COPY_HEADERS_TO := $(common_header_export_path)
|
||||
LOCAL_COPY_HEADERS := TonemapFactory.h Tonemapper.h
|
||||
LOCAL_VENDOR_MODULE := true
|
||||
include $(BUILD_COPY_HEADERS)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := libgpu_tonemapper
|
||||
LOCAL_VENDOR_MODULE := true
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_C_INCLUDES := $(TARGET_OUT_HEADERS)/qcom/display/
|
||||
LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
|
||||
LOCAL_SHARED_LIBRARIES := libEGL libGLESv2 libGLESv3 libui libutils liblog
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) $(kernel_deps)
|
||||
|
||||
LOCAL_CFLAGS := $(version_flag) -Wno-missing-field-initializers -Wall \
|
||||
-Wno-unused-parameter -std=c++11 -DLOG_TAG=\"GPU_TONEMAPPER\"
|
||||
|
||||
LOCAL_SRC_FILES := TonemapFactory.cpp \
|
||||
glengine.cpp \
|
||||
EGLImageBuffer.cpp \
|
||||
EGLImageWrapper.cpp \
|
||||
Tonemapper.cpp
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
@@ -1,161 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
|
||||
* Not a Contribution.
|
||||
*
|
||||
* Copyright 2015 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.
|
||||
*/
|
||||
|
||||
#include "EGLImageBuffer.h"
|
||||
#include <cutils/native_handle.h>
|
||||
#include <gralloc_priv.h>
|
||||
#include <ui/GraphicBuffer.h>
|
||||
#include <map>
|
||||
#include "EGLImageWrapper.h"
|
||||
#include "glengine.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
EGLImageKHR create_eglImage(android::sp<android::GraphicBuffer> graphicBuffer)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
bool isProtected = (graphicBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
|
||||
EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
|
||||
isProtected ? EGL_PROTECTED_CONTENT_EXT : EGL_NONE,
|
||||
isProtected ? EGL_TRUE : EGL_NONE, EGL_NONE};
|
||||
|
||||
EGLImageKHR eglImage = eglCreateImageKHR(
|
||||
eglGetCurrentDisplay(), (EGLContext)EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
|
||||
(EGLClientBuffer)(graphicBuffer->getNativeBuffer()), attrs);
|
||||
|
||||
return eglImage;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
EGLImageBuffer::EGLImageBuffer(android::sp<android::GraphicBuffer> graphicBuffer)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
// this->graphicBuffer = graphicBuffer;
|
||||
this->eglImageID = create_eglImage(graphicBuffer);
|
||||
this->width = graphicBuffer->getWidth();
|
||||
this->height = graphicBuffer->getHeight();
|
||||
|
||||
textureID = 0;
|
||||
renderbufferID = 0;
|
||||
framebufferID = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
EGLImageBuffer::~EGLImageBuffer()
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if (textureID != 0) {
|
||||
GL(glDeleteTextures(1, &textureID));
|
||||
textureID = 0;
|
||||
}
|
||||
|
||||
if (renderbufferID != 0) {
|
||||
GL(glDeleteRenderbuffers(1, &renderbufferID));
|
||||
renderbufferID = 0;
|
||||
}
|
||||
|
||||
if (framebufferID != 0) {
|
||||
GL(glDeleteFramebuffers(1, &framebufferID));
|
||||
framebufferID = 0;
|
||||
}
|
||||
|
||||
// Delete the eglImage
|
||||
if (eglImageID != 0)
|
||||
{
|
||||
eglDestroyImageKHR(eglGetCurrentDisplay(), eglImageID);
|
||||
eglImageID = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int EGLImageBuffer::getWidth()
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return width;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int EGLImageBuffer::getHeight()
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
return height;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned int EGLImageBuffer::getTexture()
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if (textureID == 0) {
|
||||
bindAsTexture();
|
||||
}
|
||||
|
||||
return textureID;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned int EGLImageBuffer::getFramebuffer()
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if (framebufferID == 0) {
|
||||
bindAsFramebuffer();
|
||||
}
|
||||
|
||||
return framebufferID;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void EGLImageBuffer::bindAsTexture()
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if (textureID == 0) {
|
||||
GL(glGenTextures(1, &textureID));
|
||||
int target = 0x8D65;
|
||||
GL(glBindTexture(target, textureID));
|
||||
GL(glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
||||
GL(glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
|
||||
GL(glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
|
||||
GL(glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
|
||||
|
||||
GL(glEGLImageTargetTexture2DOES(0x8D65, eglImageID));
|
||||
}
|
||||
|
||||
GL(glBindTexture(0x8D65, textureID));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void EGLImageBuffer::bindAsFramebuffer()
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if (renderbufferID == 0) {
|
||||
GL(glGenFramebuffers(1, &framebufferID));
|
||||
GL(glGenRenderbuffers(1, &renderbufferID));
|
||||
|
||||
GL(glBindRenderbuffer(GL_RENDERBUFFER, renderbufferID));
|
||||
GL(glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, eglImageID));
|
||||
|
||||
GL(glBindFramebuffer(GL_FRAMEBUFFER, framebufferID));
|
||||
GL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
|
||||
renderbufferID));
|
||||
GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
if (result != GL_FRAMEBUFFER_COMPLETE) {
|
||||
ALOGI("%s Framebuffer Invalid***************", __FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
GL(glBindFramebuffer(GL_FRAMEBUFFER, framebufferID));
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, The Linux Foundation. All rights reserved.
|
||||
* Not a Contribution.
|
||||
*
|
||||
* Copyright 2015 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 __EGLIMAGE_BUFFER_H__
|
||||
#define __EGLIMAGE_BUFFER_H__
|
||||
|
||||
#include <cutils/native_handle.h>
|
||||
#include <gralloc_priv.h>
|
||||
#include <ui/GraphicBuffer.h>
|
||||
#include "engine.h"
|
||||
|
||||
class EGLImageBuffer {
|
||||
// android::sp<android::GraphicBuffer> graphicBuffer;
|
||||
void *eglImageID;
|
||||
int width;
|
||||
int height;
|
||||
uint textureID;
|
||||
uint renderbufferID;
|
||||
uint framebufferID;
|
||||
|
||||
public:
|
||||
int getWidth();
|
||||
int getHeight();
|
||||
EGLImageBuffer(android::sp<android::GraphicBuffer>);
|
||||
unsigned int getTexture();
|
||||
unsigned int getFramebuffer();
|
||||
void bindAsTexture();
|
||||
void bindAsFramebuffer();
|
||||
~EGLImageBuffer();
|
||||
static EGLImageBuffer *from(const private_handle_t *src);
|
||||
static void clear();
|
||||
};
|
||||
|
||||
#endif //__EGLIMAGE_BUFFER_H__
|
||||
@@ -1,154 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
|
||||
* Not a Contribution.
|
||||
*
|
||||
* Copyright 2015 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.
|
||||
*/
|
||||
|
||||
#include "EGLImageWrapper.h"
|
||||
#include <cutils/native_handle.h>
|
||||
#include <gralloc_priv.h>
|
||||
#include <ui/GraphicBuffer.h>
|
||||
#include <fcntl.h>
|
||||
#include <linux/msm_ion.h>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void free_ion_cookie(int ion_fd, int cookie)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if (ion_fd && !ioctl(ion_fd, ION_IOC_FREE, &cookie)) {
|
||||
} else {
|
||||
ALOGE("ION_IOC_FREE failed: ion_fd = %d, cookie = %d", ion_fd, cookie);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int get_ion_cookie(int ion_fd, int fd)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
int cookie = fd;
|
||||
|
||||
struct ion_fd_data fdData;
|
||||
memset(&fdData, 0, sizeof(fdData));
|
||||
fdData.fd = fd;
|
||||
|
||||
if (ion_fd && !ioctl(ion_fd, ION_IOC_IMPORT, &fdData)) {
|
||||
cookie = fdData.handle;
|
||||
} else {
|
||||
ALOGE("ION_IOC_IMPORT failed: ion_fd = %d, fd = %d", ion_fd, fd);
|
||||
}
|
||||
|
||||
return cookie;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
EGLImageWrapper::DeleteEGLImageCallback::DeleteEGLImageCallback(int fd)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
ion_fd = fd;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void EGLImageWrapper::DeleteEGLImageCallback::operator()(int& k, EGLImageBuffer*& eglImage)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
free_ion_cookie(ion_fd, k);
|
||||
if( eglImage != 0 )
|
||||
{
|
||||
delete eglImage;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
EGLImageWrapper::EGLImageWrapper()
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
eglImageBufferMap = new android::LruCache<int, EGLImageBuffer*>(32);
|
||||
ion_fd = open("/dev/ion", O_RDONLY);
|
||||
callback = new DeleteEGLImageCallback(ion_fd);
|
||||
eglImageBufferMap->setOnEntryRemovedListener(callback);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
EGLImageWrapper::~EGLImageWrapper()
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if( eglImageBufferMap != 0 )
|
||||
{
|
||||
eglImageBufferMap->clear();
|
||||
delete eglImageBufferMap;
|
||||
eglImageBufferMap = 0;
|
||||
}
|
||||
|
||||
if( callback != 0 )
|
||||
{
|
||||
delete callback;
|
||||
callback = 0;
|
||||
}
|
||||
|
||||
if( ion_fd > 0 )
|
||||
{
|
||||
close(ion_fd);
|
||||
}
|
||||
ion_fd = -1;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
static EGLImageBuffer* L_wrap(const private_handle_t *src)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
EGLImageBuffer* result = 0;
|
||||
|
||||
native_handle_t *native_handle = const_cast<private_handle_t *>(src);
|
||||
|
||||
int flags = android::GraphicBuffer::USAGE_HW_TEXTURE |
|
||||
android::GraphicBuffer::USAGE_SW_READ_NEVER |
|
||||
android::GraphicBuffer::USAGE_SW_WRITE_NEVER;
|
||||
|
||||
if (src->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
|
||||
flags |= android::GraphicBuffer::USAGE_PROTECTED;
|
||||
}
|
||||
|
||||
android::sp<android::GraphicBuffer> graphicBuffer =
|
||||
new android::GraphicBuffer(src->unaligned_width, src->unaligned_height, src->format,
|
||||
#ifndef __NOUGAT__
|
||||
1, // Layer count
|
||||
#endif
|
||||
flags, src->width /*src->stride*/,
|
||||
native_handle, false);
|
||||
|
||||
result = new EGLImageBuffer(graphicBuffer);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
EGLImageBuffer *EGLImageWrapper::wrap(const void *pvt_handle)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
const private_handle_t *src = static_cast<const private_handle_t *>(pvt_handle);
|
||||
|
||||
int ion_cookie = get_ion_cookie(ion_fd, src->fd);
|
||||
EGLImageBuffer* eglImage = eglImageBufferMap->get(ion_cookie);
|
||||
if( eglImage == 0 )
|
||||
{
|
||||
eglImage = L_wrap(src);
|
||||
eglImageBufferMap->put(ion_cookie, eglImage);
|
||||
}
|
||||
else {
|
||||
free_ion_cookie(ion_fd, ion_cookie);
|
||||
}
|
||||
|
||||
return eglImage;
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
|
||||
* Not a Contribution.
|
||||
*
|
||||
* Copyright 2015 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 __TONEMAPPER_EGLIMAGEWRAPPER_H__
|
||||
#define __TONEMAPPER_EGLIMAGEWRAPPER_H__
|
||||
|
||||
#include <utils/LruCache.h>
|
||||
#include "EGLImageBuffer.h"
|
||||
|
||||
class EGLImageWrapper {
|
||||
private:
|
||||
class DeleteEGLImageCallback : public android::OnEntryRemoved<int, EGLImageBuffer*>
|
||||
{
|
||||
private:
|
||||
int ion_fd;
|
||||
public:
|
||||
DeleteEGLImageCallback(int ion_fd);
|
||||
void operator()(int& ion_cookie, EGLImageBuffer*& eglImage);
|
||||
};
|
||||
|
||||
android::LruCache<int, EGLImageBuffer *>* eglImageBufferMap;
|
||||
DeleteEGLImageCallback* callback;
|
||||
int ion_fd;
|
||||
|
||||
public:
|
||||
EGLImageWrapper();
|
||||
~EGLImageWrapper();
|
||||
EGLImageBuffer* wrap(const void *pvt_handle);
|
||||
};
|
||||
|
||||
#endif //__TONEMAPPER_EGLIMAGEWRAPPER_H__
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
|
||||
* Not a Contribution.
|
||||
*
|
||||
* Copyright 2015 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.
|
||||
*/
|
||||
|
||||
#include "TonemapFactory.h"
|
||||
#include <log/log.h>
|
||||
#include "Tonemapper.h"
|
||||
#include "engine.h"
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
Tonemapper *TonemapperFactory_GetInstance(int type, void *colorMap, int colorMapSize,
|
||||
void *lutXform, int lutXformSize, bool isSecure)
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
{
|
||||
// build the tonemapper
|
||||
Tonemapper *tonemapper = Tonemapper::build(type, colorMap, colorMapSize, lutXform, lutXformSize, isSecure);
|
||||
|
||||
return tonemapper;
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, The Linux Foundation. All rights reserved.
|
||||
* Not a Contribution.
|
||||
*
|
||||
* Copyright 2015 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 __TONEMAPPER_TONEMAPPERFACTORY_H__
|
||||
#define __TONEMAPPER_TONEMAPPERFACTORY_H__
|
||||
|
||||
#include "Tonemapper.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// returns an instance of Tonemapper
|
||||
Tonemapper *TonemapperFactory_GetInstance(int type, void *colorMap, int colorMapSize,
|
||||
void *lutXform, int lutXformSize, bool isSecure);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //__TONEMAPPER_TONEMAPPERFACTORY_H__
|
||||
@@ -1,153 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
|
||||
* Not a Contribution.
|
||||
*
|
||||
* Copyright 2015 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.
|
||||
*/
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include "EGLImageWrapper.h"
|
||||
#include "Tonemapper.h"
|
||||
#include "engine.h"
|
||||
#include "forward_tonemap.inl"
|
||||
#include "fullscreen_vertex_shader.inl"
|
||||
#include "rgba_inverse_tonemap.inl"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
Tonemapper::Tonemapper()
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
tonemapTexture = 0;
|
||||
lutXformTexture = 0;
|
||||
programID = 0;
|
||||
eglImageWrapper = new EGLImageWrapper();
|
||||
|
||||
lutXformScaleOffset[0] = 1.0f;
|
||||
lutXformScaleOffset[1] = 0.0f;
|
||||
|
||||
tonemapScaleOffset[0] = 1.0f;
|
||||
tonemapScaleOffset[1] = 0.0f;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
Tonemapper::~Tonemapper()
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
engine_bind(engineContext);
|
||||
engine_deleteInputBuffer(tonemapTexture);
|
||||
engine_deleteInputBuffer(lutXformTexture);
|
||||
engine_deleteProgram(programID);
|
||||
|
||||
// clear EGLImage mappings
|
||||
if (eglImageWrapper != 0) {
|
||||
delete eglImageWrapper;
|
||||
eglImageWrapper = 0;
|
||||
}
|
||||
|
||||
engine_shutdown(engineContext);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
Tonemapper *Tonemapper::build(int type, void *colorMap, int colorMapSize, void *lutXform,
|
||||
int lutXformSize, bool isSecure)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if (colorMapSize <= 0) {
|
||||
ALOGE("Invalid Color Map size = %d", colorMapSize);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// build new tonemapper
|
||||
Tonemapper *tonemapper = new Tonemapper();
|
||||
|
||||
tonemapper->engineContext = engine_initialize(isSecure);
|
||||
|
||||
engine_bind(tonemapper->engineContext);
|
||||
|
||||
// load the 3d lut
|
||||
tonemapper->tonemapTexture = engine_load3DTexture(colorMap, colorMapSize, 0);
|
||||
tonemapper->tonemapScaleOffset[0] = ((float)(colorMapSize-1))/((float)(colorMapSize));
|
||||
tonemapper->tonemapScaleOffset[1] = 1.0f/(2.0f*colorMapSize);
|
||||
|
||||
// load the non-uniform xform
|
||||
tonemapper->lutXformTexture = engine_load1DTexture(lutXform, lutXformSize, 0);
|
||||
bool bUseXform = (tonemapper->lutXformTexture != 0) && (lutXformSize != 0);
|
||||
if( bUseXform )
|
||||
{
|
||||
tonemapper->lutXformScaleOffset[0] = ((float)(lutXformSize-1))/((float)(lutXformSize));
|
||||
tonemapper->lutXformScaleOffset[1] = 1.0f/(2.0f*lutXformSize);
|
||||
}
|
||||
|
||||
// create the program
|
||||
const char *fragmentShaders[3];
|
||||
int fragmentShaderCount = 0;
|
||||
const char *version = "#version 300 es\n";
|
||||
const char *define = "#define USE_NONUNIFORM_SAMPLING\n";
|
||||
|
||||
fragmentShaders[fragmentShaderCount++] = version;
|
||||
|
||||
// non-uniform sampling
|
||||
if (bUseXform) {
|
||||
fragmentShaders[fragmentShaderCount++] = define;
|
||||
}
|
||||
|
||||
if (type == TONEMAP_INVERSE) { // inverse tonemapping
|
||||
fragmentShaders[fragmentShaderCount++] = rgba_inverse_tonemap_shader;
|
||||
} else { // forward tonemapping
|
||||
fragmentShaders[fragmentShaderCount++] = forward_tonemap_shader;
|
||||
}
|
||||
|
||||
tonemapper->programID =
|
||||
engine_loadProgram(1, &fullscreen_vertex_shader, fragmentShaderCount, fragmentShaders);
|
||||
|
||||
return tonemapper;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int Tonemapper::blit(const void *dst, const void *src, int srcFenceFd)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
// make current
|
||||
engine_bind(engineContext);
|
||||
|
||||
// create eglimages if required
|
||||
EGLImageBuffer *dst_buffer = eglImageWrapper->wrap(dst);
|
||||
EGLImageBuffer *src_buffer = eglImageWrapper->wrap(src);
|
||||
|
||||
// bind the program
|
||||
engine_setProgram(programID);
|
||||
|
||||
engine_setData2f(3, tonemapScaleOffset);
|
||||
bool bUseXform = (lutXformTexture != 0);
|
||||
if( bUseXform )
|
||||
{
|
||||
engine_setData2f(4, lutXformScaleOffset);
|
||||
}
|
||||
|
||||
// set destination
|
||||
engine_setDestination(dst_buffer->getFramebuffer(), 0, 0, dst_buffer->getWidth(),
|
||||
dst_buffer->getHeight());
|
||||
// set source
|
||||
engine_setExternalInputBuffer(0, src_buffer->getTexture());
|
||||
// set 3d lut
|
||||
engine_set3DInputBuffer(1, tonemapTexture);
|
||||
// set non-uniform xform
|
||||
engine_set2DInputBuffer(2, lutXformTexture);
|
||||
|
||||
// perform
|
||||
int fenceFD = engine_blit(srcFenceFd);
|
||||
|
||||
return fenceFD;
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
|
||||
* Not a Contribution.
|
||||
*
|
||||
* Copyright 2015 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 __TONEMAPPER_TONEMAP_H__
|
||||
#define __TONEMAPPER_TONEMAP_H__
|
||||
|
||||
#define TONEMAP_FORWARD 0
|
||||
#define TONEMAP_INVERSE 1
|
||||
|
||||
#include "EGLImageWrapper.h"
|
||||
#include "engine.h"
|
||||
|
||||
class Tonemapper {
|
||||
private:
|
||||
void* engineContext;
|
||||
unsigned int tonemapTexture;
|
||||
unsigned int lutXformTexture;
|
||||
unsigned int programID;
|
||||
float lutXformScaleOffset[2];
|
||||
float tonemapScaleOffset[2];
|
||||
EGLImageWrapper* eglImageWrapper;
|
||||
Tonemapper();
|
||||
|
||||
public:
|
||||
~Tonemapper();
|
||||
static Tonemapper *build(int type, void *colorMap, int colorMapSize, void *lutXform,
|
||||
int lutXformSize, bool isSecure);
|
||||
int blit(const void *dst, const void *src, int srcFenceFd);
|
||||
};
|
||||
|
||||
#endif //__TONEMAPPER_TONEMAP_H__
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
|
||||
* Not a Contribution.
|
||||
*
|
||||
* Copyright 2015 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 __TONEMAPPER_ENGINE_H__
|
||||
#define __TONEMAPPER_ENGINE_H__
|
||||
|
||||
void* engine_initialize(bool isSecure);
|
||||
void engine_bind(void*);
|
||||
void engine_shutdown(void*);
|
||||
|
||||
unsigned int engine_loadProgram(int, const char **, int, const char **);
|
||||
void engine_setProgram(int);
|
||||
void engine_deleteProgram(unsigned int);
|
||||
|
||||
unsigned int engine_load3DTexture(void *data, int sz, int format);
|
||||
unsigned int engine_load1DTexture(void *xform, int xformSize, int format);
|
||||
void engine_deleteInputBuffer(unsigned int);
|
||||
|
||||
void engine_set2DInputBuffer(int binding, unsigned int textureID);
|
||||
void engine_set3DInputBuffer(int binding, unsigned int textureID);
|
||||
void engine_setExternalInputBuffer(int binding, unsigned int textureID);
|
||||
void engine_setDestination(int id, int x, int y, int w, int h);
|
||||
void engine_setData2f(int loc, float* data);
|
||||
|
||||
int engine_blit(int);
|
||||
|
||||
#endif //__TONEMAPPER_ENGINE_H__
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
|
||||
* Not a Contribution.
|
||||
*
|
||||
* Copyright 2015 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.
|
||||
*/
|
||||
|
||||
const char* forward_tonemap_shader = ""
|
||||
"#extension GL_OES_EGL_image_external_essl3 : require \n"
|
||||
"precision highp float; \n"
|
||||
"precision highp sampler2D; \n"
|
||||
"layout(binding = 0) uniform samplerExternalOES externalTexture; \n"
|
||||
"layout(binding = 1) uniform sampler3D tonemapper; \n"
|
||||
"layout(binding = 2) uniform sampler2D xform; \n"
|
||||
"layout(location = 3) uniform vec2 tSO; \n"
|
||||
"#ifdef USE_NONUNIFORM_SAMPLING \n"
|
||||
"layout(location = 4) uniform vec2 xSO; \n"
|
||||
"#endif \n"
|
||||
"in vec2 uv; \n"
|
||||
"out vec4 fs_color; \n"
|
||||
" \n"
|
||||
"vec3 ScaleOffset(in vec3 samplePt, in vec2 so) \n"
|
||||
"{ \n"
|
||||
" vec3 adjPt = so.x * samplePt + so.y; \n"
|
||||
" return adjPt; \n"
|
||||
"} \n"
|
||||
" \n"
|
||||
"void main() \n"
|
||||
"{ \n"
|
||||
"vec2 flipped = vec2(uv.x, 1.0f - uv.y); \n"
|
||||
"vec4 rgb = texture(externalTexture, flipped); \n"
|
||||
"#ifdef USE_NONUNIFORM_SAMPLING \n"
|
||||
"vec3 adj = ScaleOffset(rgb.xyz, xSO); \n"
|
||||
"float r = texture(xform, vec2(adj.r, 0.5f)).r; \n"
|
||||
"float g = texture(xform, vec2(adj.g, 0.5f)).g; \n"
|
||||
"float b = texture(xform, vec2(adj.b, 0.5f)).b; \n"
|
||||
"#else \n"
|
||||
"float r = rgb.r; \n"
|
||||
"float g = rgb.g; \n"
|
||||
"float b = rgb.b; \n"
|
||||
"#endif \n"
|
||||
"fs_color.rgb = texture(tonemapper, ScaleOffset(vec3(r, g, b), tSO)).rgb; \n"
|
||||
"} \n";
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, The Linux Foundation. All rights reserved.
|
||||
* Not a Contribution.
|
||||
*
|
||||
* Copyright 2015 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.
|
||||
*/
|
||||
|
||||
const char* fullscreen_vertex_shader = " "
|
||||
"#version 300 es \n"
|
||||
"precision highp float; \n"
|
||||
"layout(location = 0) in vec2 iUV; \n"
|
||||
"out vec2 uv; \n"
|
||||
"void main() \n"
|
||||
"{ \n"
|
||||
" vec2 positions[3]; \n"
|
||||
" positions[0] = vec2(-1.0f, 3.0f); \n"
|
||||
" positions[1] = vec2(-1.0f, -1.0f); \n"
|
||||
" positions[2] = vec2(3.0f, -1.0f); \n"
|
||||
" vec2 uvs[3]; \n"
|
||||
" uvs[0] = vec2(0.0f, -1.0f); \n"
|
||||
" uvs[1] = vec2(0.0f, 1.0f); \n"
|
||||
" uvs[2] = vec2(2.0f, 1.0f); \n"
|
||||
" gl_Position = vec4(positions[gl_VertexID], -1.0f, 1.0f); \n"
|
||||
" uv = uvs[gl_VertexID]; \n"
|
||||
"} \n";
|
||||
@@ -1,415 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
|
||||
* Not a Contribution.
|
||||
*
|
||||
* Copyright 2015 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.
|
||||
*/
|
||||
|
||||
#include "glengine.h"
|
||||
#include <log/log.h>
|
||||
#include "engine.h"
|
||||
|
||||
void checkGlError(const char *, int);
|
||||
void checkEglError(const char *, int);
|
||||
|
||||
class EngineContext {
|
||||
public:
|
||||
EGLDisplay eglDisplay;
|
||||
EGLContext eglContext;
|
||||
EGLSurface eglSurface;
|
||||
EngineContext()
|
||||
{
|
||||
eglDisplay = EGL_NO_DISPLAY;
|
||||
eglContext = EGL_NO_CONTEXT;
|
||||
eglSurface = EGL_NO_SURFACE;
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Make Current
|
||||
void engine_bind(void* context)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
EngineContext* engineContext = (EngineContext*)(context);
|
||||
EGL(eglMakeCurrent(engineContext->eglDisplay, engineContext->eglSurface, engineContext->eglSurface, engineContext->eglContext));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// initialize GL
|
||||
//
|
||||
void* engine_initialize(bool isSecure)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
EngineContext* engineContext = new EngineContext();
|
||||
|
||||
// display
|
||||
engineContext->eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
EGL(eglBindAPI(EGL_OPENGL_ES_API));
|
||||
|
||||
// initialize
|
||||
EGL(eglInitialize(engineContext->eglDisplay, 0, 0));
|
||||
|
||||
// config
|
||||
EGLConfig eglConfig;
|
||||
EGLint eglConfigAttribList[] = {EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
|
||||
EGL_RED_SIZE, 8,
|
||||
EGL_GREEN_SIZE, 8,
|
||||
EGL_BLUE_SIZE, 8,
|
||||
EGL_ALPHA_SIZE, 8,
|
||||
EGL_NONE};
|
||||
int numConfig = 0;
|
||||
EGL(eglChooseConfig(engineContext->eglDisplay, eglConfigAttribList, &eglConfig, 1, &numConfig));
|
||||
|
||||
// context
|
||||
EGLint eglContextAttribList[] = {EGL_CONTEXT_CLIENT_VERSION, 3,
|
||||
isSecure ? EGL_PROTECTED_CONTENT_EXT : EGL_NONE,
|
||||
isSecure ? EGL_TRUE : EGL_NONE,
|
||||
EGL_NONE};
|
||||
engineContext->eglContext = eglCreateContext(engineContext->eglDisplay, eglConfig, NULL, eglContextAttribList);
|
||||
|
||||
// surface
|
||||
EGLint eglSurfaceAttribList[] = {EGL_WIDTH, 1,
|
||||
EGL_HEIGHT, 1,
|
||||
isSecure ? EGL_PROTECTED_CONTENT_EXT : EGL_NONE,
|
||||
isSecure ? EGL_TRUE : EGL_NONE,
|
||||
EGL_NONE};
|
||||
engineContext->eglSurface = eglCreatePbufferSurface(engineContext->eglDisplay, eglConfig, eglSurfaceAttribList);
|
||||
|
||||
eglMakeCurrent(engineContext->eglDisplay, engineContext->eglSurface, engineContext->eglSurface, engineContext->eglContext);
|
||||
|
||||
ALOGI("In %s context = %p", __FUNCTION__, (void *)(engineContext->eglContext));
|
||||
|
||||
return (void*)(engineContext);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Shutdown.
|
||||
void engine_shutdown(void* context)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
EngineContext* engineContext = (EngineContext*)context;
|
||||
EGL(eglMakeCurrent(engineContext->eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
|
||||
EGL(eglDestroySurface(engineContext->eglDisplay, engineContext->eglSurface));
|
||||
EGL(eglDestroyContext(engineContext->eglDisplay, engineContext->eglContext));
|
||||
EGL(eglTerminate(engineContext->eglDisplay));
|
||||
engineContext->eglDisplay = EGL_NO_DISPLAY;
|
||||
engineContext->eglContext = EGL_NO_CONTEXT;
|
||||
engineContext->eglSurface = EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void engine_deleteInputBuffer(unsigned int id)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if (id != 0) {
|
||||
GL(glDeleteTextures(1, &id));
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void engine_deleteProgram(unsigned int id)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if (id != 0) {
|
||||
GL(glDeleteProgram(id));
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void engine_setData2f(int location, float* data)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
GL(glUniform2f(location, data[0], data[1]));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned int engine_load3DTexture(void *colorMapData, int sz, int format)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
GLuint texture = 0;
|
||||
GL(glGenTextures(1, &texture));
|
||||
GL(glBindTexture(GL_TEXTURE_3D, texture));
|
||||
GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
|
||||
GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
|
||||
GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE));
|
||||
GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
||||
GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
|
||||
|
||||
GL(glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB10_A2, sz, sz, sz, 0, GL_RGBA,
|
||||
GL_UNSIGNED_INT_2_10_10_10_REV, colorMapData));
|
||||
|
||||
return texture;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
unsigned int engine_load1DTexture(void *data, int sz, int format)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
GLuint texture = 0;
|
||||
if ((data != 0) && (sz != 0)) {
|
||||
GL(glGenTextures(1, &texture));
|
||||
GL(glBindTexture(GL_TEXTURE_2D, texture));
|
||||
GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
|
||||
GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
|
||||
GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
||||
GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
|
||||
|
||||
GL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB10_A2, sz, 1, 0, GL_RGBA,
|
||||
GL_UNSIGNED_INT_2_10_10_10_REV, data));
|
||||
}
|
||||
return texture;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void dumpShaderLog(int shader)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
int success = 0;
|
||||
GLchar infoLog[512];
|
||||
GL(glGetShaderiv(shader, GL_COMPILE_STATUS, &success));
|
||||
if (!success) {
|
||||
glGetShaderInfoLog(shader, 512, NULL, infoLog);
|
||||
ALOGI("Shader Failed to compile: %s\n", infoLog);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
GLuint engine_loadProgram(int vertexEntries, const char **vertex, int fragmentEntries,
|
||||
const char **fragment)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
GLuint progId = glCreateProgram();
|
||||
|
||||
int vertId = glCreateShader(GL_VERTEX_SHADER);
|
||||
int fragId = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
|
||||
GL(glShaderSource(vertId, vertexEntries, vertex, 0));
|
||||
GL(glCompileShader(vertId));
|
||||
dumpShaderLog(vertId);
|
||||
|
||||
GL(glShaderSource(fragId, fragmentEntries, fragment, 0));
|
||||
GL(glCompileShader(fragId));
|
||||
dumpShaderLog(fragId);
|
||||
|
||||
GL(glAttachShader(progId, vertId));
|
||||
GL(glAttachShader(progId, fragId));
|
||||
|
||||
GL(glLinkProgram(progId));
|
||||
|
||||
GL(glDetachShader(progId, vertId));
|
||||
GL(glDetachShader(progId, fragId));
|
||||
|
||||
GL(glDeleteShader(vertId));
|
||||
GL(glDeleteShader(fragId));
|
||||
|
||||
return progId;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void WaitOnNativeFence(int fd)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
if (fd != -1) {
|
||||
EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fd, EGL_NONE};
|
||||
|
||||
EGLSyncKHR sync = eglCreateSyncKHR(eglGetCurrentDisplay(), EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
|
||||
|
||||
if (sync == EGL_NO_SYNC_KHR) {
|
||||
ALOGE("%s - Failed to Create sync from source fd", __FUNCTION__);
|
||||
} else {
|
||||
// the gpu will wait for this sync - not this cpu thread.
|
||||
EGL(eglWaitSyncKHR(eglGetCurrentDisplay(), sync, 0));
|
||||
EGL(eglDestroySyncKHR(eglGetCurrentDisplay(), sync));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int CreateNativeFence()
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
int fd = -1;
|
||||
|
||||
EGLSyncKHR sync = eglCreateSyncKHR(eglGetCurrentDisplay(), EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
|
||||
GL(glFlush());
|
||||
if (sync == EGL_NO_SYNC_KHR) {
|
||||
ALOGE("%s - Failed to Create Native Fence sync", __FUNCTION__);
|
||||
} else {
|
||||
fd = eglDupNativeFenceFDANDROID(eglGetCurrentDisplay(), sync);
|
||||
if (fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
|
||||
ALOGE("%s - Failed to dup sync", __FUNCTION__);
|
||||
}
|
||||
EGL(eglDestroySyncKHR(eglGetCurrentDisplay(), sync));
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void engine_setDestination(int id, int x, int y, int w, int h)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
GL(glBindFramebuffer(GL_FRAMEBUFFER, id));
|
||||
GL(glViewport(x, y, w, h));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void engine_setProgram(int id)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
GL(glUseProgram(id));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void engine_set2DInputBuffer(int binding, unsigned int id)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
GL(glActiveTexture(GL_TEXTURE0 + binding));
|
||||
GL(glBindTexture(GL_TEXTURE_2D, id));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void engine_set3DInputBuffer(int binding, unsigned int id)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
GL(glActiveTexture(GL_TEXTURE0 + binding));
|
||||
GL(glBindTexture(GL_TEXTURE_3D, id));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void engine_setExternalInputBuffer(int binding, unsigned int id)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
GL(glActiveTexture(GL_TEXTURE0 + binding));
|
||||
GL(glBindTexture(0x8D65, id));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
int engine_blit(int srcFenceFd)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
int fd = -1;
|
||||
WaitOnNativeFence(srcFenceFd);
|
||||
float fullscreen_vertices[]{0.0f, 2.0f, 0.0f, 0.0f, 2.0f, 0.0f};
|
||||
GL(glEnableVertexAttribArray(0));
|
||||
GL(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, fullscreen_vertices));
|
||||
GL(glDrawArrays(GL_TRIANGLES, 0, 3));
|
||||
fd = CreateNativeFence();
|
||||
GL(glFlush());
|
||||
return fd;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void checkGlError(const char *file, int line)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
for (GLint error = glGetError(); error; error = glGetError()) {
|
||||
char *pError;
|
||||
switch (error) {
|
||||
case GL_NO_ERROR:
|
||||
pError = (char *)"GL_NO_ERROR";
|
||||
break;
|
||||
case GL_INVALID_ENUM:
|
||||
pError = (char *)"GL_INVALID_ENUM";
|
||||
break;
|
||||
case GL_INVALID_VALUE:
|
||||
pError = (char *)"GL_INVALID_VALUE";
|
||||
break;
|
||||
case GL_INVALID_OPERATION:
|
||||
pError = (char *)"GL_INVALID_OPERATION";
|
||||
break;
|
||||
case GL_OUT_OF_MEMORY:
|
||||
pError = (char *)"GL_OUT_OF_MEMORY";
|
||||
break;
|
||||
case GL_INVALID_FRAMEBUFFER_OPERATION:
|
||||
pError = (char *)"GL_INVALID_FRAMEBUFFER_OPERATION";
|
||||
break;
|
||||
|
||||
default:
|
||||
ALOGE("glError (0x%x) %s:%d\n", error, file, line);
|
||||
return;
|
||||
}
|
||||
|
||||
ALOGE("glError (%s) %s:%d\n", pError, file, line);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void checkEglError(const char *file, int line)
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
for (int i = 0; i < 5; i++) {
|
||||
const EGLint error = eglGetError();
|
||||
if (error == EGL_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
|
||||
char *pError;
|
||||
switch (error) {
|
||||
case EGL_SUCCESS:
|
||||
pError = (char *)"EGL_SUCCESS";
|
||||
break;
|
||||
case EGL_NOT_INITIALIZED:
|
||||
pError = (char *)"EGL_NOT_INITIALIZED";
|
||||
break;
|
||||
case EGL_BAD_ACCESS:
|
||||
pError = (char *)"EGL_BAD_ACCESS";
|
||||
break;
|
||||
case EGL_BAD_ALLOC:
|
||||
pError = (char *)"EGL_BAD_ALLOC";
|
||||
break;
|
||||
case EGL_BAD_ATTRIBUTE:
|
||||
pError = (char *)"EGL_BAD_ATTRIBUTE";
|
||||
break;
|
||||
case EGL_BAD_CONTEXT:
|
||||
pError = (char *)"EGL_BAD_CONTEXT";
|
||||
break;
|
||||
case EGL_BAD_CONFIG:
|
||||
pError = (char *)"EGL_BAD_CONFIG";
|
||||
break;
|
||||
case EGL_BAD_CURRENT_SURFACE:
|
||||
pError = (char *)"EGL_BAD_CURRENT_SURFACE";
|
||||
break;
|
||||
case EGL_BAD_DISPLAY:
|
||||
pError = (char *)"EGL_BAD_DISPLAY";
|
||||
break;
|
||||
case EGL_BAD_SURFACE:
|
||||
pError = (char *)"EGL_BAD_SURFACE";
|
||||
break;
|
||||
case EGL_BAD_MATCH:
|
||||
pError = (char *)"EGL_BAD_MATCH";
|
||||
break;
|
||||
case EGL_BAD_PARAMETER:
|
||||
pError = (char *)"EGL_BAD_PARAMETER";
|
||||
break;
|
||||
case EGL_BAD_NATIVE_PIXMAP:
|
||||
pError = (char *)"EGL_BAD_NATIVE_PIXMAP";
|
||||
break;
|
||||
case EGL_BAD_NATIVE_WINDOW:
|
||||
pError = (char *)"EGL_BAD_NATIVE_WINDOW";
|
||||
break;
|
||||
case EGL_CONTEXT_LOST:
|
||||
pError = (char *)"EGL_CONTEXT_LOST";
|
||||
break;
|
||||
default:
|
||||
ALOGE("eglError (0x%x) %s:%d\n", error, file, line);
|
||||
return;
|
||||
}
|
||||
ALOGE("eglError (%s) %s:%d\n", pError, file, line);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, The Linux Foundation. All rights reserved.
|
||||
* Not a Contribution.
|
||||
*
|
||||
* Copyright 2015 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 __TONEMAPPER_GLENGINE_H__
|
||||
#define __TONEMAPPER_GLENGINE_H__
|
||||
#include <EGL/egl.h>
|
||||
#define EGL_EGLEXT_PROTOTYPES
|
||||
#include <EGL/eglext.h>
|
||||
#include <GLES3/gl31.h>
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
#include <GLES2/gl2ext.h>
|
||||
#include <GLES3/gl3ext.h>
|
||||
|
||||
#if defined(CHECK_GL_ERRORS)
|
||||
#define GL(func) func;
|
||||
#define EGL(func) func;
|
||||
#else
|
||||
#define GL(func) \
|
||||
func; \
|
||||
checkGlError(__FILE__, __LINE__);
|
||||
#define EGL(func) \
|
||||
func; \
|
||||
checkEglError(__FILE__, __LINE__);
|
||||
#endif
|
||||
|
||||
#define EGL_PROTECTED_CONTENT_EXT 0x32C0
|
||||
|
||||
void checkGlError(const char *file, int line);
|
||||
void checkEglError(const char *file, int line);
|
||||
|
||||
#endif //__TONEMAPPER_GLENGINE_H__
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
|
||||
* Not a Contribution.
|
||||
*
|
||||
* Copyright 2015 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.
|
||||
*/
|
||||
|
||||
const char* rgba_inverse_tonemap_shader = ""
|
||||
"#extension GL_OES_EGL_image_external_essl3 : require \n"
|
||||
"precision highp float; \n"
|
||||
"precision highp sampler2D; \n"
|
||||
"layout(binding = 0) uniform samplerExternalOES externalTexture; \n"
|
||||
"layout(binding = 1) uniform sampler3D tonemapper; \n"
|
||||
"layout(binding = 2) uniform sampler2D xform; \n"
|
||||
"layout(location = 3) uniform vec2 tSO; \n"
|
||||
"#if defined(USE_NONUNIFORM_SAMPLING) \n"
|
||||
"layout(location = 4) uniform vec2 xSO; \n"
|
||||
"#endif \n"
|
||||
"in vec2 uv; \n"
|
||||
"out vec4 fs_color; \n"
|
||||
" \n"
|
||||
"vec3 ScaleOffset(in vec3 samplePt, in vec2 so) \n"
|
||||
"{ \n"
|
||||
" vec3 adjPt = so.x * samplePt + so.y; \n"
|
||||
" return adjPt; \n"
|
||||
"} \n"
|
||||
" \n"
|
||||
"void main() \n"
|
||||
"{ \n"
|
||||
"vec2 flipped = vec2(uv.x, 1.0f - uv.y); \n"
|
||||
"vec4 rgb_premulalpha = texture(externalTexture, flipped); \n"
|
||||
"fs_color = rgb_premulalpha; \n"
|
||||
"if( rgb_premulalpha.a > 0.0 ) { \n"
|
||||
"vec3 rgb = rgb_premulalpha.rgb/rgb_premulalpha.a; \n"
|
||||
"#if defined(USE_NONUNIFORM_SAMPLING) \n"
|
||||
"vec3 adj = ScaleOffset(rgb.xyz, xSO); \n"
|
||||
"float r = texture(xform, vec2(adj.r, 0.5f)).r; \n"
|
||||
"float g = texture(xform, vec2(adj.g, 0.5f)).g; \n"
|
||||
"float b = texture(xform, vec2(adj.b, 0.5f)).b; \n"
|
||||
"#else \n"
|
||||
"float r = rgb.r; \n"
|
||||
"float g = rgb.g; \n"
|
||||
"float b = rgb.b; \n"
|
||||
"#endif \n"
|
||||
"fs_color.rgb = texture(tonemapper, ScaleOffset(vec3(r, g, b), tSO)).rgb * rgb_premulalpha.a; \n"
|
||||
"fs_color.a = rgb_premulalpha.a; \n"
|
||||
"} \n"
|
||||
"} \n";
|
||||
@@ -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
|
||||
@@ -1,18 +0,0 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(LOCAL_PATH)/../common.mk
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE := hdmi_cec.$(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) libqservice libbinder libqdutils
|
||||
|
||||
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdhdmi_cec\" -Wno-sign-conversion
|
||||
LOCAL_CLANG := true
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
|
||||
LOCAL_SRC_FILES := qhdmi_cec.cpp \
|
||||
QHDMIClient.cpp
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 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 <QServiceUtils.h>
|
||||
#include "QHDMIClient.h"
|
||||
|
||||
using namespace android;
|
||||
using namespace qhdmicec;
|
||||
using namespace qService;
|
||||
|
||||
namespace qClient {
|
||||
|
||||
void QHDMIClient::binderDied(const wp<IBinder>& who __unused)
|
||||
{
|
||||
ALOGW("%s: Display QService died", __FUNCTION__);
|
||||
}
|
||||
|
||||
void QHDMIClient::onHdmiHotplug(int connected)
|
||||
{
|
||||
ALOGD("%s: HDMI connected event connected: %d", __FUNCTION__, connected);
|
||||
cec_hdmi_hotplug(mCtx, connected);
|
||||
}
|
||||
|
||||
void QHDMIClient::onCECMessageRecieved(char *msg, ssize_t len)
|
||||
{
|
||||
ALOGD_IF(DEBUG, "%s: CEC message received len: %zd", __FUNCTION__, len);
|
||||
cec_receive_message(mCtx, msg, len);
|
||||
}
|
||||
|
||||
void QHDMIClient::registerClient(sp<QHDMIClient>& client)
|
||||
{
|
||||
sp<IServiceManager> sm = defaultServiceManager();
|
||||
sp<IBinder> binder = sm->getService(String16("display.qservice"));
|
||||
binder->linkToDeath(client);
|
||||
mQService = interface_cast<IQService>(binder);
|
||||
mQService->connect(interface_cast<IQHDMIClient>(client));
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 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 "IQHDMIClient.h"
|
||||
#include "qhdmi_cec.h"
|
||||
#include <IQService.h>
|
||||
|
||||
namespace qClient {
|
||||
|
||||
class QHDMIClient: public android::IBinder::DeathRecipient,
|
||||
public BnQHDMIClient
|
||||
{
|
||||
public:
|
||||
QHDMIClient() {}
|
||||
|
||||
virtual void binderDied(const android::wp<android::IBinder>& who);
|
||||
|
||||
virtual void onHdmiHotplug(int connected);
|
||||
|
||||
virtual void onCECMessageRecieved(char *msg, ssize_t len);
|
||||
|
||||
void setCECContext(qhdmicec::cec_context_t* ctx) { mCtx = ctx; }
|
||||
|
||||
void registerClient(android::sp<QHDMIClient>& client);
|
||||
|
||||
private:
|
||||
qhdmicec::cec_context_t* mCtx;
|
||||
android::sp<qService::IQService> mQService;
|
||||
|
||||
};
|
||||
};
|
||||
@@ -1,520 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2016-2017, 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 <cstdlib>
|
||||
#include <log/log.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <hardware/hdmi_cec.h>
|
||||
#include <utils/Trace.h>
|
||||
#include "qhdmi_cec.h"
|
||||
#include "QHDMIClient.h"
|
||||
|
||||
namespace qhdmicec {
|
||||
|
||||
const int NUM_HDMI_PORTS = 1;
|
||||
const int MAX_SYSFS_DATA = 128;
|
||||
const int MAX_CEC_FRAME_SIZE = 20;
|
||||
const int MAX_SEND_MESSAGE_RETRIES = 1;
|
||||
|
||||
enum {
|
||||
LOGICAL_ADDRESS_SET = 1,
|
||||
LOGICAL_ADDRESS_UNSET = -1,
|
||||
};
|
||||
|
||||
// Offsets of members of struct hdmi_cec_msg
|
||||
// drivers/video/msm/mdss/mdss_hdmi_cec.c
|
||||
// XXX: Get this from a driver header
|
||||
enum {
|
||||
CEC_OFFSET_SENDER_ID,
|
||||
CEC_OFFSET_RECEIVER_ID,
|
||||
CEC_OFFSET_OPCODE,
|
||||
CEC_OFFSET_OPERAND,
|
||||
CEC_OFFSET_FRAME_LENGTH = 17,
|
||||
CEC_OFFSET_RETRANSMIT,
|
||||
};
|
||||
|
||||
//Forward declarations
|
||||
static void cec_close_context(cec_context_t* ctx __unused);
|
||||
static int cec_enable(cec_context_t *ctx, int enable);
|
||||
static int cec_is_connected(const struct hdmi_cec_device* dev, int port_id);
|
||||
|
||||
static ssize_t read_node(const char *path, char *data)
|
||||
{
|
||||
ssize_t err = 0;
|
||||
FILE *fp = NULL;
|
||||
err = access(path, R_OK);
|
||||
if (!err) {
|
||||
fp = fopen(path, "r");
|
||||
if (fp) {
|
||||
err = fread(data, sizeof(char), MAX_SYSFS_DATA ,fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static ssize_t write_node(const char *path, const char *data, size_t len)
|
||||
{
|
||||
ssize_t err = 0;
|
||||
int fd = -1;
|
||||
err = access(path, W_OK);
|
||||
if (!err) {
|
||||
fd = open(path, O_WRONLY);
|
||||
errno = 0;
|
||||
err = write(fd, data, len);
|
||||
if (err < 0) {
|
||||
err = -errno;
|
||||
}
|
||||
close(fd);
|
||||
} else {
|
||||
ALOGE("%s: Failed to access path: %s error: %s",
|
||||
__FUNCTION__, path, strerror(errno));
|
||||
err = -errno;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
// Helper function to write integer values to the full sysfs path
|
||||
static ssize_t write_int_to_node(cec_context_t *ctx,
|
||||
const char *path_postfix,
|
||||
const int value)
|
||||
{
|
||||
char sysfs_full_path[MAX_PATH_LENGTH];
|
||||
char sysfs_data[MAX_SYSFS_DATA];
|
||||
snprintf(sysfs_data, sizeof(sysfs_data), "%d",value);
|
||||
snprintf(sysfs_full_path,sizeof(sysfs_full_path), "%s/%s",
|
||||
ctx->fb_sysfs_path, path_postfix);
|
||||
ssize_t err = write_node(sysfs_full_path, sysfs_data, strlen(sysfs_data));
|
||||
return err;
|
||||
}
|
||||
|
||||
static void hex_to_string(const char *msg, ssize_t len, char *str)
|
||||
{
|
||||
//Functions assumes sufficient memory in str
|
||||
char *ptr = str;
|
||||
for(int i=0; i < len ; i++) {
|
||||
ptr += snprintf(ptr, 3, "%02X", msg[i]);
|
||||
// Overwrite null termination of snprintf in all except the last byte
|
||||
if (i < len - 1)
|
||||
*ptr = ':';
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t cec_get_fb_node_number(cec_context_t *ctx)
|
||||
{
|
||||
//XXX: Do this from a common utility library across the display HALs
|
||||
const int MAX_FB_DEVICES = 2;
|
||||
ssize_t len = 0;
|
||||
char fb_type_path[MAX_PATH_LENGTH];
|
||||
char fb_type[MAX_SYSFS_DATA];
|
||||
const char *dtv_panel_str = "dtv panel";
|
||||
|
||||
for(int num = 0; num < MAX_FB_DEVICES; num++) {
|
||||
snprintf(fb_type_path, sizeof(fb_type_path),"%s%d/msm_fb_type",
|
||||
SYSFS_BASE,num);
|
||||
ALOGD_IF(DEBUG, "%s: num: %d fb_type_path: %s", __FUNCTION__, num, fb_type_path);
|
||||
len = read_node(fb_type_path, fb_type);
|
||||
ALOGD_IF(DEBUG, "%s: fb_type:%s", __FUNCTION__, fb_type);
|
||||
if(len > 0 && (strncmp(fb_type, dtv_panel_str, strlen(dtv_panel_str)) == 0)){
|
||||
ALOGD_IF(DEBUG, "%s: Found DTV panel at fb%d", __FUNCTION__, num);
|
||||
ctx->fb_num = num;
|
||||
snprintf(ctx->fb_sysfs_path, sizeof(ctx->fb_sysfs_path),
|
||||
"%s%d", SYSFS_BASE, num);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (len < 0)
|
||||
return len;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cec_add_logical_address(const struct hdmi_cec_device* dev,
|
||||
cec_logical_address_t addr)
|
||||
{
|
||||
if (addr < CEC_ADDR_TV || addr > CEC_ADDR_BROADCAST) {
|
||||
ALOGE("%s: Received invalid address: %d ", __FUNCTION__, addr);
|
||||
return -EINVAL;
|
||||
}
|
||||
cec_context_t* ctx = (cec_context_t*)(dev);
|
||||
ctx->logical_address[addr] = LOGICAL_ADDRESS_SET;
|
||||
|
||||
//XXX: We can get multiple logical addresses here but we can only send one
|
||||
//to the driver. Store locally for now
|
||||
ssize_t err = write_int_to_node(ctx, "cec/logical_addr", addr);
|
||||
ALOGI("%s: Allocated logical address: %d ", __FUNCTION__, addr);
|
||||
return (int) err;
|
||||
}
|
||||
|
||||
static void cec_clear_logical_address(const struct hdmi_cec_device* dev)
|
||||
{
|
||||
cec_context_t* ctx = (cec_context_t*)(dev);
|
||||
memset(ctx->logical_address, LOGICAL_ADDRESS_UNSET,
|
||||
sizeof(ctx->logical_address));
|
||||
//XXX: Find logical_addr that needs to be reset
|
||||
write_int_to_node(ctx, "cec/logical_addr", 15);
|
||||
ALOGD_IF(DEBUG, "%s: Cleared logical addresses", __FUNCTION__);
|
||||
}
|
||||
|
||||
static int cec_get_physical_address(const struct hdmi_cec_device* dev,
|
||||
uint16_t* addr)
|
||||
{
|
||||
cec_context_t* ctx = (cec_context_t*)(dev);
|
||||
char pa_path[MAX_PATH_LENGTH];
|
||||
char pa_data[MAX_SYSFS_DATA];
|
||||
snprintf (pa_path, sizeof(pa_path),"%s/pa",
|
||||
ctx->fb_sysfs_path);
|
||||
int err = (int) read_node(pa_path, pa_data);
|
||||
*addr = (uint16_t) atoi(pa_data);
|
||||
ALOGD_IF(DEBUG, "%s: Physical Address: 0x%x", __FUNCTION__, *addr);
|
||||
if (err < 0)
|
||||
return err;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cec_send_message(const struct hdmi_cec_device* dev,
|
||||
const cec_message_t* msg)
|
||||
{
|
||||
ATRACE_CALL();
|
||||
if(cec_is_connected(dev, 0) <= 0)
|
||||
return HDMI_RESULT_FAIL;
|
||||
|
||||
cec_context_t* ctx = (cec_context_t*)(dev);
|
||||
ALOGD_IF(DEBUG, "%s: initiator: %d destination: %d length: %u",
|
||||
__FUNCTION__, msg->initiator, msg->destination,
|
||||
(uint32_t) msg->length);
|
||||
|
||||
// Dump message received from framework
|
||||
char dump[128];
|
||||
if(msg->length > 0) {
|
||||
hex_to_string((char*)msg->body, msg->length, dump);
|
||||
ALOGD_IF(DEBUG, "%s: message from framework: %s", __FUNCTION__, dump);
|
||||
}
|
||||
|
||||
char write_msg_path[MAX_PATH_LENGTH];
|
||||
char write_msg[MAX_CEC_FRAME_SIZE];
|
||||
memset(write_msg, 0, sizeof(write_msg));
|
||||
// See definition of struct hdmi_cec_msg in driver code
|
||||
// drivers/video/msm/mdss/mdss_hdmi_cec.c
|
||||
// Write header block
|
||||
// XXX: Include this from header in kernel
|
||||
write_msg[CEC_OFFSET_SENDER_ID] = msg->initiator;
|
||||
write_msg[CEC_OFFSET_RECEIVER_ID] = msg->destination;
|
||||
//Kernel splits opcode/operand, but Android sends it in one byte array
|
||||
write_msg[CEC_OFFSET_OPCODE] = msg->body[0];
|
||||
if(msg->length > 1) {
|
||||
memcpy(&write_msg[CEC_OFFSET_OPERAND], &msg->body[1],
|
||||
sizeof(char)*(msg->length - 1));
|
||||
}
|
||||
//msg length + initiator + destination
|
||||
write_msg[CEC_OFFSET_FRAME_LENGTH] = (unsigned char) (msg->length + 1);
|
||||
hex_to_string(write_msg, sizeof(write_msg), dump);
|
||||
ALOGD_IF(DEBUG, "%s: message to driver: %s", __FUNCTION__, dump);
|
||||
snprintf(write_msg_path, sizeof(write_msg_path), "%s/cec/wr_msg",
|
||||
ctx->fb_sysfs_path);
|
||||
int retry_count = 0;
|
||||
ssize_t err = 0;
|
||||
//HAL spec requires us to retry at least once.
|
||||
while (true) {
|
||||
err = write_node(write_msg_path, write_msg, sizeof(write_msg));
|
||||
retry_count++;
|
||||
if (err == -EAGAIN && retry_count <= MAX_SEND_MESSAGE_RETRIES) {
|
||||
ALOGE("%s: CEC line busy, retrying", __FUNCTION__);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (err < 0) {
|
||||
if (err == -ENXIO) {
|
||||
ALOGI("%s: No device exists with the destination address",
|
||||
__FUNCTION__);
|
||||
return HDMI_RESULT_NACK;
|
||||
} else if (err == -EAGAIN) {
|
||||
ALOGE("%s: CEC line is busy, max retry count exceeded",
|
||||
__FUNCTION__);
|
||||
return HDMI_RESULT_BUSY;
|
||||
} else {
|
||||
return HDMI_RESULT_FAIL;
|
||||
ALOGE("%s: Failed to send CEC message err: %zd - %s",
|
||||
__FUNCTION__, err, strerror(int(-err)));
|
||||
}
|
||||
} else {
|
||||
ALOGD_IF(DEBUG, "%s: Sent CEC message - %zd bytes written",
|
||||
__FUNCTION__, err);
|
||||
return HDMI_RESULT_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
void cec_receive_message(cec_context_t *ctx, char *msg, ssize_t len)
|
||||
{
|
||||
if(!ctx->system_control)
|
||||
return;
|
||||
|
||||
char dump[128];
|
||||
if(len > 0) {
|
||||
hex_to_string(msg, len, dump);
|
||||
ALOGD_IF(DEBUG, "%s: Message from driver: %s", __FUNCTION__, dump);
|
||||
}
|
||||
|
||||
hdmi_event_t event;
|
||||
event.type = HDMI_EVENT_CEC_MESSAGE;
|
||||
event.dev = (hdmi_cec_device *) ctx;
|
||||
// Remove initiator/destination from this calculation
|
||||
event.cec.length = msg[CEC_OFFSET_FRAME_LENGTH] - 1;
|
||||
event.cec.initiator = (cec_logical_address_t) msg[CEC_OFFSET_SENDER_ID];
|
||||
event.cec.destination = (cec_logical_address_t) msg[CEC_OFFSET_RECEIVER_ID];
|
||||
//Copy opcode and operand
|
||||
size_t copy_size = event.cec.length > sizeof(event.cec.body) ?
|
||||
sizeof(event.cec.body) : event.cec.length;
|
||||
memcpy(event.cec.body, &msg[CEC_OFFSET_OPCODE],copy_size);
|
||||
hex_to_string((char *) event.cec.body, copy_size, dump);
|
||||
ALOGD_IF(DEBUG, "%s: Message to framework: %s", __FUNCTION__, dump);
|
||||
ctx->callback.callback_func(&event, ctx->callback.callback_arg);
|
||||
}
|
||||
|
||||
void cec_hdmi_hotplug(cec_context_t *ctx, int connected)
|
||||
{
|
||||
//Ignore unplug events when system control is disabled
|
||||
if(!ctx->system_control && connected == 0)
|
||||
return;
|
||||
hdmi_event_t event;
|
||||
event.type = HDMI_EVENT_HOT_PLUG;
|
||||
event.dev = (hdmi_cec_device *) ctx;
|
||||
event.hotplug.connected = connected ? HDMI_CONNECTED : HDMI_NOT_CONNECTED;
|
||||
ctx->callback.callback_func(&event, ctx->callback.callback_arg);
|
||||
}
|
||||
|
||||
static void cec_register_event_callback(const struct hdmi_cec_device* dev,
|
||||
event_callback_t callback, void* arg)
|
||||
{
|
||||
ALOGD_IF(DEBUG, "%s: Registering callback", __FUNCTION__);
|
||||
cec_context_t* ctx = (cec_context_t*)(dev);
|
||||
ctx->callback.callback_func = callback;
|
||||
ctx->callback.callback_arg = arg;
|
||||
}
|
||||
|
||||
static void cec_get_version(const struct hdmi_cec_device* dev, int* version)
|
||||
{
|
||||
cec_context_t* ctx = (cec_context_t*)(dev);
|
||||
*version = ctx->version;
|
||||
ALOGD_IF(DEBUG, "%s: version: %d", __FUNCTION__, *version);
|
||||
}
|
||||
|
||||
static void cec_get_vendor_id(const struct hdmi_cec_device* dev,
|
||||
uint32_t* vendor_id)
|
||||
{
|
||||
cec_context_t* ctx = (cec_context_t*)(dev);
|
||||
*vendor_id = ctx->vendor_id;
|
||||
ALOGD_IF(DEBUG, "%s: vendor id: %u", __FUNCTION__, *vendor_id);
|
||||
}
|
||||
|
||||
static void cec_get_port_info(const struct hdmi_cec_device* dev,
|
||||
struct hdmi_port_info* list[], int* total)
|
||||
{
|
||||
ALOGD_IF(DEBUG, "%s: Get port info", __FUNCTION__);
|
||||
cec_context_t* ctx = (cec_context_t*)(dev);
|
||||
*total = NUM_HDMI_PORTS;
|
||||
*list = ctx->port_info;
|
||||
}
|
||||
|
||||
static void cec_set_option(const struct hdmi_cec_device* dev, int flag,
|
||||
int value)
|
||||
{
|
||||
cec_context_t* ctx = (cec_context_t*)(dev);
|
||||
switch (flag) {
|
||||
case HDMI_OPTION_WAKEUP:
|
||||
ALOGD_IF(DEBUG, "%s: Wakeup: value: %d", __FUNCTION__, value);
|
||||
//XXX
|
||||
break;
|
||||
case HDMI_OPTION_ENABLE_CEC:
|
||||
ALOGD_IF(DEBUG, "%s: Enable CEC: value: %d", __FUNCTION__, value);
|
||||
cec_enable(ctx, value? 1 : 0);
|
||||
break;
|
||||
case HDMI_OPTION_SYSTEM_CEC_CONTROL:
|
||||
ALOGD_IF(DEBUG, "%s: system_control: value: %d",
|
||||
__FUNCTION__, value);
|
||||
ctx->system_control = !!value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void cec_set_audio_return_channel(const struct hdmi_cec_device* dev,
|
||||
int port, int flag)
|
||||
{
|
||||
cec_context_t* ctx = (cec_context_t*)(dev);
|
||||
ctx->arc_enabled = flag ? true : false;
|
||||
ALOGD_IF(DEBUG, "%s: ARC flag: %d port: %d", __FUNCTION__, flag, port);
|
||||
}
|
||||
|
||||
static int cec_is_connected(const struct hdmi_cec_device* dev, int port_id)
|
||||
{
|
||||
// Ignore port_id since we have only one port
|
||||
int connected = 0;
|
||||
cec_context_t* ctx = (cec_context_t*)(dev);
|
||||
char connected_path[MAX_PATH_LENGTH];
|
||||
char connected_data[MAX_SYSFS_DATA];
|
||||
snprintf (connected_path, sizeof(connected_path),"%s/connected",
|
||||
ctx->fb_sysfs_path);
|
||||
ssize_t err = read_node(connected_path, connected_data);
|
||||
connected = atoi(connected_data);
|
||||
|
||||
ALOGD_IF(DEBUG, "%s: HDMI at port %d is - %s", __FUNCTION__, port_id,
|
||||
connected ? "connected":"disconnected");
|
||||
if (err < 0)
|
||||
return (int) err;
|
||||
else
|
||||
return connected;
|
||||
}
|
||||
|
||||
static int cec_device_close(struct hw_device_t *dev)
|
||||
{
|
||||
ALOGD_IF(DEBUG, "%s: Close CEC HAL ", __FUNCTION__);
|
||||
if (!dev) {
|
||||
ALOGE("%s: NULL device pointer", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
cec_context_t* ctx = (cec_context_t*)(dev);
|
||||
cec_close_context(ctx);
|
||||
free(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cec_enable(cec_context_t *ctx, int enable)
|
||||
{
|
||||
ssize_t err;
|
||||
// Enable CEC
|
||||
int value = enable ? 0x3 : 0x0;
|
||||
err = write_int_to_node(ctx, "cec/enable", value);
|
||||
if(err < 0) {
|
||||
ALOGE("%s: Failed to toggle CEC: enable: %d",
|
||||
__FUNCTION__, enable);
|
||||
return (int) err;
|
||||
}
|
||||
ctx->enabled = enable;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cec_init_context(cec_context_t *ctx)
|
||||
{
|
||||
ALOGD_IF(DEBUG, "%s: Initializing context", __FUNCTION__);
|
||||
cec_get_fb_node_number(ctx);
|
||||
|
||||
//Initialize ports - We support only one output port
|
||||
ctx->port_info = new hdmi_port_info[NUM_HDMI_PORTS];
|
||||
ctx->port_info[0].type = HDMI_OUTPUT;
|
||||
ctx->port_info[0].port_id = 1;
|
||||
ctx->port_info[0].cec_supported = 1;
|
||||
//XXX: Enable ARC if supported
|
||||
ctx->port_info[0].arc_supported = 0;
|
||||
cec_get_physical_address((hdmi_cec_device *) ctx,
|
||||
&ctx->port_info[0].physical_address );
|
||||
|
||||
ctx->version = 0x4;
|
||||
ctx->vendor_id = 0xA47733;
|
||||
cec_clear_logical_address((hdmi_cec_device_t*)ctx);
|
||||
|
||||
//Set up listener for HDMI events
|
||||
ctx->disp_client = new qClient::QHDMIClient();
|
||||
ctx->disp_client->setCECContext(ctx);
|
||||
ctx->disp_client->registerClient(ctx->disp_client);
|
||||
|
||||
//Enable CEC - framework expects it to be enabled by default
|
||||
cec_enable(ctx, true);
|
||||
|
||||
ALOGD("%s: CEC enabled", __FUNCTION__);
|
||||
}
|
||||
|
||||
static void cec_close_context(cec_context_t* ctx __unused)
|
||||
{
|
||||
ALOGD("%s: Closing context", __FUNCTION__);
|
||||
}
|
||||
|
||||
static int cec_device_open(const struct hw_module_t* module,
|
||||
const char* name,
|
||||
struct hw_device_t** device)
|
||||
{
|
||||
ALOGD_IF(DEBUG, "%s: name: %s", __FUNCTION__, name);
|
||||
int status = -EINVAL;
|
||||
if (!strcmp(name, HDMI_CEC_HARDWARE_INTERFACE )) {
|
||||
struct cec_context_t *dev;
|
||||
dev = (cec_context_t *) calloc (1, sizeof(*dev));
|
||||
if (dev) {
|
||||
cec_init_context(dev);
|
||||
|
||||
//Setup CEC methods
|
||||
dev->device.common.tag = HARDWARE_DEVICE_TAG;
|
||||
dev->device.common.version = HDMI_CEC_DEVICE_API_VERSION_1_0;
|
||||
dev->device.common.module = const_cast<hw_module_t* >(module);
|
||||
dev->device.common.close = cec_device_close;
|
||||
dev->device.add_logical_address = cec_add_logical_address;
|
||||
dev->device.clear_logical_address = cec_clear_logical_address;
|
||||
dev->device.get_physical_address = cec_get_physical_address;
|
||||
dev->device.send_message = cec_send_message;
|
||||
dev->device.register_event_callback = cec_register_event_callback;
|
||||
dev->device.get_version = cec_get_version;
|
||||
dev->device.get_vendor_id = cec_get_vendor_id;
|
||||
dev->device.get_port_info = cec_get_port_info;
|
||||
dev->device.set_option = cec_set_option;
|
||||
dev->device.set_audio_return_channel = cec_set_audio_return_channel;
|
||||
dev->device.is_connected = cec_is_connected;
|
||||
|
||||
*device = &dev->device.common;
|
||||
status = 0;
|
||||
} else {
|
||||
status = -EINVAL;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
}; //namespace qhdmicec
|
||||
|
||||
// Standard HAL module, should be outside qhdmicec namespace
|
||||
static struct hw_module_methods_t cec_module_methods = {
|
||||
.open = qhdmicec::cec_device_open
|
||||
};
|
||||
|
||||
hdmi_module_t HAL_MODULE_INFO_SYM = {
|
||||
.common = {
|
||||
.tag = HARDWARE_MODULE_TAG,
|
||||
.version_major = 1,
|
||||
.version_minor = 0,
|
||||
.id = HDMI_CEC_HARDWARE_MODULE_ID,
|
||||
.name = "QTI HDMI CEC module",
|
||||
.author = "The Linux Foundation",
|
||||
.methods = &cec_module_methods,
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 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 QHDMI_CEC_H
|
||||
#define QHDMI_CEC_H
|
||||
|
||||
#include <hardware/hdmi_cec.h>
|
||||
#include <utils/RefBase.h>
|
||||
|
||||
namespace qClient {
|
||||
class QHDMIClient;
|
||||
};
|
||||
|
||||
namespace qhdmicec {
|
||||
|
||||
#define SYSFS_BASE "/sys/class/graphics/fb"
|
||||
#define MAX_PATH_LENGTH 128
|
||||
|
||||
struct cec_callback_t {
|
||||
// Function in HDMI service to call back on CEC messages
|
||||
event_callback_t callback_func;
|
||||
// This stores the object to pass back to the framework
|
||||
void* callback_arg;
|
||||
|
||||
};
|
||||
|
||||
struct cec_context_t {
|
||||
hdmi_cec_device_t device; // Device for HW module
|
||||
cec_callback_t callback; // Struct storing callback object
|
||||
bool enabled;
|
||||
bool arc_enabled;
|
||||
bool system_control; // If true, HAL/driver handle CEC messages
|
||||
int fb_num; // Framebuffer node for HDMI
|
||||
char fb_sysfs_path[MAX_PATH_LENGTH];
|
||||
hdmi_port_info *port_info; // HDMI port info
|
||||
|
||||
// Logical address is stored in an array, the index of the array is the
|
||||
// logical address and the value in the index shows whether it is set or not
|
||||
int logical_address[CEC_ADDR_BROADCAST];
|
||||
int version;
|
||||
uint32_t vendor_id;
|
||||
android::sp<qClient::QHDMIClient> disp_client;
|
||||
};
|
||||
|
||||
void cec_receive_message(cec_context_t *ctx, char *msg, ssize_t len);
|
||||
void cec_hdmi_hotplug(cec_context_t *ctx, int connected);
|
||||
|
||||
}; //namespace
|
||||
#endif /* end of include guard: QHDMI_CEC_H */
|
||||
@@ -1,21 +0,0 @@
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
include $(LOCAL_PATH)/../common.mk
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
# Legacy header copy. This is deprecated.
|
||||
# Modules using these headers should shift to using
|
||||
# LOCAL_HEADER_LIBRARIES := display_headers
|
||||
LOCAL_VENDOR_MODULE := true
|
||||
LOCAL_COPY_HEADERS_TO := $(common_header_export_path)
|
||||
LOCAL_COPY_HEADERS := color_metadata.h \
|
||||
display_properties.h \
|
||||
../libqdutils/qd_utils.h \
|
||||
../libqdutils/qdMetaData.h \
|
||||
../libqdutils/display_config.h \
|
||||
../libdebug/debug_handler.h \
|
||||
../libqservice/QServiceUtils.h \
|
||||
../libqservice/IQService.h \
|
||||
../libqservice/IQHDMIClient.h \
|
||||
../libqservice/IQClient.h
|
||||
|
||||
include $(BUILD_COPY_HEADERS)
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
|
||||
* 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:
|
||||
@@ -33,8 +33,9 @@ extern "C" {
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum ColorRange {
|
||||
Range_Limited = 0,
|
||||
Range_Full = 1,
|
||||
Range_Limited = 0,
|
||||
Range_Full = 1,
|
||||
Range_Extended = 2,
|
||||
Range_Max = 0xff,
|
||||
} ColorRange;
|
||||
|
||||
|
||||
@@ -1,100 +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 __DISPLAY_PROPERTIES_H__
|
||||
#define __DISPLAY_PROPERTIES_H__
|
||||
|
||||
#define DISP_PROP_PREFIX "vendor.display."
|
||||
#define GRALLOC_PROP_PREFIX "vendor.gralloc."
|
||||
#define RO_DISP_PROP_PREFIX "ro.vendor.display."
|
||||
#define PERSIST_DISP_PROP_PREFIX "persist.vendor.display."
|
||||
|
||||
#define DISPLAY_PROP(prop_name) DISP_PROP_PREFIX prop_name
|
||||
#define GRALLOC_PROP(prop_name) GRALLOC_PROP_PREFIX prop_name
|
||||
#define RO_DISPLAY_PROP(prop_name) RO_DISP_PROP_PREFIX prop_name
|
||||
#define PERSIST_DISPLAY_PROP(prop_name) PERSIST_DISP_PROP_PREFIX prop_name
|
||||
|
||||
#define COMPOSITION_MASK_PROP DISPLAY_PROP("comp_mask")
|
||||
#define HDMI_CONFIG_INDEX_PROP DISPLAY_PROP("hdmi_cfg_idx")
|
||||
#define IDLE_TIME_PROP DISPLAY_PROP("idle_time")
|
||||
#define IDLE_TIME_INACTIVE_PROP DISPLAY_PROP("idle_time_inactive")
|
||||
#define BOOT_ANIMATION_LAYER_COUNT_PROP DISPLAY_PROP("boot_anim_layer_count")
|
||||
#define DISABLE_ROTATOR_DOWNSCALE_PROP DISPLAY_PROP("disable_rotator_downscale")
|
||||
#define DISABLE_DECIMATION_PROP DISPLAY_PROP("disable_decimation")
|
||||
#define PRIMARY_MIXER_STAGES_PROP DISPLAY_PROP("primary_mixer_stages")
|
||||
#define EXTERNAL_MIXER_STAGES_PROP DISPLAY_PROP("external_mixer_stages")
|
||||
#define VIRTUAL_MIXER_STAGES_PROP DISPLAY_PROP("virtual_mixer_stages")
|
||||
#define MAX_UPSCALE_PROP DISPLAY_PROP("max_upscale")
|
||||
#define VIDEO_MODE_PANEL_PROP DISPLAY_PROP("video_mode_panel")
|
||||
#define DISABLE_ROTATOR_UBWC_PROP DISPLAY_PROP("disable_rotator_ubwc")
|
||||
#define DISABLE_ROTATOR_SPLIT_PROP DISPLAY_PROP("disable_rotator_split")
|
||||
#define DISABLE_SCALER_PROP DISPLAY_PROP("disable_scaler")
|
||||
#define DISABLE_AVR_PROP DISPLAY_PROP("disable_avr")
|
||||
#define DISABLE_EXTERNAL_ANIMATION_PROP DISPLAY_PROP("disable_ext_anim")
|
||||
#define DISABLE_PARTIAL_SPLIT_PROP DISPLAY_PROP("disable_partial_split")
|
||||
#define PREFER_SOURCE_SPLIT_PROP DISPLAY_PROP("prefer_source_split")
|
||||
#define MIXER_RESOLUTION_PROP DISPLAY_PROP("mixer_resolution")
|
||||
#define SIMULATED_CONFIG_PROP DISPLAY_PROP("simulated_config")
|
||||
#define MAX_EXTERNAL_LAYERS_PROP DISPLAY_PROP("max_external_layers")
|
||||
#define PERF_HINT_WINDOW_PROP DISPLAY_PROP("perf_hint_window")
|
||||
#define ENABLE_EXTERNAL_DOWNSCALE_PROP DISPLAY_PROP("enable_external_downscale")
|
||||
#define EXTERNAL_ACTION_SAFE_WIDTH_PROP DISPLAY_PROP("external_action_safe_width")
|
||||
#define EXTERNAL_ACTION_SAFE_HEIGHT_PROP DISPLAY_PROP("external_action_safe_height")
|
||||
#define FB_WIDTH_PROP DISPLAY_PROP("fb_width")
|
||||
#define FB_HEIGHT_PROP DISPLAY_PROP("fb_height")
|
||||
#define DISABLE_METADATA_DYNAMIC_FPS_PROP DISPLAY_PROP("disable_metadata_dynamic_fps")
|
||||
#define DISABLE_BLIT_COMPOSITION_PROP DISPLAY_PROP("disable_blit_comp")
|
||||
#define DISABLE_SKIP_VALIDATE_PROP DISPLAY_PROP("disable_skip_validate")
|
||||
#define HDMI_S3D_MODE_PROP DISPLAY_PROP("hdmi_s3d_mode")
|
||||
#define DISABLE_DESTINATION_SCALER_PROP DISPLAY_PROP("disable_dest_scaler")
|
||||
#define ENABLE_PARTIAL_UPDATE_PROP DISPLAY_PROP("enable_partial_update")
|
||||
#define DISABLE_UBWC_PROP GRALLOC_PROP("disable_ubwc")
|
||||
#define ENABLE_FB_UBWC_PROP GRALLOC_PROP("enable_fb_ubwc")
|
||||
#define MAP_FB_MEMORY_PROP GRALLOC_PROP("map_fb_memory")
|
||||
|
||||
#define MAX_BLIT_FACTOR_PROP DISPLAY_PROP("max_blit_factor")
|
||||
#define DISABLE_SECURE_INLINE_ROTATOR_PROP DISPLAY_PROP("disable_secure_inline_rotator")
|
||||
#define DISABLE_MULTIRECT_PROP DISPLAY_PROP("disable_multirect")
|
||||
#define DISABLE_UBWC_FF_VOTING_PROP DISPLAY_PROP("disable_ubwc_ff_voting")
|
||||
#define DISABLE_INLINE_ROTATOR_PROP DISPLAY_PROP("disable_inline_rotator")
|
||||
#define DISABLE_FB_CROPPING_PROP DISPLAY_PROP("disable_fb_cropping")
|
||||
#define PRIORITIZE_CACHE_COMPOSITION_PROP DISPLAY_PROP("prioritize_cache_comp")
|
||||
|
||||
#define DISABLE_HDR_LUT_GEN DISPLAY_PROP("disable_hdr_lut_gen")
|
||||
#define ENABLE_DEFAULT_COLOR_MODE DISPLAY_PROP("enable_default_color_mode")
|
||||
#define DISABLE_HDR DISPLAY_PROP("hwc_disable_hdr")
|
||||
|
||||
#define HDR_CONFIG_PROP RO_DISPLAY_PROP("hdr.config")
|
||||
#define QDCM_PCC_TRANS_PROP DISPLAY_PROP("qdcm.pcc_for_trans")
|
||||
#define QDCM_DIAGONAL_MATRIXMODE_PROP DISPLAY_PROP("qdcm.diagonal_matrix_mode")
|
||||
#define QDCM_DISABLE_TIMEOUT_PROP PERSIST_DISPLAY_PROP("qdcm.disable_timeout")
|
||||
|
||||
#define ZERO_SWAP_INTERVAL "vendor.debug.egl.swapinterval"
|
||||
|
||||
#endif // __DISPLAY_PROPERTIES_H__
|
||||
@@ -1,23 +0,0 @@
|
||||
# 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.
|
||||
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
include $(LOCAL_PATH)/../common.mk
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_VENDOR_MODULE := true
|
||||
LOCAL_COPY_HEADERS_TO := $(common_header_export_path)
|
||||
LOCAL_COPY_HEADERS := copybit.h copybit_priv.h c2d2.h
|
||||
#Copy the headers regardless of whether copybit is built
|
||||
include $(BUILD_COPY_HEADERS)
|
||||
@@ -1,189 +0,0 @@
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
@@ -1,685 +0,0 @@
|
||||
/* Copyright (c) 2010-2013, 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 __c2d2_h_
|
||||
#define __c2d2_h_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef C2D_API
|
||||
#define C2D_API /* define API export as needed */
|
||||
#endif
|
||||
#if !defined(int32) && !defined(_INT32_DEFINED)
|
||||
typedef int int32;
|
||||
#define _INT32_DEFINED
|
||||
#endif
|
||||
#if !defined(uint32) && !defined(_UINT32_DEFINED)
|
||||
typedef unsigned int uint32;
|
||||
#define _UINT32_DEFINED
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/*********************** Blit definitions *****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
/* Status codes, returned by any blit function */
|
||||
typedef enum {
|
||||
C2D_STATUS_OK = 0,
|
||||
C2D_STATUS_NOT_SUPPORTED = 1,
|
||||
C2D_STATUS_OUT_OF_MEMORY = 2,
|
||||
C2D_STATUS_INVALID_PARAM = 3,
|
||||
C2D_STATUS_SURFACE_IN_USE = 4,
|
||||
} C2D_STATUS;
|
||||
|
||||
|
||||
/* Definitions of color format modes, used together with color formats */
|
||||
typedef enum {
|
||||
C2D_FORMAT_PACK_INTO_32BIT = (1 << 8), /* pack into dword if set */
|
||||
C2D_FORMAT_SWAP_ENDIANNESS = (1 << 9), /* swaps the order */
|
||||
C2D_FORMAT_LINEAR_SPACE = (1 << 10), /* linear color space */
|
||||
C2D_FORMAT_PREMULTIPLIED = (1 << 11), /* alpha premultiplied */
|
||||
C2D_FORMAT_INVERT_ALPHA = (1 << 12), /* inverts alpha */
|
||||
C2D_FORMAT_DISABLE_ALPHA = (1 << 13), /* disables alpha */
|
||||
C2D_FORMAT_INTERLACED = (1 << 14), /* YUV line-interlaced */
|
||||
C2D_FORMAT_TRANSPARENT = (1 << 15), /* YUV 1-bit alpha in Y */
|
||||
C2D_FORMAT_MACROTILED = (1 << 16), /* tiled in macro level */
|
||||
C2D_FORMAT_TILED_4x4 = (1 << 17), /* 4x4 tiled format */
|
||||
C2D_FORMAT_SWAP_RB = (1 << 18), /* Swap R & B color components */
|
||||
C2D_FORMAT_UBWC_COMPRESSED = (1 << 23), /* UBWC compressed format */
|
||||
} C2D_FORMAT_MODE;
|
||||
|
||||
/* Definitions of supported RGB formats, used in C2D_RGB_SURFACE_DEF.
|
||||
* The bits of each color channel are packed into a machine word
|
||||
* representing a single pixel from left to right (MSB to LSB) in the
|
||||
* order indicated by format name. For the sub-byte formats the pixels
|
||||
* are packed into bytes from left to right (MSbit to LSBit).
|
||||
* If the C2D_FORMAT_PACK_INTO_32BIT bit is set, the minimal
|
||||
* machine word used for pixel storage is 32-bit and the whole word
|
||||
* is reversed if endianness is swapped.
|
||||
* If the C2D_FORMAT_SWAP_ENDIANNESS bit is set, the order within a
|
||||
* minimal machine word representing a pixel
|
||||
* is reversed for both sub-byte and multi-byte formats.
|
||||
* If the C2D_FORMAT_LINEAR_SPACE bit is set, the color space of
|
||||
* the formats below is considered linear, if applicable.
|
||||
* If the C2D_FORMAT_PREMULTIPLIED bit is set, the color channels
|
||||
* are premultiplied with the alpha, if applicable.
|
||||
* If the C2D_FORMAT_INVERT_ALPHA bit is set, the alpha interpretation
|
||||
* is inverted: 0 - opaque, 1 - transparent, if applicable.
|
||||
* If the C2D_FORMAT_DISABLE_ALPHA bit is set, the alpha channel serves
|
||||
* as a placeholder and is ignored during blit, if applicable.
|
||||
* If the C2D_FORMAT_MACROTILED bit is set, the surface is in the
|
||||
* tiled format : 64x32 for 8bpp, 32x32 for 16bpp formats */
|
||||
typedef enum {
|
||||
C2D_COLOR_FORMAT_1 = 0, /* 1-bit alpha/color expansion */
|
||||
|
||||
C2D_COLOR_FORMAT_2_PALETTE = 1, /* 2-bit indices for palette */
|
||||
C2D_COLOR_FORMAT_4_PALETTE = 2, /* 4-bit indices for palette */
|
||||
C2D_COLOR_FORMAT_8_PALETTE = 3, /* 8-bit indices for palette */
|
||||
|
||||
C2D_COLOR_FORMAT_2_L = 4, /* 2-bit grayscale */
|
||||
C2D_COLOR_FORMAT_4_L = 5, /* 4-bit grayscale */
|
||||
C2D_COLOR_FORMAT_8_L = 6, /* 8-bit grayscale */
|
||||
|
||||
C2D_COLOR_FORMAT_2_A = 7, /* 2-bit alpha only */
|
||||
C2D_COLOR_FORMAT_4_A = 8, /* 4-bit alpha only */
|
||||
C2D_COLOR_FORMAT_8_A = 9, /* 8-bit alpha only */
|
||||
|
||||
C2D_COLOR_FORMAT_444_RGB = 10, /* 12-bit colors */
|
||||
C2D_COLOR_FORMAT_565_RGB = 11, /* 16-bit colors */
|
||||
C2D_COLOR_FORMAT_888_RGB = 12, /* 24-bit colors */
|
||||
|
||||
C2D_COLOR_FORMAT_1555_ARGB = 13, /* 16-bit colors (1-bit alpha) */
|
||||
C2D_COLOR_FORMAT_4444_ARGB = 14, /* 16-bit colors (4-bit alpha) */
|
||||
C2D_COLOR_FORMAT_8565_ARGB = 15, /* 24-bit colors (8-bit alpha) */
|
||||
C2D_COLOR_FORMAT_8888_ARGB = 16, /* 32-bit colors (8-bit alpha) */
|
||||
|
||||
C2D_COLOR_FORMAT_5551_RGBA = 17, /* 16-bit colors (1-bit alpha) */
|
||||
C2D_COLOR_FORMAT_4444_RGBA = 18, /* 16-bit colors (4-bit alpha) */
|
||||
C2D_COLOR_FORMAT_5658_RGBA = 19, /* 24-bit colors (8-bit alpha) */
|
||||
C2D_COLOR_FORMAT_8888_RGBA = 20, /* 32-bit colors (8-bit alpha) */
|
||||
|
||||
/* derived RGB color formats (base format + mode bits) */
|
||||
|
||||
} C2D_RGB_FORMAT;
|
||||
|
||||
/* Definitions of supported YUV formats, used in C2D_YUV_SURFACE_DEF.
|
||||
* Each of Y,U,V channels usually takes 1 byte and therefore is
|
||||
* individually addressable. The definitions below show how Y,U,V
|
||||
* channels are packed into macropixels for each particular format.
|
||||
* The order is from left (smaller byte addresses) to right (larger
|
||||
* byte addresses). The first three digits (4xx) denote the chroma
|
||||
* subsampling in standard YUV notation. The digits in the macropixel
|
||||
* denote that the whole block (from the previous digit or from the
|
||||
* beginning) has to be repeated the number of times. Underscores
|
||||
* between Y,U,V channels are used to describe separate planes for
|
||||
* planar YUV formats. Formats are mapped to numbers so that future
|
||||
* versions with various YUV permutations are easy to add.
|
||||
* If the C2D_FORMAT_INTERLACED bit is set, the line order is
|
||||
* interlaced: 0,2,4,...1,3,5... if applicable.
|
||||
* If the C2D_FORMAT_TRANSPARENT bit is set, the least significant
|
||||
* bit of Y channel serves as alpha: 0 - transparent, 1 - opaque. */
|
||||
typedef enum {
|
||||
C2D_COLOR_FORMAT_411_YYUYYV = 110, /* packed, 12-bit */
|
||||
C2D_COLOR_FORMAT_411_YUYYVY = 111, /* packed, 12-bit */
|
||||
C2D_COLOR_FORMAT_411_UYYVYY = 112, /* packed, 12-bit, "Y411" */
|
||||
C2D_COLOR_FORMAT_411_YUYV2Y4 = 116, /* packed, 12-bit */
|
||||
C2D_COLOR_FORMAT_411_UYVY2Y4 = 117, /* packed, 12-bit, "Y41P" */
|
||||
|
||||
C2D_COLOR_FORMAT_422_YUYV = 120, /* packed, 16-bit, "YUY2" */
|
||||
C2D_COLOR_FORMAT_422_UYVY = 121, /* packed, 16-bit, "UYVY" */
|
||||
C2D_COLOR_FORMAT_422_YVYU = 122, /* packed, 16-bit, "YVYU" */
|
||||
C2D_COLOR_FORMAT_422_VYUY = 123, /* packed, 16-bit */
|
||||
|
||||
C2D_COLOR_FORMAT_444_YUV = 130, /* packed, 24-bit */
|
||||
C2D_COLOR_FORMAT_444_UYV = 131, /* packed, 24-bit, "IYU2" */
|
||||
C2D_COLOR_FORMAT_444_AYUV = 136, /* packed, 24-bit, "AYUV" */
|
||||
|
||||
C2D_COLOR_FORMAT_410_Y_UV = 150, /* planar, Y + interleaved UV */
|
||||
C2D_COLOR_FORMAT_411_Y_UV = 151, /* planar, Y + interleaved UV */
|
||||
C2D_COLOR_FORMAT_420_Y_UV = 152, /* planar, Y + interleaved UV */
|
||||
C2D_COLOR_FORMAT_422_Y_UV = 153, /* planar, Y + interleaved UV */
|
||||
C2D_COLOR_FORMAT_444_Y_UV = 154, /* planar, Y + interleaved UV */
|
||||
|
||||
C2D_COLOR_FORMAT_410_Y_VU = 160, /* planar, Y + interleaved VU */
|
||||
C2D_COLOR_FORMAT_411_Y_VU = 161, /* planar, Y + interleaved VU */
|
||||
C2D_COLOR_FORMAT_420_Y_VU = 162, /* planar, Y + interleaved VU */
|
||||
C2D_COLOR_FORMAT_422_Y_VU = 163, /* planar, Y + interleaved VU */
|
||||
C2D_COLOR_FORMAT_444_Y_VU = 164, /* planar, Y + interleaved VU */
|
||||
|
||||
C2D_COLOR_FORMAT_410_Y_U_V = 170, /* planar, Y + U + V separate */
|
||||
C2D_COLOR_FORMAT_411_Y_U_V = 171, /* planar, Y + U + V separate */
|
||||
C2D_COLOR_FORMAT_420_Y_V_U = 172, /* planar, Y + V + U separate */
|
||||
C2D_COLOR_FORMAT_420_Y_U_V = 173, /* planar, Y + U + V separate */
|
||||
C2D_COLOR_FORMAT_422_Y_U_V = 174, /* planar, Y + U + V separate */
|
||||
C2D_COLOR_FORMAT_444_Y_U_V = 175, /* planar, Y + U + V separate */
|
||||
|
||||
C2D_COLOR_FORMAT_800_Y = 190, /* planar, Y only, grayscale */
|
||||
|
||||
/* derived YUV color formats (base format + mode bits), FOURCC */
|
||||
|
||||
C2D_COLOR_FORMAT_411_Y411 = 112,
|
||||
C2D_COLOR_FORMAT_411_Y41P = 117,
|
||||
C2D_COLOR_FORMAT_411_IY41 = 117 | (1 << 14),
|
||||
C2D_COLOR_FORMAT_411_Y41T = 117 | (1 << 15),
|
||||
|
||||
C2D_COLOR_FORMAT_422_YUY2 = 120,
|
||||
C2D_COLOR_FORMAT_422_IUYV = 121 | (1 << 14),
|
||||
C2D_COLOR_FORMAT_422_Y42T = 121 | (1 << 15),
|
||||
C2D_COLOR_FORMAT_444_IYU2 = 131,
|
||||
|
||||
C2D_COLOR_FORMAT_420_NV12 = 152,
|
||||
C2D_COLOR_FORMAT_420_NV21 = 162,
|
||||
|
||||
C2D_COLOR_FORMAT_410_YUV9 = 170,
|
||||
C2D_COLOR_FORMAT_410_YVU9 = 170,
|
||||
C2D_COLOR_FORMAT_411_Y41B = 171,
|
||||
C2D_COLOR_FORMAT_420_YV12 = 172,
|
||||
C2D_COLOR_FORMAT_420_IYUV = 173,
|
||||
C2D_COLOR_FORMAT_420_I420 = 173,
|
||||
C2D_COLOR_FORMAT_422_YV16 = 174,
|
||||
C2D_COLOR_FORMAT_422_Y42B = 174,
|
||||
|
||||
C2D_COLOR_FORMAT_800_Y800 = 190,
|
||||
|
||||
} C2D_YUV_FORMAT;
|
||||
|
||||
|
||||
/* Configuration bits, used in the config_mask field of C2D_OBJECT struct */
|
||||
typedef enum {
|
||||
C2D_SOURCE_RECT_BIT = (1 << 0), /* enables source_rect field */
|
||||
C2D_MIRROR_H_BIT = (1 << 1), /* enables horizontal flipping */
|
||||
C2D_MIRROR_V_BIT = (1 << 2), /* enables vertical flipping */
|
||||
C2D_SOURCE_TILE_BIT = (1 << 3), /* enables source surface tiling */
|
||||
C2D_TARGET_RECT_BIT = (1 << 4), /* enables target_rect field */
|
||||
C2D_ROTATE_BIT = (1 << 5), /* enables all rotation fields */
|
||||
C2D_SCISSOR_RECT_BIT = (1 << 6), /* enables scissor_rect field */
|
||||
C2D_MASK_SURFACE_BIT = (1 << 7), /* enables mask_surface_id field */
|
||||
C2D_MASK_ALIGN_BIT = (1 << 8), /* aligns mask to source_rect */
|
||||
C2D_MASK_SCALE_BIT = (1 << 9), /* enables mask surface scaling */
|
||||
C2D_MASK_TILE_BIT = (1 << 10), /* enables mask surface tiling */
|
||||
C2D_GLOBAL_ALPHA_BIT = (1 << 11), /* enables global_alpha field */
|
||||
C2D_COLOR_KEY_BIT = (1 << 12), /* enables color_key field */
|
||||
C2D_NO_PIXEL_ALPHA_BIT = (1 << 13), /* disables source alpha channel */
|
||||
C2D_NO_BILINEAR_BIT = (1 << 14), /* disables bilinear on scaling */
|
||||
C2D_NO_ANTIALIASING_BIT = (1 << 15), /* disables antialiasing on edges */
|
||||
C2D_DRAW_LINE_BIT = (1 << 16), /* enables line drawing with source rectangle */
|
||||
C2D_DRAW_LINE_NOLAST = (1 << 17), /* disable last pixel draw for line */
|
||||
} C2D_SOURCE_CONFIG;
|
||||
|
||||
|
||||
/* Target configuration bits, defines rotation + mirroring.
|
||||
* Mirror is applied prior to rotation if enabled. */
|
||||
typedef enum {
|
||||
C2D_TARGET_MIRROR_H = (1 << 0), /* horizontal flip */
|
||||
C2D_TARGET_MIRROR_V = (1 << 1), /* vertical flip */
|
||||
C2D_TARGET_ROTATE_0 = (0 << 2), /* no rotation */
|
||||
C2D_TARGET_ROTATE_90 = (1 << 2), /* 90 degree rotation */
|
||||
C2D_TARGET_ROTATE_180 = (2 << 2), /* 180 degree rotation */
|
||||
C2D_TARGET_ROTATE_270 = (3 << 2), /* 270 degree rotation, 90 + 180 */
|
||||
C2D_TARGET_MASK_ALIGN = (1 << 4), /* aligns mask to target scissor */
|
||||
C2D_TARGET_MASK_SCALE = (1 << 5), /* enables mask scaling */
|
||||
C2D_TARGET_MASK_TILE = (1 << 6), /* enables mask tiling */
|
||||
C2D_TARGET_COLOR_KEY = (1 << 7), /* enables target_color_key */
|
||||
C2D_TARGET_NO_PIXEL_ALPHA = (1 << 8), /* disables target alpha channel */
|
||||
} C2D_TARGET_CONFIG;
|
||||
|
||||
#define C2D_TARGET_ROTATION_MASK (C2D_TARGET_ROTATE_90*3)
|
||||
|
||||
/* Additional blend modes, can be used with both source and target configs.
|
||||
If none of the below is set, the default "SRC over DST" is applied. */
|
||||
typedef enum {
|
||||
C2D_ALPHA_BLEND_SRC_OVER = (0 << 20), /* Default, Porter-Duff "SRC over DST" */
|
||||
C2D_ALPHA_BLEND_SRC = (1 << 20), /* Porter-Duff "SRC" */
|
||||
C2D_ALPHA_BLEND_SRC_IN = (2 << 20), /* Porter-Duff "SRC in DST" */
|
||||
C2D_ALPHA_BLEND_DST_IN = (3 << 20), /* Porter-Duff "DST in SRC" */
|
||||
C2D_ALPHA_BLEND_SRC_OUT = (4 << 20), /* Porter-Duff "SRC out DST" */
|
||||
C2D_ALPHA_BLEND_DST_OUT = (5 << 20), /* Porter-Duff "DST out SRC" */
|
||||
C2D_ALPHA_BLEND_DST_OVER = (6 << 20), /* Porter-Duff "DST over SRC" */
|
||||
C2D_ALPHA_BLEND_SRC_ATOP = (7 << 20), /* Porter-Duff "SRC ATOP" */
|
||||
C2D_ALPHA_BLEND_DST_ATOP = (8 << 20), /* Porter-Duff "DST ATOP" */
|
||||
C2D_ALPHA_BLEND_XOR = (9 << 20), /* Xor */
|
||||
C2D_ALPHA_BLEND_MULTIPLY = (10 << 20), /* OpenVG "MULTIPLY" */
|
||||
C2D_ALPHA_BLEND_SCREEN = (11 << 20), /* OpenVG "SCREEN" */
|
||||
C2D_ALPHA_BLEND_DARKEN = (12 << 20), /* OpenVG "DARKEN" */
|
||||
C2D_ALPHA_BLEND_LIGHTEN = (13 << 20), /* OpenVG "LIGHTEN" */
|
||||
C2D_ALPHA_BLEND_ADDITIVE = (14 << 20), /* OpenVG "ADDITIVE" */
|
||||
C2D_ALPHA_BLEND_DIRECT = (15 << 20), /* Direct alpha blitting */
|
||||
C2D_ALPHA_BLEND_INVERTC = (16 << 20), /* Invert color */
|
||||
C2D_ALPHA_BLEND_NONE = (1 << 25), /* disables alpha blending */
|
||||
} C2D_ALPHA_BLEND_MODE;
|
||||
|
||||
/* Configuration bits, used in the config_mask field of C2D_OBJECT struct */
|
||||
typedef enum {
|
||||
C2D_OVERRIDE_GLOBAL_TARGET_ROTATE_CONFIG = (1 << 27), /* Overrides TARGET Config */
|
||||
C2D_OVERRIDE_TARGET_ROTATE_0 = (0 << 28), /* no rotation */
|
||||
C2D_OVERRIDE_TARGET_ROTATE_90 = (1 << 28), /* 90 degree rotation */
|
||||
C2D_OVERRIDE_TARGET_ROTATE_180 = (2 << 28), /* 180 degree rotation */
|
||||
C2D_OVERRIDE_TARGET_ROTATE_270 = (3 << 28), /* 270 degree rotation */
|
||||
} C2D_SOURCE_TARGET_CONFIG;
|
||||
|
||||
#define C2D_OVERRIDE_SOURCE_CONFIG_TARGET_ROTATION_SHIFT_MASK 28
|
||||
#define C2D_OVERRIDE_TARGET_CONFIG_TARGET_ROTATION_SHIFT_MASK 2
|
||||
|
||||
|
||||
/* Surface caps enumeration */
|
||||
typedef enum {
|
||||
C2D_SOURCE = (1 << 0), /* allows to use as a source */
|
||||
C2D_TARGET = (1 << 1), /* allows to use as a target */
|
||||
C2D_MASK = (1 << 2), /* allows to use as a mask */
|
||||
C2D_PALETTE = (1 << 3), /* allows to use as a palette */
|
||||
} C2D_SURFACE_BITS;
|
||||
|
||||
/* Surface type enumeration */
|
||||
typedef enum {
|
||||
C2D_SURFACE_RGB_HOST = 1, /* Host memory RGB surface */
|
||||
C2D_SURFACE_RGB_EXT = 2, /* External memory RGB surface */
|
||||
C2D_SURFACE_YUV_HOST = 3, /* Host memory YUV surface */
|
||||
C2D_SURFACE_YUV_EXT = 4, /* External memory YUV surface */
|
||||
C2D_SURFACE_WITH_PHYS = (1<<3), /* physical address already mapped */
|
||||
/* this bit is valid with HOST types */
|
||||
C2D_SURFACE_WITH_PHYS_DUMMY = (1<<4), /* physical address already mapped */
|
||||
/* this bit is valid with HOST types */
|
||||
} C2D_SURFACE_TYPE;
|
||||
|
||||
/* Structure for registering a RGB buffer as a blit surface */
|
||||
typedef struct {
|
||||
uint32 format; /* RGB color format plus additional mode bits */
|
||||
uint32 width; /* defines width in pixels */
|
||||
uint32 height; /* defines height in pixels */
|
||||
void *buffer; /* pointer to the RGB buffer */
|
||||
void *phys; /* physical address */
|
||||
int32 stride; /* defines stride in bytes, negative stride is allowed */
|
||||
} C2D_RGB_SURFACE_DEF;
|
||||
|
||||
/* Structure for registering a YUV plane(s) as a blit surface */
|
||||
typedef struct {
|
||||
uint32 format; /* YUV color format plus additional mode bits */
|
||||
uint32 width; /* defines width in pixels */
|
||||
uint32 height; /* defines height in pixels */
|
||||
void *plane0; /* holds the whole buffer if YUV format is not planar */
|
||||
void *phys0; /* physical address */
|
||||
int32 stride0; /* stride in bytes if YUV format is not planar */
|
||||
void *plane1; /* holds UV or VU plane for planar interleaved */
|
||||
void *phys1; /* physical address */
|
||||
int32 stride1; /* stride for UV or VU plane for planar interleaved */
|
||||
void *plane2; /* holds the 3. plane, ignored if YUV format is not planar */
|
||||
void *phys2; /* physical address */
|
||||
int32 stride2; /* stride for the 3. plane, ignored if YUV format is not planar */
|
||||
} C2D_YUV_SURFACE_DEF;
|
||||
|
||||
|
||||
/* Rectangle definition */
|
||||
typedef struct {
|
||||
int32 x; /* upper-left x */
|
||||
int32 y; /* upper-left y */
|
||||
int32 width; /* width */
|
||||
int32 height; /* height */
|
||||
} C2D_RECT;
|
||||
|
||||
/* C2D_OBJECT encapsulates the blit parameters for a source surface.
|
||||
* The fg_color defines color in target format for bits equal to 1
|
||||
* in the source C2D_COLOR_FORMAT_1 format. It also defines rendering
|
||||
* color for all alpha-only source formats. If the surface_id is 0
|
||||
* the fg_color defines a constant fill color used instead of the surface.
|
||||
* The bg_color defines color in target format for bits equal to 0
|
||||
* in the source C2D_COLOR_FORMAT_1 format, otherwise both are ignored.
|
||||
* The palette_id is used for all palette source formats, otherwise ignored.
|
||||
|
||||
* The source_rect first defines the content of the source surface,
|
||||
* it is then horizontally/vertically flipped if C2D_MIRROR_*_BIT is set,
|
||||
* then scaled with bilinear interpolation to exactly fit target_rect
|
||||
* or repeated across target_rect if C2D_SOURCE_TILE_BIT is set,
|
||||
* target_rect is then rotated clockwise by an arbitrary angle in degrees
|
||||
* around the rot_orig_x/y, defined relative to target_rect's top left point,
|
||||
* and then clipped to scissor_rect defined in target coordinate system.
|
||||
|
||||
* Finally alpha blending is applied before pixels get written into the target.
|
||||
* Surface's pixel alpha is combined with mask alpha and with global alpha.
|
||||
* Mask surface follows all transformations applied to the source surface.
|
||||
* Source color key defines transparent color, applied together with alpha. */
|
||||
typedef struct C2D_OBJECT_STR {
|
||||
uint32 surface_id; /* source surface */
|
||||
|
||||
uint32 fg_color; /* foreground color */
|
||||
uint32 bg_color; /* background color */
|
||||
uint32 palette_id; /* one-dimensional horizontal palette surface */
|
||||
|
||||
uint32 config_mask; /* defines which fields below are enabled */
|
||||
|
||||
C2D_RECT source_rect; /* region of the source surface, 16.16 fp */
|
||||
C2D_RECT target_rect; /* position and scaling in target, 16.16 fp */
|
||||
|
||||
int32 rot_orig_x; /* rotation origin relative to target_rect's... */
|
||||
int32 rot_orig_y; /* ...top left point, both are 16.16 fp */
|
||||
int32 rotation; /* clock-wise rotation in degrees, 16.16 fp */
|
||||
|
||||
C2D_RECT scissor_rect; /* defines the clip rectangle in target surface */
|
||||
|
||||
uint32 mask_surface_id; /* source alpha-mask surface */
|
||||
uint32 global_alpha; /* 0 = fully transparent, 255 = fully opaque */
|
||||
uint32 color_key; /* transparent color for the source surface */
|
||||
|
||||
struct C2D_OBJECT_STR *next; /* pointer to the next object or NULL */
|
||||
} C2D_OBJECT;
|
||||
|
||||
/* Configuration bits, driver capabilities used by 2Dapplications */
|
||||
typedef enum {
|
||||
C2D_DRIVER_SUPPORTS_GLOBAL_ALPHA_OP = (1 << 0),
|
||||
C2D_DRIVER_SUPPORTS_TILE_OP = (1 << 1),
|
||||
C2D_DRIVER_SUPPORTS_COLOR_KEY_OP = (1 << 2),
|
||||
C2D_DRIVER_SUPPORTS_NO_PIXEL_ALPHA_OP = (1 << 3),
|
||||
C2D_DRIVER_SUPPORTS_TARGET_ROTATE_OP = (1 << 4),
|
||||
C2D_DRIVER_SUPPORTS_ANTI_ALIASING_OP = (1 << 5), /* antialiasing */
|
||||
C2D_DRIVER_SUPPORTS_BILINEAR_FILTER_OP = (1 << 6),
|
||||
C2D_DRIVER_SUPPORTS_LENS_CORRECTION_OP = (1 << 7),
|
||||
C2D_DRIVER_SUPPORTS_OVERRIDE_TARGET_ROTATE_OP = (1 << 8),
|
||||
C2D_DRIVER_SUPPORTS_SHADER_BLOB_OP = (1 << 9),
|
||||
C2D_DRIVER_SUPPORTS_MASK_SURFACE_OP = (1 << 10), /* mask surface */
|
||||
C2D_DRIVER_SUPPORTS_MIRROR_H_OP = (1 << 11), /* horizontal flip */
|
||||
C2D_DRIVER_SUPPORTS_MIRROR_V_OP = (1 << 12), /* vertical flip */
|
||||
C2D_DRIVER_SUPPORTS_SCISSOR_RECT_OP = (1 << 13),
|
||||
C2D_DRIVER_SUPPORTS_SOURCE_RECT_OP = (1 << 14),
|
||||
C2D_DRIVER_SUPPORTS_TARGET_RECT_OP = (1 << 15),
|
||||
C2D_DRIVER_SUPPORTS_ROTATE_OP = (1 << 16), /* all rotations */
|
||||
C2D_DRIVER_SUPPORTS_FLUSH_WITH_FENCE_FD_OP = (1 << 17), /* all rotations */
|
||||
C2D_DRIVER_SUPPORTS_UBWC_COMPRESSED_OP = (1 << 18), /* UBWC Compression */
|
||||
C2D_DRIVER_SUPPORTS_ALL_CAPABILITIES_OP = ((0xFFFFFFFF) >> (31 - 18)) /* mask for all capabilities supported */
|
||||
} C2D_DRIVER_CAPABILITIES;
|
||||
|
||||
/* 2D driver workaround bits used by the 2D applications */
|
||||
typedef enum {
|
||||
C2D_DRIVER_WORKAROUND_NONE = 0, /* NO workaround */
|
||||
C2D_DRIVER_WORKAROUND_SWAP_UV_FOR_YUV_TARGET = (1 << 0), /* Swap UV when this flag set */
|
||||
} C2D_DRIVER_WORKAROUND;
|
||||
|
||||
/* Structure to query Driver information */
|
||||
typedef struct {
|
||||
uint32 capabilities_mask;
|
||||
uint32 workaround_mask;
|
||||
uint32 reserved1;
|
||||
uint32 reserved2;
|
||||
uint32 reserved3;
|
||||
} C2D_DRIVER_INFO;
|
||||
|
||||
/* Structure to query Driver information */
|
||||
typedef struct {
|
||||
uint32 max_surface_template_needed;
|
||||
uint32 reserved1;
|
||||
uint32 reserved2;
|
||||
uint32 reserved3;
|
||||
} C2D_DRIVER_SETUP_INFO;
|
||||
|
||||
/*****************************************************************************/
|
||||
/**************************** C2D API 2.0 ********************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
* Functions to create/destroy surfaces */
|
||||
|
||||
/* Creates a generic blit surface according to its type.
|
||||
* Pass a combination of desired surface bits according to planned usage.
|
||||
* Accepted values for surface_bits may include bits from C2D_SURFACE_BITS,
|
||||
* and also from C2D_DISPLAY for compatibility with HW display controller.
|
||||
* For host memory types the memory is preallocated outside the API
|
||||
* and should remain valid until surface is destroyed.
|
||||
* For external memory types the memory is allocated within API.
|
||||
* On success, the non-zero surface identifier is returned.
|
||||
* All numbers greater that 0 are valid surface identifiers, 0 is invalid.
|
||||
|
||||
* Host memory RGB surface:
|
||||
* surface_type = C2D_SURFACE_RGB_HOST
|
||||
* surface_definition = C2D_RGB_SURFACE_DEF
|
||||
* all fields in definition structure should be set
|
||||
|
||||
* External memory RGB surface:
|
||||
* surface_type = C2D_SURFACE_RGB_EXT
|
||||
* surface_definition = C2D_RGB_SURFACE_DEF
|
||||
* buffer field in definition structure is ignored
|
||||
|
||||
* Host memory YUV surface:
|
||||
* surface_type = C2D_SURFACE_YUV_HOST
|
||||
* surface_definition = C2D_YUV_SURFACE_DEF
|
||||
* one or all plane and stride fields in definition structure
|
||||
* should be set depending on whether the format is planar or not
|
||||
|
||||
* External memory YUV surface:
|
||||
* surface_type = C2D_SURFACE_YUV_EXT
|
||||
* surface_definition = C2D_YUV_SURFACE_DEF
|
||||
* all plane and stride fields in definition structure are ignored */
|
||||
C2D_API C2D_STATUS c2dCreateSurface( uint32 *surface_id,
|
||||
uint32 surface_bits,
|
||||
C2D_SURFACE_TYPE surface_type,
|
||||
void *surface_definition );
|
||||
|
||||
/* Requests properties of the specified surface. */
|
||||
C2D_API C2D_STATUS c2dQuerySurface( uint32 surface_id,
|
||||
uint32 *surface_bits,
|
||||
C2D_SURFACE_TYPE *surface_type,
|
||||
uint32 *width, uint32 *height,
|
||||
uint32 *format );
|
||||
|
||||
/* Destroys a generic blit surface.
|
||||
* For external memory surfaces also deallocates the memory.
|
||||
* It is safe to free any external resources associated with a given
|
||||
* surface on c2dCreateSurface call after this function returns. */
|
||||
C2D_API C2D_STATUS c2dDestroySurface( uint32 surface_id );
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Functions to modify/exchange surface data */
|
||||
|
||||
/* The format of fill_color is the same as color format being used
|
||||
* for specified surface. If fill_rect is NULL the whole surface is filled.
|
||||
* Alpha-blending is not performed while filling.
|
||||
* The operation is complete when function returns. */
|
||||
C2D_API C2D_STATUS c2dFillSurface( uint32 surface_id,
|
||||
uint32 fill_color,
|
||||
C2D_RECT *fill_rect );
|
||||
|
||||
/* Writes data located in host memory into the specified surface.
|
||||
* The chunk of host memory is identified with surface_type and
|
||||
* surface_definition, no surface registration needed in this case.
|
||||
* Only C2D_SURFACE_RGB_HOST, C2D_SURFACE_YUV_HOST are accepted.
|
||||
* If only part of the host memory buffer should be loaded, it should
|
||||
* be configured in surface_definition using width, height and stride.
|
||||
* The x and y are defined in target surface coordinate space.
|
||||
* Color conversion has to be done, if color formats differ.
|
||||
* Alpha-blending is not performed while writing.
|
||||
* The operation is complete when function returns. */
|
||||
C2D_API C2D_STATUS c2dWriteSurface( uint32 surface_id,
|
||||
C2D_SURFACE_TYPE surface_type,
|
||||
void *surface_definition,
|
||||
int32 x, int32 y );
|
||||
|
||||
/* Reads data from the specified surface into the host memory.
|
||||
* The chunk of host memory is identified with surface_type and
|
||||
* surface_definition, no surface registration needed in this case.
|
||||
* Only C2D_SURFACE_RGB_HOST, C2D_SURFACE_YUV_HOST are accepted.
|
||||
* If only part of the surface should be read, it should
|
||||
* be configured in surface_definition using width, height and stride.
|
||||
* The x and y are defined in source surface coordinate space.
|
||||
* Color conversion has to be done, if color formats differ.
|
||||
* Alpha-blending is not performed while reading.
|
||||
* The operation is complete when function returns. */
|
||||
C2D_API C2D_STATUS c2dReadSurface( uint32 surface_id,
|
||||
C2D_SURFACE_TYPE surface_type,
|
||||
void *surface_definition,
|
||||
int32 x, int32 y );
|
||||
|
||||
/* Notifies c2d imlementation that surface has been updated from outside the API,
|
||||
* if updated_rect is NULL then the whole surface has been updated. */
|
||||
C2D_API C2D_STATUS c2dSurfaceUpdated( uint32 surface_id,
|
||||
C2D_RECT *updated_rect );
|
||||
|
||||
/* Updates surface information.
|
||||
* Could be called only for host surfaces set with parameter "C2D_SURFACE_WITH_PHYS".
|
||||
* Count for surface planes have to be same than for already allocated surface */
|
||||
C2D_API C2D_STATUS c2dUpdateSurface( uint32 surface_id,
|
||||
uint32 surface_bits,
|
||||
C2D_SURFACE_TYPE surface_type,
|
||||
void *surface_definition );
|
||||
|
||||
/******************************************************************************
|
||||
* Functions to do actual blit */
|
||||
|
||||
/* Draw a list of blit objects into the given target.
|
||||
* The target_config is a bitwise OR of values from C2D_TARGET_CONFIG.
|
||||
* The target transformation creates the effect that target surface
|
||||
* is transformed before the blit and then transformed back
|
||||
* after blit, however no physical target transform is performed.
|
||||
* The objects_list is a linked list of blit objects, no more
|
||||
* than num_objects is drawn from the given list.
|
||||
* If num_objects is 0, the whole list is drawn.
|
||||
* The blit is not guaranteed to complete after function returns. */
|
||||
C2D_API C2D_STATUS c2dDraw( uint32 target_id,
|
||||
uint32 target_config, C2D_RECT *target_scissor,
|
||||
uint32 target_mask_id, uint32 target_color_key,
|
||||
C2D_OBJECT *objects_list, uint32 num_objects );
|
||||
|
||||
|
||||
/* timstamp set in the blit commands flush */
|
||||
typedef void* c2d_ts_handle;
|
||||
|
||||
/* Forces any pending blit to complete for a given target.
|
||||
* Non-blocking. All input surfaces for this target except those
|
||||
* which are shared with other targets are expected to be immediately
|
||||
* writable after client has been waiting returned timestamp with
|
||||
* c2dWaitTimestamp funtion or c2dFinish has been called for same target */
|
||||
C2D_API C2D_STATUS c2dFlush( uint32 target_id, c2d_ts_handle *timestamp);
|
||||
|
||||
|
||||
/* Waits the pending timestamp */
|
||||
C2D_API C2D_STATUS c2dWaitTimestamp( c2d_ts_handle timestamp );
|
||||
|
||||
|
||||
/* Forces any pending blit to complete for a given target.
|
||||
* Blocking version, returns when blit is done.
|
||||
* All input surfaces for this target except those which are shared with
|
||||
* other targets are expected to be immediately
|
||||
* writable after this function returns. */
|
||||
C2D_API C2D_STATUS c2dFinish( uint32 target_id );
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/****************************** Display API **********************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
/* Display input enumeration */
|
||||
typedef enum {
|
||||
C2D_DISPLAY_INPUT_0 = 0, /*!< default input */
|
||||
C2D_DISPLAY_INPUT_1 = (1<<16), /*!< Overlay 1 */
|
||||
C2D_DISPLAY_INPUT_2 = (1<<17), /*!< Overlay 2... */
|
||||
} C2D_DISPLAY_INPUT;
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Functions for display output. */
|
||||
|
||||
/* Functionality described in this section is optional and is
|
||||
* provided only for the cases when blit HW
|
||||
* is tightly bound to the display controller. */
|
||||
|
||||
/* Display enumeration, may also be used in surface caps */
|
||||
typedef enum {
|
||||
C2D_DISPLAY_MAIN = (1 << 10), /* main display */
|
||||
C2D_DISPLAY_SECONDARY = (1 << 11), /* secondary display */
|
||||
C2D_DISPLAY_TV_OUT = (1 << 12), /* tv-out */
|
||||
} C2D_DISPLAY;
|
||||
|
||||
/* Display window enumeration */
|
||||
typedef enum {
|
||||
C2D_DISPLAY_OVERLAY = C2D_DISPLAY_INPUT_1, /*!< Overlay window bit. This defines display input.
|
||||
When defined the surface is set on the overlay window
|
||||
otherwise the surface is set on the background window. */
|
||||
} C2D_DISPLAY_WINDOW; /*!< Window bit set with display parameter */
|
||||
|
||||
|
||||
/* Display update modes */
|
||||
typedef enum {
|
||||
C2D_DISPLAY_MODE_TEAR_SYNC = (1 << 0), /* enables tearing sync */
|
||||
C2D_DISPLAY_MODE_SURF_REMOVE = (1 << 1), /* Remove surface from given display + input */
|
||||
} C2D_DISPLAY_MODE;
|
||||
|
||||
|
||||
/* Sets the given surface as a current display front buffer.
|
||||
* Several displays can be specified as an output if supported.
|
||||
* Still only one input can be specified at a time fro display/displays.
|
||||
* The surface remains shown until it gets replaced with another one. */
|
||||
C2D_API C2D_STATUS c2dDisplaySetSurface( uint32 display,
|
||||
uint32 surface_id, uint32 mode );
|
||||
|
||||
/* Returns the current surface for a particular display.
|
||||
* Only one display can be specified at a time.
|
||||
* The latest surface set with compDisplaySetSurface or
|
||||
* the default pre-allocated surface is returned. */
|
||||
C2D_API C2D_STATUS c2dDisplayGetSurface( uint32 display,
|
||||
uint32 *surface_id );
|
||||
|
||||
/* Returns the properties for a particular display.
|
||||
* Only one display can be specified at a time. */
|
||||
C2D_API C2D_STATUS c2dDisplayGetProperties( uint32 display,
|
||||
uint32 *width, uint32 *height,
|
||||
uint32 *format );
|
||||
|
||||
/* Sets the properties for a particular display input.
|
||||
* Only one display + input can be specified at a time.
|
||||
* C2D_OBJECT used to set input rect(target rect),
|
||||
* blending operations, rotation...etc for display source */
|
||||
C2D_API C2D_STATUS c2dDisplaySetObject( uint32 display,
|
||||
uint32 target_config, uint32 target_color_key,
|
||||
C2D_OBJECT * c2dObject, uint32 mode);
|
||||
|
||||
/* allows user to map a memory region to the gpu. only supported on linux
|
||||
* mem_fd is the fd of the memory region, hostptr is the host pointer to the region,
|
||||
* len and offset are the size and offset of the memory.
|
||||
* flags is one of the memory types supported by gsl
|
||||
* gpaddr is passed by refernce back to the user
|
||||
*/
|
||||
C2D_API C2D_STATUS c2dMapAddr ( int mem_fd, void * hostptr, uint32 len, uint32 offset, uint32 flags, void ** gpuaddr);
|
||||
|
||||
/* allows user to unmap memory region mapped by c2dMapAddr.
|
||||
* gpaddr is the gpuaddr to unmap */
|
||||
C2D_API C2D_STATUS c2dUnMapAddr (void * gpuaddr);
|
||||
|
||||
/* allows user to query driver capabilities.
|
||||
* driver_info is the information about driver */
|
||||
C2D_API C2D_STATUS c2dGetDriverCapabilities( C2D_DRIVER_INFO * driver_info);
|
||||
|
||||
/* create a fence fd for the timestamp */
|
||||
C2D_API C2D_STATUS c2dCreateFenceFD( uint32 target_id, c2d_ts_handle timestamp, int32 *fd);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __c2d2_h_ */
|
||||
@@ -1,794 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
* Copyright (c) 2010 - 2014, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Not a Contribution, Apache license notifications and license are retained
|
||||
* for attribution purposes only.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <log/log.h>
|
||||
|
||||
#include <linux/msm_mdp.h>
|
||||
#include <linux/fb.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <copybit.h>
|
||||
|
||||
#include "gralloc_priv.h"
|
||||
#include "software_converter.h"
|
||||
#include <qdMetaData.h>
|
||||
|
||||
#define DEBUG_MDP_ERRORS 1
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
#define MAX_SCALE_FACTOR (4)
|
||||
#define MAX_DIMENSION (4096)
|
||||
|
||||
/******************************************************************************/
|
||||
struct blitReq{
|
||||
struct mdp_buf_sync sync;
|
||||
uint32_t count;
|
||||
struct mdp_blit_req req[10];
|
||||
};
|
||||
|
||||
/** State information for each device instance */
|
||||
struct copybit_context_t {
|
||||
struct copybit_device_t device;
|
||||
int mFD;
|
||||
uint8_t mAlpha;
|
||||
int mFlags;
|
||||
bool mBlitToFB;
|
||||
int acqFence[MDP_MAX_FENCE_FD];
|
||||
int relFence;
|
||||
struct mdp_buf_sync sync;
|
||||
struct blitReq list;
|
||||
uint8_t dynamic_fps;
|
||||
};
|
||||
|
||||
/**
|
||||
* Common hardware methods
|
||||
*/
|
||||
|
||||
static int open_copybit(const struct hw_module_t* module, const char* name,
|
||||
struct hw_device_t** device);
|
||||
|
||||
static struct hw_module_methods_t copybit_module_methods = {
|
||||
open: open_copybit
|
||||
};
|
||||
|
||||
/*
|
||||
* The COPYBIT Module
|
||||
*/
|
||||
struct copybit_module_t HAL_MODULE_INFO_SYM = {
|
||||
common: {
|
||||
tag: HARDWARE_MODULE_TAG,
|
||||
version_major: 1,
|
||||
version_minor: 0,
|
||||
id: COPYBIT_HARDWARE_MODULE_ID,
|
||||
name: "QCT MSM7K COPYBIT Module",
|
||||
author: "Google, Inc.",
|
||||
methods: ©bit_module_methods
|
||||
}
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
/** min of int a, b */
|
||||
static inline int min(int a, int b) {
|
||||
return (a<b) ? a : b;
|
||||
}
|
||||
|
||||
/** max of int a, b */
|
||||
static inline int max(int a, int b) {
|
||||
return (a>b) ? a : b;
|
||||
}
|
||||
|
||||
/** scale each parameter by mul/div. Assume div isn't 0 */
|
||||
static inline void MULDIV(uint32_t *a, uint32_t *b, int mul, int div) {
|
||||
if (mul != div) {
|
||||
*a = (mul * *a) / div;
|
||||
*b = (mul * *b) / div;
|
||||
}
|
||||
}
|
||||
|
||||
/** Determine the intersection of lhs & rhs store in out */
|
||||
static void intersect(struct copybit_rect_t *out,
|
||||
const struct copybit_rect_t *lhs,
|
||||
const struct copybit_rect_t *rhs) {
|
||||
out->l = max(lhs->l, rhs->l);
|
||||
out->t = max(lhs->t, rhs->t);
|
||||
out->r = min(lhs->r, rhs->r);
|
||||
out->b = min(lhs->b, rhs->b);
|
||||
}
|
||||
|
||||
static bool validateCopybitRect(struct copybit_rect_t *rect) {
|
||||
return ((rect->b > rect->t) && (rect->r > rect->l)) ;
|
||||
}
|
||||
|
||||
/** convert COPYBIT_FORMAT to MDP format */
|
||||
static int get_format(int format) {
|
||||
switch (format) {
|
||||
case HAL_PIXEL_FORMAT_RGB_565: return MDP_RGB_565;
|
||||
case HAL_PIXEL_FORMAT_RGBA_5551: return MDP_RGBA_5551;
|
||||
case HAL_PIXEL_FORMAT_RGBA_4444: return MDP_RGBA_4444;
|
||||
case HAL_PIXEL_FORMAT_RGBX_8888: return MDP_RGBX_8888;
|
||||
case HAL_PIXEL_FORMAT_BGRX_8888: return MDP_BGRX_8888;
|
||||
case HAL_PIXEL_FORMAT_RGB_888: return MDP_RGB_888;
|
||||
case HAL_PIXEL_FORMAT_RGBA_8888: return MDP_RGBA_8888;
|
||||
case HAL_PIXEL_FORMAT_BGRA_8888: return MDP_BGRA_8888;
|
||||
case HAL_PIXEL_FORMAT_YCrCb_422_I: return MDP_YCRYCB_H2V1;
|
||||
case HAL_PIXEL_FORMAT_YCbCr_422_I: return MDP_YCBYCR_H2V1;
|
||||
case HAL_PIXEL_FORMAT_YCrCb_422_SP: return MDP_Y_CRCB_H2V1;
|
||||
case HAL_PIXEL_FORMAT_YCrCb_420_SP: return MDP_Y_CRCB_H2V2;
|
||||
case HAL_PIXEL_FORMAT_YCbCr_422_SP: return MDP_Y_CBCR_H2V1;
|
||||
case HAL_PIXEL_FORMAT_YCbCr_420_SP: return MDP_Y_CBCR_H2V2;
|
||||
case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: return MDP_Y_CBCR_H2V2_ADRENO;
|
||||
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: return MDP_Y_CBCR_H2V2_VENUS;
|
||||
case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: return MDP_Y_CRCB_H2V2_VENUS;
|
||||
case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: return MDP_Y_CBCR_H2V2;
|
||||
case HAL_PIXEL_FORMAT_CbYCrY_422_I: return MDP_CBYCRY_H2V1;
|
||||
case HAL_PIXEL_FORMAT_BGR_888: return MDP_BGR_888;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** convert from copybit image to mdp image structure */
|
||||
static void set_image(struct mdp_img *img, const struct copybit_image_t *rhs)
|
||||
{
|
||||
private_handle_t* hnd = (private_handle_t*)rhs->handle;
|
||||
if(hnd == NULL){
|
||||
ALOGE("copybit: Invalid handle");
|
||||
return;
|
||||
}
|
||||
img->width = rhs->w;
|
||||
img->height = rhs->h;
|
||||
img->format = get_format(rhs->format);
|
||||
img->offset = (uint32_t)hnd->offset;
|
||||
img->memory_id = hnd->fd;
|
||||
}
|
||||
/** setup rectangles */
|
||||
static bool set_rects(struct copybit_context_t *dev,
|
||||
struct mdp_blit_req *e,
|
||||
const struct copybit_rect_t *dst,
|
||||
const struct copybit_rect_t *src,
|
||||
const struct copybit_rect_t *scissor) {
|
||||
struct copybit_rect_t clip;
|
||||
intersect(&clip, scissor, dst);
|
||||
|
||||
if (!validateCopybitRect(&clip))
|
||||
return false;
|
||||
|
||||
e->dst_rect.x = clip.l;
|
||||
e->dst_rect.y = clip.t;
|
||||
e->dst_rect.w = clip.r - clip.l;
|
||||
e->dst_rect.h = clip.b - clip.t;
|
||||
|
||||
uint32_t W, H, delta_x, delta_y;
|
||||
if (dev->mFlags & COPYBIT_TRANSFORM_ROT_90) {
|
||||
delta_x = (clip.t - dst->t);
|
||||
delta_y = (dst->r - clip.r);
|
||||
e->src_rect.w = (clip.b - clip.t);
|
||||
e->src_rect.h = (clip.r - clip.l);
|
||||
W = dst->b - dst->t;
|
||||
H = dst->r - dst->l;
|
||||
} else {
|
||||
delta_x = (clip.l - dst->l);
|
||||
delta_y = (clip.t - dst->t);
|
||||
e->src_rect.w = (clip.r - clip.l);
|
||||
e->src_rect.h = (clip.b - clip.t);
|
||||
W = dst->r - dst->l;
|
||||
H = dst->b - dst->t;
|
||||
}
|
||||
|
||||
MULDIV(&delta_x, &e->src_rect.w, src->r - src->l, W);
|
||||
MULDIV(&delta_y, &e->src_rect.h, src->b - src->t, H);
|
||||
|
||||
e->src_rect.x = delta_x + src->l;
|
||||
e->src_rect.y = delta_y + src->t;
|
||||
|
||||
if (dev->mFlags & COPYBIT_TRANSFORM_FLIP_V) {
|
||||
if (dev->mFlags & COPYBIT_TRANSFORM_ROT_90) {
|
||||
e->src_rect.x = (src->l + src->r) - (e->src_rect.x + e->src_rect.w);
|
||||
}else{
|
||||
e->src_rect.y = (src->t + src->b) - (e->src_rect.y + e->src_rect.h);
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->mFlags & COPYBIT_TRANSFORM_FLIP_H) {
|
||||
if (dev->mFlags & COPYBIT_TRANSFORM_ROT_90) {
|
||||
e->src_rect.y = (src->t + src->b) - (e->src_rect.y + e->src_rect.h);
|
||||
}else{
|
||||
e->src_rect.x = (src->l + src->r) - (e->src_rect.x + e->src_rect.w);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** setup mdp request */
|
||||
static void set_infos(struct copybit_context_t *dev,
|
||||
struct mdp_blit_req *req, int flags)
|
||||
{
|
||||
req->alpha = dev->mAlpha;
|
||||
req->fps = dev->dynamic_fps;
|
||||
req->transp_mask = MDP_TRANSP_NOP;
|
||||
req->flags = dev->mFlags | flags;
|
||||
// check if we are blitting to f/b
|
||||
if (COPYBIT_ENABLE == dev->mBlitToFB) {
|
||||
req->flags |= MDP_MEMORY_ID_TYPE_FB;
|
||||
}
|
||||
#if defined(COPYBIT_QSD8K)
|
||||
req->flags |= MDP_BLEND_FG_PREMULT;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** copy the bits */
|
||||
static int msm_copybit(struct copybit_context_t *dev, void const *list)
|
||||
{
|
||||
int err;
|
||||
if (dev->relFence != -1) {
|
||||
close(dev->relFence);
|
||||
dev->relFence = -1;
|
||||
}
|
||||
err = ioctl(dev->mFD, MSMFB_ASYNC_BLIT,
|
||||
(struct mdp_async_blit_req_list const*)list);
|
||||
ALOGE_IF(err<0, "copyBits failed (%s)", strerror(errno));
|
||||
if (err == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
#if DEBUG_MDP_ERRORS
|
||||
struct mdp_async_blit_req_list const* l =
|
||||
(struct mdp_async_blit_req_list const*)list;
|
||||
for (unsigned int i=0 ; i<l->count ; i++) {
|
||||
ALOGE("%d: src={w=%d, h=%d, f=%d, rect={%d,%d,%d,%d}}\n"
|
||||
" dst={w=%d, h=%d, f=%d, rect={%d,%d,%d,%d}}\n"
|
||||
" flags=%08x, fps=%d"
|
||||
,
|
||||
i,
|
||||
l->req[i].src.width,
|
||||
l->req[i].src.height,
|
||||
l->req[i].src.format,
|
||||
l->req[i].src_rect.x,
|
||||
l->req[i].src_rect.y,
|
||||
l->req[i].src_rect.w,
|
||||
l->req[i].src_rect.h,
|
||||
l->req[i].dst.width,
|
||||
l->req[i].dst.height,
|
||||
l->req[i].dst.format,
|
||||
l->req[i].dst_rect.x,
|
||||
l->req[i].dst_rect.y,
|
||||
l->req[i].dst_rect.w,
|
||||
l->req[i].dst_rect.h,
|
||||
l->req[i].flags,
|
||||
l->req[i].fps
|
||||
);
|
||||
}
|
||||
#endif
|
||||
return -errno;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Set a parameter to value */
|
||||
static int set_parameter_copybit(
|
||||
struct copybit_device_t *dev,
|
||||
int name,
|
||||
int value)
|
||||
{
|
||||
struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
|
||||
int status = 0;
|
||||
if (ctx) {
|
||||
switch(name) {
|
||||
case COPYBIT_ROTATION_DEG:
|
||||
switch (value) {
|
||||
case 0:
|
||||
ctx->mFlags &= ~0x7;
|
||||
break;
|
||||
case 90:
|
||||
ctx->mFlags &= ~0x7;
|
||||
ctx->mFlags |= MDP_ROT_90;
|
||||
break;
|
||||
case 180:
|
||||
ctx->mFlags &= ~0x7;
|
||||
ctx->mFlags |= MDP_ROT_180;
|
||||
break;
|
||||
case 270:
|
||||
ctx->mFlags &= ~0x7;
|
||||
ctx->mFlags |= MDP_ROT_270;
|
||||
break;
|
||||
default:
|
||||
ALOGE("Invalid value for COPYBIT_ROTATION_DEG");
|
||||
status = -EINVAL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case COPYBIT_PLANE_ALPHA:
|
||||
if (value < 0) value = MDP_ALPHA_NOP;
|
||||
if (value >= 256) value = 255;
|
||||
ctx->mAlpha = (uint8_t)value;
|
||||
break;
|
||||
case COPYBIT_DYNAMIC_FPS:
|
||||
ctx->dynamic_fps = (uint8_t)value;
|
||||
break;
|
||||
case COPYBIT_DITHER:
|
||||
if (value == COPYBIT_ENABLE) {
|
||||
ctx->mFlags |= MDP_DITHER;
|
||||
} else if (value == COPYBIT_DISABLE) {
|
||||
ctx->mFlags &= ~MDP_DITHER;
|
||||
}
|
||||
break;
|
||||
case COPYBIT_BLUR:
|
||||
if (value == COPYBIT_ENABLE) {
|
||||
ctx->mFlags |= MDP_BLUR;
|
||||
} else if (value == COPYBIT_DISABLE) {
|
||||
ctx->mFlags &= ~MDP_BLUR;
|
||||
}
|
||||
break;
|
||||
case COPYBIT_BLEND_MODE:
|
||||
if(value == COPYBIT_BLENDING_PREMULT) {
|
||||
ctx->mFlags |= MDP_BLEND_FG_PREMULT;
|
||||
} else {
|
||||
ctx->mFlags &= ~MDP_BLEND_FG_PREMULT;
|
||||
}
|
||||
break;
|
||||
case COPYBIT_TRANSFORM:
|
||||
ctx->mFlags &= ~0x7;
|
||||
ctx->mFlags |= value & 0x7;
|
||||
break;
|
||||
case COPYBIT_BLIT_TO_FRAMEBUFFER:
|
||||
if (COPYBIT_ENABLE == value) {
|
||||
ctx->mBlitToFB = value;
|
||||
} else if (COPYBIT_DISABLE == value) {
|
||||
ctx->mBlitToFB = value;
|
||||
} else {
|
||||
ALOGE ("%s:Invalid input for COPYBIT_BLIT_TO_FRAMEBUFFER : %d",
|
||||
__FUNCTION__, value);
|
||||
}
|
||||
break;
|
||||
case COPYBIT_FG_LAYER:
|
||||
if(value == COPYBIT_ENABLE) {
|
||||
ctx->mFlags |= MDP_IS_FG;
|
||||
} else if (value == COPYBIT_DISABLE) {
|
||||
ctx->mFlags &= ~MDP_IS_FG;
|
||||
}
|
||||
break ;
|
||||
default:
|
||||
status = -EINVAL;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
status = -EINVAL;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/** Get a static info value */
|
||||
static int get(struct copybit_device_t *dev, int name)
|
||||
{
|
||||
struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
|
||||
int value;
|
||||
if (ctx) {
|
||||
switch(name) {
|
||||
case COPYBIT_MINIFICATION_LIMIT:
|
||||
value = MAX_SCALE_FACTOR;
|
||||
break;
|
||||
case COPYBIT_MAGNIFICATION_LIMIT:
|
||||
value = MAX_SCALE_FACTOR;
|
||||
break;
|
||||
case COPYBIT_SCALING_FRAC_BITS:
|
||||
value = 32;
|
||||
break;
|
||||
case COPYBIT_ROTATION_STEP_DEG:
|
||||
value = 90;
|
||||
break;
|
||||
default:
|
||||
value = -EINVAL;
|
||||
}
|
||||
} else {
|
||||
value = -EINVAL;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
static int set_sync_copybit(struct copybit_device_t *dev,
|
||||
int acquireFenceFd)
|
||||
{
|
||||
struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
|
||||
if (acquireFenceFd != -1) {
|
||||
if (ctx->list.sync.acq_fen_fd_cnt < (MDP_MAX_FENCE_FD - 1)) {
|
||||
ctx->acqFence[ctx->list.sync.acq_fen_fd_cnt++] = acquireFenceFd;
|
||||
} else {
|
||||
int ret = -EINVAL;
|
||||
struct blitReq *list = &ctx->list;
|
||||
|
||||
// Since fence is full kick off what is already in the list
|
||||
ret = msm_copybit(ctx, list);
|
||||
if (ret < 0) {
|
||||
ALOGE("%s: Blit call failed", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
list->count = 0;
|
||||
list->sync.acq_fen_fd_cnt = 0;
|
||||
ctx->acqFence[list->sync.acq_fen_fd_cnt++] = acquireFenceFd;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** do a stretch blit type operation */
|
||||
static int stretch_copybit(
|
||||
struct copybit_device_t *dev,
|
||||
struct copybit_image_t const *dst,
|
||||
struct copybit_image_t const *src,
|
||||
struct copybit_rect_t const *dst_rect,
|
||||
struct copybit_rect_t const *src_rect,
|
||||
struct copybit_region_t const *region)
|
||||
{
|
||||
struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
|
||||
struct blitReq *list;
|
||||
int status = 0;
|
||||
private_handle_t *yv12_handle = NULL;
|
||||
|
||||
if (ctx) {
|
||||
list = &ctx->list;
|
||||
|
||||
if (ctx->mAlpha < 255) {
|
||||
switch (src->format) {
|
||||
// we don't support plane alpha with RGBA formats
|
||||
case HAL_PIXEL_FORMAT_RGBA_8888:
|
||||
case HAL_PIXEL_FORMAT_BGRA_8888:
|
||||
case HAL_PIXEL_FORMAT_RGBA_5551:
|
||||
case HAL_PIXEL_FORMAT_RGBA_4444:
|
||||
ALOGE ("%s : Unsupported Pixel format %d", __FUNCTION__,
|
||||
src->format);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (src_rect->l < 0 || (uint32_t)src_rect->r > src->w ||
|
||||
src_rect->t < 0 || (uint32_t)src_rect->b > src->h) {
|
||||
// this is always invalid
|
||||
ALOGE ("%s : Invalid source rectangle : src_rect l %d t %d r %d b %d",\
|
||||
__FUNCTION__, src_rect->l, src_rect->t, src_rect->r, src_rect->b);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (src->w > MAX_DIMENSION || src->h > MAX_DIMENSION) {
|
||||
ALOGE ("%s : Invalid source dimensions w %d h %d", __FUNCTION__, src->w, src->h);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (dst->w > MAX_DIMENSION || dst->h > MAX_DIMENSION) {
|
||||
ALOGE ("%s : Invalid DST dimensions w %d h %d", __FUNCTION__, dst->w, dst->h);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if(src->format == HAL_PIXEL_FORMAT_YV12) {
|
||||
int usage =
|
||||
GRALLOC_USAGE_PRIVATE_IOMMU_HEAP | GRALLOC_USAGE_PRIVATE_UNCACHED;
|
||||
if (0 == alloc_buffer(&yv12_handle,src->w,src->h,
|
||||
src->format, usage)){
|
||||
if(0 == convertYV12toYCrCb420SP(src,yv12_handle)){
|
||||
(const_cast<copybit_image_t *>(src))->format =
|
||||
HAL_PIXEL_FORMAT_YCrCb_420_SP;
|
||||
(const_cast<copybit_image_t *>(src))->handle =
|
||||
yv12_handle;
|
||||
(const_cast<copybit_image_t *>(src))->base =
|
||||
(void *)yv12_handle->base;
|
||||
}
|
||||
else{
|
||||
ALOGE("Error copybit conversion from yv12 failed");
|
||||
if(yv12_handle)
|
||||
free_buffer(yv12_handle);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
else{
|
||||
ALOGE("Error:unable to allocate memeory for yv12 software conversion");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
const uint32_t maxCount =
|
||||
(uint32_t)(sizeof(list->req)/sizeof(list->req[0]));
|
||||
const struct copybit_rect_t bounds = { 0, 0, (int)dst->w, (int)dst->h };
|
||||
struct copybit_rect_t clip;
|
||||
status = 0;
|
||||
while ((status == 0) && region->next(region, &clip)) {
|
||||
intersect(&clip, &bounds, &clip);
|
||||
mdp_blit_req* req = &list->req[list->count];
|
||||
int flags = 0;
|
||||
|
||||
private_handle_t* src_hnd = (private_handle_t*)src->handle;
|
||||
if(src_hnd != NULL &&
|
||||
(!(src_hnd->flags & private_handle_t::PRIV_FLAGS_CACHED))) {
|
||||
flags |= MDP_BLIT_NON_CACHED;
|
||||
}
|
||||
|
||||
// Set Color Space for MDP to configure CSC matrix
|
||||
req->color_space = ITU_R_601;
|
||||
MetaData_t *metadata = NULL;
|
||||
|
||||
if (src_hnd != NULL)
|
||||
metadata = (MetaData_t *)src_hnd->base_metadata;
|
||||
|
||||
if (metadata && (metadata->operation & UPDATE_COLOR_SPACE)) {
|
||||
req->color_space = metadata->colorSpace;
|
||||
}
|
||||
|
||||
set_infos(ctx, req, flags);
|
||||
set_image(&req->dst, dst);
|
||||
set_image(&req->src, src);
|
||||
if (set_rects(ctx, req, dst_rect, src_rect, &clip) == false)
|
||||
continue;
|
||||
|
||||
if (req->src_rect.w<=0 || req->src_rect.h<=0)
|
||||
continue;
|
||||
|
||||
if (req->dst_rect.w<=0 || req->dst_rect.h<=0)
|
||||
continue;
|
||||
|
||||
if (++list->count == maxCount) {
|
||||
status = msm_copybit(ctx, list);
|
||||
list->sync.acq_fen_fd_cnt = 0;
|
||||
list->count = 0;
|
||||
}
|
||||
}
|
||||
if(yv12_handle) {
|
||||
//Before freeing the buffer we need buffer passed through blit call
|
||||
if (list->count != 0) {
|
||||
status = msm_copybit(ctx, list);
|
||||
list->sync.acq_fen_fd_cnt = 0;
|
||||
list->count = 0;
|
||||
}
|
||||
free_buffer(yv12_handle);
|
||||
}
|
||||
} else {
|
||||
ALOGE ("%s : Invalid COPYBIT context", __FUNCTION__);
|
||||
status = -EINVAL;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/** Perform a blit type operation */
|
||||
static int blit_copybit(
|
||||
struct copybit_device_t *dev,
|
||||
struct copybit_image_t const *dst,
|
||||
struct copybit_image_t const *src,
|
||||
struct copybit_region_t const *region)
|
||||
{
|
||||
struct copybit_rect_t dr = { 0, 0, (int)dst->w, (int)dst->h };
|
||||
struct copybit_rect_t sr = { 0, 0, (int)src->w, (int)src->h };
|
||||
return stretch_copybit(dev, dst, src, &dr, &sr, region);
|
||||
}
|
||||
|
||||
static int finish_copybit(struct copybit_device_t *dev)
|
||||
{
|
||||
// NOP for MDP copybit
|
||||
if(!dev)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int clear_copybit(struct copybit_device_t *dev,
|
||||
struct copybit_image_t const *buf,
|
||||
struct copybit_rect_t *rect)
|
||||
{
|
||||
struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
|
||||
uint32_t color = 0; // black color
|
||||
|
||||
if (!ctx) {
|
||||
ALOGE ("%s: Invalid copybit context", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
struct blitReq list1;
|
||||
memset((char *)&list1 , 0 ,sizeof (struct blitReq) );
|
||||
list1.count = 1;
|
||||
int my_tmp_get_fence = -1;
|
||||
|
||||
list1.sync.acq_fen_fd = ctx->acqFence;
|
||||
list1.sync.rel_fen_fd = &my_tmp_get_fence;
|
||||
list1.sync.acq_fen_fd_cnt = ctx->list.sync.acq_fen_fd_cnt;
|
||||
mdp_blit_req* req = &list1.req[0];
|
||||
|
||||
if(!req) {
|
||||
ALOGE ("%s : Invalid request", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
set_image(&req->dst, buf);
|
||||
set_image(&req->src, buf);
|
||||
|
||||
if (rect->l < 0 || (uint32_t)(rect->r - rect->l) > req->dst.width ||
|
||||
rect->t < 0 || (uint32_t)(rect->b - rect->t) > req->dst.height) {
|
||||
ALOGE ("%s : Invalid rect : src_rect l %d t %d r %d b %d",\
|
||||
__FUNCTION__, rect->l, rect->t, rect->r, rect->b);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
req->dst_rect.x = rect->l;
|
||||
req->dst_rect.y = rect->t;
|
||||
req->dst_rect.w = rect->r - rect->l;
|
||||
req->dst_rect.h = rect->b - rect->t;
|
||||
|
||||
req->src_rect = req->dst_rect;
|
||||
|
||||
req->const_color.b = (uint32_t)((color >> 16) & 0xff);
|
||||
req->const_color.g = (uint32_t)((color >> 8) & 0xff);
|
||||
req->const_color.r = (uint32_t)((color >> 0) & 0xff);
|
||||
req->const_color.alpha = MDP_ALPHA_NOP;
|
||||
|
||||
req->transp_mask = MDP_TRANSP_NOP;
|
||||
req->flags = MDP_SOLID_FILL | MDP_MEMORY_ID_TYPE_FB | MDP_BLEND_FG_PREMULT;
|
||||
int status = msm_copybit(ctx, &list1);
|
||||
|
||||
ctx->list.sync.acq_fen_fd_cnt = 0;
|
||||
if (my_tmp_get_fence != -1)
|
||||
close(my_tmp_get_fence);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/** Fill the rect on dst with RGBA color **/
|
||||
static int fill_color(struct copybit_device_t *dev,
|
||||
struct copybit_image_t const *dst,
|
||||
struct copybit_rect_t const *rect,
|
||||
uint32_t color)
|
||||
{
|
||||
struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
|
||||
if (!ctx) {
|
||||
ALOGE("%s: Invalid copybit context", __FUNCTION__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (dst->w > MAX_DIMENSION || dst->h > MAX_DIMENSION) {
|
||||
ALOGE("%s: Invalid DST w=%d h=%d", __FUNCTION__, dst->w, dst->h);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (rect->l < 0 || (uint32_t)(rect->r - rect->l) > dst->w ||
|
||||
rect->t < 0 || (uint32_t)(rect->b - rect->t) > dst->h) {
|
||||
ALOGE("%s: Invalid destination rect: l=%d t=%d r=%d b=%d",
|
||||
__FUNCTION__, rect->l, rect->t, rect->r, rect->b);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int status = 0;
|
||||
struct blitReq* list = &ctx->list;
|
||||
mdp_blit_req* req = &list->req[list->count++];
|
||||
set_infos(ctx, req, MDP_SOLID_FILL);
|
||||
set_image(&req->src, dst);
|
||||
set_image(&req->dst, dst);
|
||||
|
||||
req->dst_rect.x = rect->l;
|
||||
req->dst_rect.y = rect->t;
|
||||
req->dst_rect.w = rect->r - rect->l;
|
||||
req->dst_rect.h = rect->b - rect->t;
|
||||
req->src_rect = req->dst_rect;
|
||||
|
||||
req->const_color.r = (uint32_t)((color >> 0) & 0xff);
|
||||
req->const_color.g = (uint32_t)((color >> 8) & 0xff);
|
||||
req->const_color.b = (uint32_t)((color >> 16) & 0xff);
|
||||
req->const_color.alpha = (uint32_t)((color >> 24) & 0xff);
|
||||
|
||||
if (list->count == sizeof(list->req)/sizeof(list->req[0])) {
|
||||
status = msm_copybit(ctx, list);
|
||||
list->sync.acq_fen_fd_cnt = 0;
|
||||
list->count = 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Close the copybit device */
|
||||
static int close_copybit(struct hw_device_t *dev)
|
||||
{
|
||||
struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
|
||||
if (ctx) {
|
||||
close(ctx->mFD);
|
||||
free(ctx);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int flush_get_fence(struct copybit_device_t *dev, int* fd)
|
||||
{
|
||||
struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
|
||||
struct blitReq *list = &ctx->list;
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (list->count) {
|
||||
ret = msm_copybit(ctx, list);
|
||||
if (ret < 0)
|
||||
ALOGE("%s: Blit call failed", __FUNCTION__);
|
||||
list->count = 0;
|
||||
}
|
||||
*fd = ctx->relFence;
|
||||
list->sync.acq_fen_fd_cnt = 0;
|
||||
ctx->relFence = -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Open a new instance of a copybit device using name */
|
||||
static int open_copybit(const struct hw_module_t* module, const char* name,
|
||||
struct hw_device_t** device)
|
||||
{
|
||||
int status = -EINVAL;
|
||||
|
||||
if (strcmp(name, COPYBIT_HARDWARE_COPYBIT0)) {
|
||||
return COPYBIT_FAILURE;
|
||||
}
|
||||
copybit_context_t *ctx;
|
||||
ctx = (copybit_context_t *)malloc(sizeof(copybit_context_t));
|
||||
|
||||
if (ctx == NULL ) {
|
||||
return COPYBIT_FAILURE;
|
||||
}
|
||||
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
|
||||
ctx->device.common.tag = HARDWARE_DEVICE_TAG;
|
||||
ctx->device.common.version = 1;
|
||||
ctx->device.common.module = const_cast<hw_module_t*>(module);
|
||||
ctx->device.common.close = close_copybit;
|
||||
ctx->device.set_parameter = set_parameter_copybit;
|
||||
ctx->device.get = get;
|
||||
ctx->device.blit = blit_copybit;
|
||||
ctx->device.set_sync = set_sync_copybit;
|
||||
ctx->device.stretch = stretch_copybit;
|
||||
ctx->device.finish = finish_copybit;
|
||||
ctx->device.fill_color = fill_color;
|
||||
ctx->device.flush_get_fence = flush_get_fence;
|
||||
ctx->device.clear = clear_copybit;
|
||||
ctx->mAlpha = MDP_ALPHA_NOP;
|
||||
//dynamic_fps is zero means default
|
||||
//panel refresh rate for driver.
|
||||
ctx->dynamic_fps = 0;
|
||||
ctx->mFlags = 0;
|
||||
ctx->sync.flags = 0;
|
||||
ctx->relFence = -1;
|
||||
for (int i=0; i < MDP_MAX_FENCE_FD; i++) {
|
||||
ctx->acqFence[i] = -1;
|
||||
}
|
||||
ctx->sync.acq_fen_fd = ctx->acqFence;
|
||||
ctx->sync.rel_fen_fd = &ctx->relFence;
|
||||
ctx->list.count = 0;
|
||||
ctx->list.sync.acq_fen_fd_cnt = 0;
|
||||
ctx->list.sync.rel_fen_fd = ctx->sync.rel_fen_fd;
|
||||
ctx->list.sync.acq_fen_fd = ctx->sync.acq_fen_fd;
|
||||
ctx->mFD = open("/dev/graphics/fb0", O_RDWR, 0);
|
||||
if (ctx->mFD < 0) {
|
||||
status = errno;
|
||||
ALOGE("Error opening frame buffer errno=%d (%s)",
|
||||
status, strerror(status));
|
||||
status = -status;
|
||||
} else {
|
||||
status = 0;
|
||||
*device = &ctx->device.common;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
@@ -1,319 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Not a Contribution, Apache license notifications and license are retained
|
||||
* for attribution purposes only.
|
||||
*
|
||||
* 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 ANDROID_COPYBIT_INTERFACE_H
|
||||
#define ANDROID_COPYBIT_INTERFACE_H
|
||||
|
||||
#include <hardware/hardware.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/types.h>
|
||||
#include <gralloc_priv.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* The id of this module
|
||||
*/
|
||||
#define COPYBIT_HARDWARE_MODULE_ID "copybit"
|
||||
|
||||
/**
|
||||
* Name of the graphics device to open
|
||||
*/
|
||||
#define COPYBIT_HARDWARE_COPYBIT0 "copybit0"
|
||||
|
||||
/* supported pixel-formats. these must be compatible with
|
||||
* graphics/PixelFormat.java, ui/PixelFormat.h, pixelflinger/format.h
|
||||
*/
|
||||
enum {
|
||||
COPYBIT_FORMAT_RGBA_8888 = HAL_PIXEL_FORMAT_RGBA_8888,
|
||||
COPYBIT_FORMAT_RGBX_8888 = HAL_PIXEL_FORMAT_RGBX_8888,
|
||||
COPYBIT_FORMAT_RGB_888 = HAL_PIXEL_FORMAT_RGB_888,
|
||||
COPYBIT_FORMAT_RGB_565 = HAL_PIXEL_FORMAT_RGB_565,
|
||||
COPYBIT_FORMAT_BGRA_8888 = HAL_PIXEL_FORMAT_BGRA_8888,
|
||||
COPYBIT_FORMAT_RGBA_5551 = HAL_PIXEL_FORMAT_RGBA_5551,
|
||||
COPYBIT_FORMAT_RGBA_4444 = HAL_PIXEL_FORMAT_RGBA_4444,
|
||||
COPYBIT_FORMAT_YCbCr_422_SP = 0x10,
|
||||
COPYBIT_FORMAT_YCrCb_420_SP = 0x11,
|
||||
};
|
||||
|
||||
/* name for copybit_set_parameter */
|
||||
enum {
|
||||
/* Default blit destination is offline buffer */
|
||||
/* clients to set this to '1', if blitting to framebuffer */
|
||||
/* and reset to '0', after calling blit/stretch */
|
||||
COPYBIT_BLIT_TO_FRAMEBUFFER = 0,
|
||||
/* rotation of the source image in degrees (0 to 359) */
|
||||
COPYBIT_ROTATION_DEG = 1,
|
||||
/* plane alpha value */
|
||||
COPYBIT_PLANE_ALPHA = 2,
|
||||
/* enable or disable dithering */
|
||||
COPYBIT_DITHER = 3,
|
||||
/* transformation applied (this is a superset of COPYBIT_ROTATION_DEG) */
|
||||
COPYBIT_TRANSFORM = 4,
|
||||
/* blurs the copied bitmap. The amount of blurring cannot be changed
|
||||
* at this time. */
|
||||
COPYBIT_BLUR = 5,
|
||||
/* Blend mode */
|
||||
COPYBIT_BLEND_MODE = 6,
|
||||
/* FB width */
|
||||
COPYBIT_FRAMEBUFFER_WIDTH = 7,
|
||||
/* FB height */
|
||||
COPYBIT_FRAMEBUFFER_HEIGHT = 8,
|
||||
COPYBIT_FG_LAYER = 9,
|
||||
COPYBIT_DYNAMIC_FPS = 10,
|
||||
/* Source Format Mode */
|
||||
COPYBIT_SRC_FORMAT_MODE = 11,
|
||||
/* Destination Format Mode */
|
||||
COPYBIT_DST_FORMAT_MODE = 12,
|
||||
};
|
||||
|
||||
/* values for copybit_set_parameter(COPYBIT_TRANSFORM) */
|
||||
enum {
|
||||
/* flip source image horizontally */
|
||||
COPYBIT_TRANSFORM_FLIP_H = HAL_TRANSFORM_FLIP_H,
|
||||
/* flip source image vertically */
|
||||
COPYBIT_TRANSFORM_FLIP_V = HAL_TRANSFORM_FLIP_V,
|
||||
/* rotate source image 90 degres */
|
||||
COPYBIT_TRANSFORM_ROT_90 = HAL_TRANSFORM_ROT_90,
|
||||
/* rotate source image 180 degres */
|
||||
COPYBIT_TRANSFORM_ROT_180 = HAL_TRANSFORM_ROT_180,
|
||||
/* rotate source image 270 degres */
|
||||
COPYBIT_TRANSFORM_ROT_270 = HAL_TRANSFORM_ROT_270,
|
||||
};
|
||||
|
||||
/* enable/disable value copybit_set_parameter */
|
||||
enum {
|
||||
COPYBIT_DISABLE = 0,
|
||||
COPYBIT_ENABLE = 1
|
||||
};
|
||||
|
||||
/*
|
||||
* copybit blending values. same as HWC blending values
|
||||
*/
|
||||
enum {
|
||||
/* no blending */
|
||||
COPYBIT_BLENDING_NONE = 0x0100,
|
||||
|
||||
/* ONE / ONE_MINUS_SRC_ALPHA */
|
||||
COPYBIT_BLENDING_PREMULT = 0x0105,
|
||||
|
||||
/* SRC_ALPHA / ONE_MINUS_SRC_ALPHA */
|
||||
COPYBIT_BLENDING_COVERAGE = 0x0405
|
||||
};
|
||||
|
||||
enum {
|
||||
/* Linear format mode*/
|
||||
COPYBIT_LINEAR = 0x0000,
|
||||
/* UBWC format mode*/
|
||||
COPYBIT_UBWC_COMPRESSED = 0x0001,
|
||||
};
|
||||
|
||||
/* use get_static_info() to query static informations about the hardware */
|
||||
enum {
|
||||
/* Maximum amount of minification supported by the hardware*/
|
||||
COPYBIT_MINIFICATION_LIMIT = 1,
|
||||
/* Maximum amount of magnification supported by the hardware */
|
||||
COPYBIT_MAGNIFICATION_LIMIT = 2,
|
||||
/* Number of fractional bits support by the scaling engine */
|
||||
COPYBIT_SCALING_FRAC_BITS = 3,
|
||||
/* Supported rotation step in degres. */
|
||||
COPYBIT_ROTATION_STEP_DEG = 4,
|
||||
/* UBWC support*/
|
||||
COPYBIT_UBWC_SUPPORT = 5,
|
||||
};
|
||||
|
||||
/* Image structure */
|
||||
struct copybit_image_t {
|
||||
/* width */
|
||||
uint32_t w;
|
||||
/* height */
|
||||
uint32_t h;
|
||||
/* format COPYBIT_FORMAT_xxx */
|
||||
int32_t format;
|
||||
/* base of buffer with image */
|
||||
void *base;
|
||||
/* handle to the image */
|
||||
native_handle_t* handle;
|
||||
/* number of pixels added for the stride */
|
||||
uint32_t horiz_padding;
|
||||
/* number of pixels added for the vertical stride */
|
||||
uint32_t vert_padding;
|
||||
};
|
||||
|
||||
/* Rectangle */
|
||||
struct copybit_rect_t {
|
||||
/* left */
|
||||
int l;
|
||||
/* top */
|
||||
int t;
|
||||
/* right */
|
||||
int r;
|
||||
/* bottom */
|
||||
int b;
|
||||
};
|
||||
|
||||
/* Region */
|
||||
struct copybit_region_t {
|
||||
int (*next)(struct copybit_region_t const *region, struct copybit_rect_t *rect);
|
||||
};
|
||||
|
||||
/**
|
||||
* Every hardware module must have a data structure named HAL_MODULE_INFO_SYM
|
||||
* and the fields of this data structure must begin with hw_module_t
|
||||
* followed by module specific information.
|
||||
*/
|
||||
struct copybit_module_t {
|
||||
struct hw_module_t common;
|
||||
};
|
||||
|
||||
/**
|
||||
* Every device data structure must begin with hw_device_t
|
||||
* followed by module specific public methods and attributes.
|
||||
*/
|
||||
struct copybit_device_t {
|
||||
struct hw_device_t common;
|
||||
|
||||
/**
|
||||
* Set a copybit parameter.
|
||||
*
|
||||
* @param dev from open
|
||||
* @param name one for the COPYBIT_NAME_xxx
|
||||
* @param value one of the COPYBIT_VALUE_xxx
|
||||
*
|
||||
* @return 0 if successful
|
||||
*/
|
||||
int (*set_parameter)(struct copybit_device_t *dev, int name, int value);
|
||||
|
||||
/**
|
||||
* Get a static copybit information.
|
||||
*
|
||||
* @param dev from open
|
||||
* @param name one of the COPYBIT_STATIC_xxx
|
||||
*
|
||||
* @return value or -EINVAL if error
|
||||
*/
|
||||
int (*get)(struct copybit_device_t *dev, int name);
|
||||
|
||||
/**
|
||||
* Execute the bit blit copy operation
|
||||
*
|
||||
* @param dev from open
|
||||
* @param dst is the destination image
|
||||
* @param src is the source image
|
||||
* @param region the clip region
|
||||
*
|
||||
* @return 0 if successful
|
||||
*/
|
||||
int (*blit)(struct copybit_device_t *dev,
|
||||
struct copybit_image_t const *dst,
|
||||
struct copybit_image_t const *src,
|
||||
struct copybit_region_t const *region);
|
||||
|
||||
/**
|
||||
* Give acquire fence to copybit to be used in upcoming stretch
|
||||
* call
|
||||
*
|
||||
* @param dev from open
|
||||
* @param acquireFenceFd is the acquire fence
|
||||
*
|
||||
* @return 0 if successful
|
||||
*/
|
||||
int (*set_sync)(struct copybit_device_t *dev,
|
||||
int acquireFenceFd);
|
||||
|
||||
/**
|
||||
* Execute the stretch bit blit copy operation
|
||||
*
|
||||
* @param dev from open
|
||||
* @param dst is the destination image
|
||||
* @param src is the source image
|
||||
* @param dst_rect is the destination rectangle
|
||||
* @param src_rect is the source rectangle
|
||||
* @param region the clip region
|
||||
*
|
||||
* @return 0 if successful
|
||||
*/
|
||||
int (*stretch)(struct copybit_device_t *dev,
|
||||
struct copybit_image_t const *dst,
|
||||
struct copybit_image_t const *src,
|
||||
struct copybit_rect_t const *dst_rect,
|
||||
struct copybit_rect_t const *src_rect,
|
||||
struct copybit_region_t const *region);
|
||||
|
||||
/**
|
||||
* Fill the rect on dst with RGBA color
|
||||
*
|
||||
* @param dev from open
|
||||
* @param dst is destination image
|
||||
* @param rect is destination rectangle
|
||||
* @param color is RGBA color to fill
|
||||
*
|
||||
* @return 0 if successful
|
||||
*/
|
||||
int (*fill_color)(struct copybit_device_t *dev,
|
||||
struct copybit_image_t const *dst,
|
||||
struct copybit_rect_t const *rect,
|
||||
uint32_t color);
|
||||
|
||||
/**
|
||||
* Execute the completion of the copybit draw operation.
|
||||
*
|
||||
* @param dev from open
|
||||
*
|
||||
* @return 0 if successful
|
||||
*/
|
||||
int (*finish)(struct copybit_device_t *dev);
|
||||
|
||||
/**
|
||||
* Trigger the copybit draw operation(async).
|
||||
*
|
||||
* @param dev from open
|
||||
*
|
||||
* @param fd - gets the fencefd
|
||||
*
|
||||
* @return 0 if successful
|
||||
*/
|
||||
int (*flush_get_fence)(struct copybit_device_t *dev, int* fd);
|
||||
|
||||
/* Clears the buffer
|
||||
*/
|
||||
int (*clear)(struct copybit_device_t *dev, struct copybit_image_t const *buf,
|
||||
struct copybit_rect_t *rect);
|
||||
};
|
||||
|
||||
|
||||
/** convenience API for opening and closing a device */
|
||||
|
||||
static inline int copybit_open(const struct hw_module_t* module,
|
||||
struct copybit_device_t** device) {
|
||||
return module->methods->open(module,
|
||||
COPYBIT_HARDWARE_COPYBIT0, (struct hw_device_t**)device);
|
||||
}
|
||||
|
||||
static inline int copybit_close(struct copybit_device_t* device) {
|
||||
return device->common.close(&device->common);
|
||||
}
|
||||
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif // ANDROID_COPYBIT_INTERFACE_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 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 <copybit.h>
|
||||
struct copybit_iterator : public copybit_region_t {
|
||||
copybit_iterator(const copybit_rect_t& rect) {
|
||||
mRect = rect;
|
||||
mCount = 1;
|
||||
this->next = iterate;
|
||||
}
|
||||
private:
|
||||
static int iterate(copybit_region_t const * self, copybit_rect_t* rect) {
|
||||
if (!self || !rect) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
copybit_iterator const* me = static_cast<copybit_iterator const*>(self);
|
||||
if (me->mCount) {
|
||||
rect->l = me->mRect.l;
|
||||
rect->t = me->mRect.t;
|
||||
rect->r = me->mRect.r;
|
||||
rect->b = me->mRect.b;
|
||||
me->mCount--;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
copybit_rect_t mRect;
|
||||
mutable int mCount;
|
||||
};
|
||||
@@ -1,263 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2014, 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 <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include "software_converter.h"
|
||||
|
||||
/** Convert YV12 to YCrCb_420_SP */
|
||||
int convertYV12toYCrCb420SP(const copybit_image_t *src, private_handle_t *yv12_handle)
|
||||
{
|
||||
private_handle_t* hnd = (private_handle_t*)src->handle;
|
||||
|
||||
if(hnd == NULL || yv12_handle == NULL){
|
||||
ALOGE("Invalid handle");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Please refer to the description of YV12 in hardware.h
|
||||
// for the formulae used to calculate buffer sizes and offsets
|
||||
|
||||
// In a copybit_image_t, w is the stride and
|
||||
// stride - horiz_padding is the actual width
|
||||
// vertical stride is the same as height, so not considered
|
||||
unsigned int stride = src->w;
|
||||
unsigned int width = src->w - src->horiz_padding;
|
||||
unsigned int height = src->h;
|
||||
unsigned int y_size = stride * src->h;
|
||||
unsigned int c_width = ALIGN(stride/2, (unsigned int)16);
|
||||
unsigned int c_size = c_width * src->h/2;
|
||||
unsigned int chromaPadding = c_width - width/2;
|
||||
unsigned int chromaSize = c_size * 2;
|
||||
unsigned char* newChroma = (unsigned char *)(yv12_handle->base + y_size);
|
||||
unsigned char* oldChroma = (unsigned char*)(hnd->base + y_size);
|
||||
memcpy((char *)yv12_handle->base,(char *)hnd->base,y_size);
|
||||
|
||||
#if defined(__ARM_HAVE_NEON) && !defined(__aarch64__)
|
||||
/* interleave */
|
||||
if(!chromaPadding) {
|
||||
unsigned char * t1 = newChroma;
|
||||
unsigned char * t2 = oldChroma;
|
||||
unsigned char * t3 = t2 + chromaSize/2;
|
||||
for(unsigned int i=0; i < (chromaSize/2)>>3; i++) {
|
||||
__asm__ __volatile__ (
|
||||
"vld1.u8 d0, [%0]! \n"
|
||||
"vld1.u8 d1, [%1]! \n"
|
||||
"vst2.u8 {d0, d1}, [%2]! \n"
|
||||
:"+r"(t2), "+r"(t3), "+r"(t1)
|
||||
:
|
||||
:"memory","d0","d1"
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
#else //__ARM_HAVE_NEON
|
||||
if(!chromaPadding) {
|
||||
for(unsigned int i = 0; i< chromaSize/2; i++) {
|
||||
newChroma[i*2] = oldChroma[i];
|
||||
newChroma[i*2+1] = oldChroma[i+chromaSize/2];
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
// If the image is not aligned to 16 pixels,
|
||||
// convert using the C routine below
|
||||
// r1 tracks the row of the source buffer
|
||||
// r2 tracks the row of the destination buffer
|
||||
// The width/2 checks are to avoid copying
|
||||
// from the padding
|
||||
|
||||
if(chromaPadding) {
|
||||
unsigned int r1 = 0, r2 = 0, i = 0, j = 0;
|
||||
while(r1 < height/2) {
|
||||
if(j == width) {
|
||||
j = 0;
|
||||
r2++;
|
||||
continue;
|
||||
}
|
||||
if (j+1 == width) {
|
||||
newChroma[r2*width + j] = oldChroma[r1*c_width+i];
|
||||
r2++;
|
||||
newChroma[r2*width] = oldChroma[r1*c_width+i+c_size];
|
||||
j = 1;
|
||||
} else {
|
||||
newChroma[r2*width + j] = oldChroma[r1*c_width+i];
|
||||
newChroma[r2*width + j + 1] = oldChroma[r1*c_width+i+c_size];
|
||||
j+=2;
|
||||
}
|
||||
i++;
|
||||
if (i == width/2 ) {
|
||||
i = 0;
|
||||
r1++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct copyInfo{
|
||||
int width;
|
||||
int height;
|
||||
int src_stride;
|
||||
int dst_stride;
|
||||
size_t src_plane1_offset;
|
||||
size_t src_plane2_offset;
|
||||
size_t dst_plane1_offset;
|
||||
size_t dst_plane2_offset;
|
||||
};
|
||||
|
||||
/* Internal function to do the actual copy of source to destination */
|
||||
static int copy_source_to_destination(const uintptr_t src_base,
|
||||
const uintptr_t dst_base,
|
||||
copyInfo& info)
|
||||
{
|
||||
if (!src_base || !dst_base) {
|
||||
ALOGE("%s: invalid memory src_base = 0x%p dst_base=0x%p",
|
||||
__FUNCTION__, (void*)src_base, (void*)dst_base);
|
||||
return COPYBIT_FAILURE;
|
||||
}
|
||||
|
||||
int width = info.width;
|
||||
int height = info.height;
|
||||
unsigned char *src = (unsigned char*)src_base;
|
||||
unsigned char *dst = (unsigned char*)dst_base;
|
||||
|
||||
// Copy the luma
|
||||
for (int i = 0; i < height; i++) {
|
||||
memcpy(dst, src, width);
|
||||
src += info.src_stride;
|
||||
dst += info.dst_stride;
|
||||
}
|
||||
|
||||
// Copy plane 1
|
||||
src = (unsigned char*)(src_base + info.src_plane1_offset);
|
||||
dst = (unsigned char*)(dst_base + info.dst_plane1_offset);
|
||||
width = width/2;
|
||||
height = height/2;
|
||||
for (int i = 0; i < height; i++) {
|
||||
memcpy(dst, src, info.src_stride);
|
||||
src += info.src_stride;
|
||||
dst += info.dst_stride;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Function to convert the c2d format into an equivalent Android format
|
||||
*
|
||||
* @param: source buffer handle
|
||||
* @param: destination image
|
||||
*
|
||||
* @return: return status
|
||||
*/
|
||||
int convert_yuv_c2d_to_yuv_android(private_handle_t *hnd,
|
||||
struct copybit_image_t const *rhs)
|
||||
{
|
||||
ALOGD("Enter %s", __FUNCTION__);
|
||||
if (!hnd || !rhs) {
|
||||
ALOGE("%s: invalid inputs hnd=%p rhs=%p", __FUNCTION__, hnd, rhs);
|
||||
return COPYBIT_FAILURE;
|
||||
}
|
||||
|
||||
int ret = COPYBIT_SUCCESS;
|
||||
private_handle_t *dst_hnd = (private_handle_t *)rhs->handle;
|
||||
|
||||
copyInfo info;
|
||||
info.width = rhs->w;
|
||||
info.height = rhs->h;
|
||||
info.src_stride = ALIGN(info.width, 32);
|
||||
info.dst_stride = ALIGN(info.width, 16);
|
||||
switch(rhs->format) {
|
||||
case HAL_PIXEL_FORMAT_YCbCr_420_SP:
|
||||
case HAL_PIXEL_FORMAT_YCrCb_420_SP: {
|
||||
info.src_plane1_offset = info.src_stride*info.height;
|
||||
info.dst_plane1_offset = info.dst_stride*info.height;
|
||||
} break;
|
||||
case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: {
|
||||
// Chroma is 2K aligned for the NV12 encodeable format.
|
||||
info.src_plane1_offset = ALIGN(info.src_stride*info.height, 2048);
|
||||
info.dst_plane1_offset = ALIGN(info.dst_stride*info.height, 2048);
|
||||
} break;
|
||||
default:
|
||||
ALOGE("%s: unsupported format (format=0x%x)", __FUNCTION__,
|
||||
rhs->format);
|
||||
return COPYBIT_FAILURE;
|
||||
}
|
||||
|
||||
ret = copy_source_to_destination((uintptr_t) hnd->base, (uintptr_t) dst_hnd->base, info);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function to convert the Android format into an equivalent C2D format
|
||||
*
|
||||
* @param: source buffer handle
|
||||
* @param: destination image
|
||||
*
|
||||
* @return: return status
|
||||
*/
|
||||
int convert_yuv_android_to_yuv_c2d(private_handle_t *hnd,
|
||||
struct copybit_image_t const *rhs)
|
||||
{
|
||||
if (!hnd || !rhs) {
|
||||
ALOGE("%s: invalid inputs hnd=%p rhs=%p", __FUNCTION__, hnd, rhs);
|
||||
return COPYBIT_FAILURE;
|
||||
}
|
||||
|
||||
int ret = COPYBIT_SUCCESS;
|
||||
private_handle_t *dst_hnd = (private_handle_t *)rhs->handle;
|
||||
|
||||
copyInfo info;
|
||||
info.width = rhs->w;
|
||||
info.height = rhs->h;
|
||||
info.src_stride = ALIGN(hnd->width, 16);
|
||||
info.dst_stride = ALIGN(info.width, 32);
|
||||
switch(rhs->format) {
|
||||
case HAL_PIXEL_FORMAT_YCbCr_420_SP:
|
||||
case HAL_PIXEL_FORMAT_YCrCb_420_SP: {
|
||||
info.src_plane1_offset = info.src_stride*info.height;
|
||||
info.dst_plane1_offset = info.dst_stride*info.height;
|
||||
} break;
|
||||
case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: {
|
||||
// Chroma is 2K aligned for the NV12 encodeable format.
|
||||
info.src_plane1_offset = ALIGN(info.src_stride*info.height, 2048);
|
||||
info.dst_plane1_offset = ALIGN(info.dst_stride*info.height, 2048);
|
||||
} break;
|
||||
default:
|
||||
ALOGE("%s: unsupported format (format=0x%x)", __FUNCTION__,
|
||||
rhs->format);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = copy_source_to_destination((uintptr_t) hnd->base, (uintptr_t) dst_hnd->base, info);
|
||||
return ret;
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 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 <copybit.h>
|
||||
#include "gralloc_priv.h"
|
||||
|
||||
#define COPYBIT_SUCCESS 0
|
||||
#define COPYBIT_FAILURE -1
|
||||
|
||||
#define ALIGN(x, y) (((x) + y - 1) & (~(y - 1)))
|
||||
|
||||
int convertYV12toYCrCb420SP(const copybit_image_t *src,private_handle_t *yv12_handle);
|
||||
|
||||
/*
|
||||
* Function to convert the c2d format into an equivalent Android format
|
||||
*
|
||||
* @param: source buffer handle
|
||||
* @param: destination image
|
||||
*
|
||||
* @return: return status
|
||||
*/
|
||||
int convert_yuv_c2d_to_yuv_android(private_handle_t *hnd,
|
||||
struct copybit_image_t const *rhs);
|
||||
|
||||
|
||||
/*
|
||||
* Function to convert the Android format into an equivalent C2D format
|
||||
*
|
||||
* @param: source buffer handle
|
||||
* @param: destination image
|
||||
*
|
||||
* @return: return status
|
||||
*/
|
||||
int convert_yuv_android_to_yuv_c2d(private_handle_t *hnd,
|
||||
struct copybit_image_t const *rhs);
|
||||
@@ -1,14 +0,0 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE := libdisplaydebug
|
||||
LOCAL_VENDOR_MODULE := true
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_SHARED_LIBRARIES := libdl
|
||||
LOCAL_CFLAGS := -DLOG_TAG=\"SDM\" -Wall -std=c++11 -Werror -fno-operator-names
|
||||
LOCAL_CLANG := true
|
||||
LOCAL_SRC_FILES := debug_handler.cpp
|
||||
LOCAL_COPY_HEADERS_TO := qcom/display
|
||||
LOCAL_COPY_HEADERS := debug_handler.h
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
@@ -1,60 +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 "debug_handler.h"
|
||||
|
||||
namespace display {
|
||||
|
||||
// By default, drop any log messages/traces. It need to be overridden by client.
|
||||
class DefaultDebugHandler : public DebugHandler {
|
||||
public:
|
||||
virtual void Error(const char *, ...) { }
|
||||
virtual void Warning(const char *, ...) { }
|
||||
virtual void Info(const char *, ...) { }
|
||||
virtual void Debug(const char *, ...) { }
|
||||
virtual void Verbose(const char *, ...) { }
|
||||
virtual void BeginTrace(const char *, const char *, const char *) { }
|
||||
virtual void EndTrace() { }
|
||||
virtual int GetProperty(const char *, int *) { return -1; }
|
||||
virtual int GetProperty(const char *, char *) { return -1; }
|
||||
};
|
||||
|
||||
DefaultDebugHandler g_default_debug_handler;
|
||||
DebugHandler * DebugHandler::debug_handler_ = &g_default_debug_handler;
|
||||
std::bitset<32> DebugHandler::log_mask_ = 0x1; // Always print logs tagged with value 0
|
||||
|
||||
void DebugHandler::Set(DebugHandler *debug_handler) {
|
||||
if (debug_handler) {
|
||||
debug_handler_ = debug_handler;
|
||||
} else {
|
||||
debug_handler_ = &g_default_debug_handler;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace display
|
||||
@@ -1,101 +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 __DEBUG_HANDLER_H__
|
||||
#define __DEBUG_HANDLER_H__
|
||||
|
||||
#include <bitset>
|
||||
|
||||
#define DLOG(method, format, ...) \
|
||||
display::DebugHandler::Get()->method(__CLASS__ "::%s: " format, __FUNCTION__, ##__VA_ARGS__)
|
||||
|
||||
#define DLOG_IF(tag, method, format, ...) \
|
||||
if (display::DebugHandler::GetLogMask()[tag]) { \
|
||||
DLOG(method, format, ##__VA_ARGS__); \
|
||||
}
|
||||
|
||||
#define DLOGE_IF(tag, format, ...) DLOG_IF(tag, Error, format, ##__VA_ARGS__)
|
||||
#define DLOGW_IF(tag, format, ...) DLOG_IF(tag, Warning, format, ##__VA_ARGS__)
|
||||
#define DLOGI_IF(tag, format, ...) DLOG_IF(tag, Info, format, ##__VA_ARGS__)
|
||||
#define DLOGD_IF(tag, format, ...) DLOG_IF(tag, Debug, format, ##__VA_ARGS__)
|
||||
#define DLOGV_IF(tag, format, ...) DLOG_IF(tag, Verbose, format, ##__VA_ARGS__)
|
||||
|
||||
#define DLOGE(format, ...) DLOG(Error, format, ##__VA_ARGS__)
|
||||
#define DLOGW(format, ...) DLOG(Warning, format, ##__VA_ARGS__)
|
||||
#define DLOGI(format, ...) DLOG(Info, format, ##__VA_ARGS__)
|
||||
#define DLOGD(format, ...) DLOG(Debug, format, ##__VA_ARGS__)
|
||||
#define DLOGV(format, ...) DLOG(Verbose, format, ##__VA_ARGS__)
|
||||
|
||||
#define DTRACE_BEGIN(custom_string) display::DebugHandler::Get()->BeginTrace( \
|
||||
__CLASS__, __FUNCTION__, custom_string)
|
||||
#define DTRACE_END() display::DebugHandler::Get()->EndTrace()
|
||||
#define DTRACE_SCOPED() display::ScopeTracer <display::DebugHandler> \
|
||||
scope_tracer(__CLASS__, __FUNCTION__)
|
||||
|
||||
namespace display {
|
||||
|
||||
class DebugHandler {
|
||||
public:
|
||||
virtual void Error(const char *format, ...) = 0;
|
||||
virtual void Warning(const char *format, ...) = 0;
|
||||
virtual void Info(const char *format, ...) = 0;
|
||||
virtual void Debug(const char *format, ...) = 0;
|
||||
virtual void Verbose(const char *format, ...) = 0;
|
||||
virtual void BeginTrace(const char *class_name, const char *function_name,
|
||||
const char *custom_string) = 0;
|
||||
virtual void EndTrace() = 0;
|
||||
virtual int GetProperty(const char *property_name, int *value) = 0;
|
||||
virtual int GetProperty(const char *property_name, char *value) = 0;
|
||||
|
||||
static inline DebugHandler *Get() { return debug_handler_; }
|
||||
static void Set(DebugHandler *debug_handler);
|
||||
static inline std::bitset<32> & GetLogMask() { return log_mask_; }
|
||||
static void SetLogMask(const std::bitset<32> &log_mask) { log_mask_ = log_mask; }
|
||||
|
||||
protected:
|
||||
virtual ~DebugHandler() { }
|
||||
|
||||
private:
|
||||
static DebugHandler *debug_handler_;
|
||||
static std::bitset<32> log_mask_;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class ScopeTracer {
|
||||
public:
|
||||
ScopeTracer(const char *class_name, const char *function_name) {
|
||||
T::Get()->BeginTrace(class_name, function_name, "");
|
||||
}
|
||||
|
||||
~ScopeTracer() { T::Get()->EndTrace(); }
|
||||
};
|
||||
|
||||
} // namespace display
|
||||
|
||||
#endif // __DEBUG_HANDLER_H__
|
||||
@@ -1,18 +0,0 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE := libdrmutils
|
||||
LOCAL_VENDOR_MODULE := true
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_C_INCLUDES := external/libdrm \
|
||||
$(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
|
||||
LOCAL_HEADER_LIBRARIES := display_headers
|
||||
LOCAL_SHARED_LIBRARIES := libdrm libdl libdisplaydebug
|
||||
LOCAL_CFLAGS := -DLOG_TAG=\"DRMUTILS\" -Wall -std=c++11 -Werror -fno-operator-names
|
||||
LOCAL_CLANG := true
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
|
||||
LOCAL_SRC_FILES := drm_master.cpp drm_res_mgr.cpp drm_lib_loader.cpp
|
||||
LOCAL_COPY_HEADERS_TO := qcom/display
|
||||
LOCAL_COPY_HEADERS := drm_master.h drm_res_mgr.h drm_lib_loader.h drm_logger.h drm_interface.h
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
@@ -1,718 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017-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 __DRM_INTERFACE_H__
|
||||
#define __DRM_INTERFACE_H__
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "xf86drm.h"
|
||||
#include "xf86drmMode.h"
|
||||
#include <drm/msm_drm.h>
|
||||
|
||||
namespace sde_drm {
|
||||
|
||||
typedef std::map<std::pair<uint32_t, uint64_t>, float> CompRatioMap;
|
||||
|
||||
/*
|
||||
* Drm Atomic Operation Codes
|
||||
*/
|
||||
enum struct DRMOps {
|
||||
/*
|
||||
* Op: Sets plane source crop
|
||||
* Arg: uint32_t - Plane ID
|
||||
* DRMRect - Source Rectangle
|
||||
*/
|
||||
PLANE_SET_SRC_RECT,
|
||||
/*
|
||||
* Op: Sets plane destination rect
|
||||
* Arg: uint32_t - Plane ID
|
||||
* DRMRect - Dst Rectangle
|
||||
*/
|
||||
PLANE_SET_DST_RECT,
|
||||
/*
|
||||
* Op: Sets plane zorder
|
||||
* Arg: uint32_t - Plane ID
|
||||
* uint32_t - zorder
|
||||
*/
|
||||
PLANE_SET_ZORDER,
|
||||
/*
|
||||
* Op: Sets plane rotation flags
|
||||
* Arg: uint32_t - Plane ID
|
||||
* uint32_t - bit mask of rotation flags (See drm_mode.h for enums)
|
||||
*/
|
||||
PLANE_SET_ROTATION,
|
||||
/*
|
||||
* Op: Sets plane alpha
|
||||
* Arg: uint32_t - Plane ID
|
||||
* uint32_t - alpha value
|
||||
*/
|
||||
PLANE_SET_ALPHA,
|
||||
/*
|
||||
* Op: Sets the blend type
|
||||
* Arg: uint32_t - Plane ID
|
||||
* uint32_t - blend type (see DRMBlendType)
|
||||
*/
|
||||
PLANE_SET_BLEND_TYPE,
|
||||
/*
|
||||
* Op: Sets horizontal decimation
|
||||
* Arg: uint32_t - Plane ID
|
||||
* uint32_t - decimation factor
|
||||
*/
|
||||
PLANE_SET_H_DECIMATION,
|
||||
/*
|
||||
* Op: Sets vertical decimation
|
||||
* Arg: uint32_t - Plane ID
|
||||
* uint32_t - decimation factor
|
||||
*/
|
||||
PLANE_SET_V_DECIMATION,
|
||||
/*
|
||||
* Op: Sets source config flags
|
||||
* Arg: uint32_t - Plane ID
|
||||
* uint32_t - flags to enable or disable a specific op. E.g. deinterlacing
|
||||
*/
|
||||
PLANE_SET_SRC_CONFIG,
|
||||
/*
|
||||
* Op: Sets frame buffer ID for plane. Set together with CRTC.
|
||||
* Arg: uint32_t - Plane ID
|
||||
* uint32_t - Framebuffer ID
|
||||
*/
|
||||
PLANE_SET_FB_ID,
|
||||
/*
|
||||
* Op: Sets the crtc for this plane. Set together with FB_ID.
|
||||
* Arg: uint32_t - Plane ID
|
||||
* uint32_t - CRTC ID
|
||||
*/
|
||||
PLANE_SET_CRTC,
|
||||
/*
|
||||
* Op: Sets acquire fence for this plane's buffer. Set together with FB_ID, CRTC.
|
||||
* Arg: uint32_t - Plane ID
|
||||
* uint32_t - Input fence
|
||||
*/
|
||||
PLANE_SET_INPUT_FENCE,
|
||||
/*
|
||||
* Op: Sets scaler config on this plane.
|
||||
* Arg: uint32_t - Plane ID
|
||||
* uint64_t - Address of the scaler config object (version based)
|
||||
*/
|
||||
PLANE_SET_SCALER_CONFIG,
|
||||
/*
|
||||
* Op: Sets plane rotation destination rect
|
||||
* Arg: uint32_t - Plane ID
|
||||
* DRMRect - rotator dst Rectangle
|
||||
*/
|
||||
PLANE_SET_ROTATION_DST_RECT,
|
||||
/*
|
||||
* Op: Sets FB Secure mode for this plane.
|
||||
* Arg: uint32_t - Plane ID
|
||||
* uint32_t - Value of the FB Secure mode.
|
||||
*/
|
||||
PLANE_SET_FB_SECURE_MODE,
|
||||
/*
|
||||
* Op: Sets csc config on this plane.
|
||||
* Arg: uint32_t - Plane ID
|
||||
* uint32_t* - pointer to csc type
|
||||
*/
|
||||
PLANE_SET_CSC_CONFIG,
|
||||
/*
|
||||
* Op: Sets multirect mode on this plane.
|
||||
* Arg: uint32_t - Plane ID
|
||||
* uint32_t - multirect mode
|
||||
*/
|
||||
PLANE_SET_MULTIRECT_MODE,
|
||||
/*
|
||||
* Op: Activate or deactivate a CRTC
|
||||
* Arg: uint32_t - CRTC ID
|
||||
* uint32_t - 1 to enable, 0 to disable
|
||||
*/
|
||||
CRTC_SET_ACTIVE,
|
||||
/*
|
||||
* Op: Sets display mode
|
||||
* Arg: uint32_t - CRTC ID
|
||||
* drmModeModeInfo* - Pointer to display mode
|
||||
*/
|
||||
CRTC_SET_MODE,
|
||||
/*
|
||||
* Op: Sets an offset indicating when a release fence should be signalled.
|
||||
* Arg: uint32_t - offset
|
||||
* 0: non-speculative, default
|
||||
* 1: speculative
|
||||
*/
|
||||
CRTC_SET_OUTPUT_FENCE_OFFSET,
|
||||
/*
|
||||
* Op: Sets overall SDE core clock
|
||||
* Arg: uint32_t - CRTC ID
|
||||
* uint32_t - core_clk
|
||||
*/
|
||||
CRTC_SET_CORE_CLK,
|
||||
/*
|
||||
* Op: Sets MNOC bus average bandwidth
|
||||
* Arg: uint32_t - CRTC ID
|
||||
* uint32_t - core_ab
|
||||
*/
|
||||
CRTC_SET_CORE_AB,
|
||||
/*
|
||||
* Op: Sets MNOC bus instantaneous bandwidth
|
||||
* Arg: uint32_t - CRTC ID
|
||||
* uint32_t - core_ib
|
||||
*/
|
||||
CRTC_SET_CORE_IB,
|
||||
/*
|
||||
* Op: Sets LLCC Bus average bandwidth
|
||||
* Arg: uint32_t - CRTC ID
|
||||
* uint32_t - llcc_ab
|
||||
*/
|
||||
CRTC_SET_LLCC_AB,
|
||||
/*
|
||||
* Op: Sets LLCC Bus instantaneous bandwidth
|
||||
* Arg: uint32_t - CRTC ID
|
||||
* uint32_t - llcc_ib
|
||||
*/
|
||||
CRTC_SET_LLCC_IB,
|
||||
/*
|
||||
* Op: Sets DRAM bus average bandwidth
|
||||
* Arg: uint32_t - CRTC ID
|
||||
* uint32_t - dram_ab
|
||||
*/
|
||||
CRTC_SET_DRAM_AB,
|
||||
/*
|
||||
* Op: Sets DRAM bus instantaneous bandwidth
|
||||
* Arg: uint32_t - CRTC ID
|
||||
* uint32_t - dram_ib
|
||||
*/
|
||||
CRTC_SET_DRAM_IB,
|
||||
/*
|
||||
* Op: Sets Rotator BW for inline rotation
|
||||
* Arg: uint32_t - CRTC ID
|
||||
* uint32_t - rot_bw
|
||||
*/
|
||||
CRTC_SET_ROT_PREFILL_BW,
|
||||
/*
|
||||
* Op: Sets rotator clock for inline rotation
|
||||
* Arg: uint32_t - CRTC ID
|
||||
* uint32_t - rot_clk
|
||||
*/
|
||||
CRTC_SET_ROT_CLK,
|
||||
/*
|
||||
* Op: Sets destination scalar data
|
||||
* Arg: uint32_t - CRTC ID
|
||||
* uint64_t - Pointer to destination scalar data
|
||||
*/
|
||||
CRTC_SET_DEST_SCALER_CONFIG,
|
||||
/*
|
||||
* Op: Returns release fence for this frame. Should be called after Commit() on
|
||||
* DRMAtomicReqInterface.
|
||||
* Arg: uint32_t - CRTC ID
|
||||
* int * - Pointer to an integer that will hold the returned fence
|
||||
*/
|
||||
CRTC_GET_RELEASE_FENCE,
|
||||
/*
|
||||
* Op: Sets PP feature
|
||||
* Arg: uint32_t - CRTC ID
|
||||
* DRMPPFeatureInfo * - PP feature data pointer
|
||||
*/
|
||||
CRTC_SET_POST_PROC,
|
||||
/*
|
||||
* Op: Sets CRTC ROIs.
|
||||
* Arg: uint32_t - CRTC ID
|
||||
* uint32_t - number of ROIs
|
||||
* DRMRect * - Array of CRTC ROIs
|
||||
*/
|
||||
CRTC_SET_ROI,
|
||||
/*
|
||||
* Op: Sets Security level for CRTC.
|
||||
* Arg: uint32_t - CRTC ID
|
||||
* uint32_t - Security level
|
||||
*/
|
||||
CRTC_SET_SECURITY_LEVEL,
|
||||
/*
|
||||
* Op: sets solid fill stages
|
||||
* Arg: uint32_t - CRTC ID
|
||||
* Vector of DRMSolidfillStage
|
||||
*/
|
||||
CRTC_SET_SOLIDFILL_STAGES,
|
||||
/*
|
||||
* Op: Sets idle timeout.
|
||||
* Arg: uint32_t - CRTC ID
|
||||
* uint32_t - idle timeout in ms
|
||||
*/
|
||||
CRTC_SET_IDLE_TIMEOUT,
|
||||
/*
|
||||
* Op: Returns retire fence for this commit. Should be called after Commit() on
|
||||
* DRMAtomicReqInterface.
|
||||
* Arg: uint32_t - Connector ID
|
||||
* int * - Pointer to an integer that will hold the returned fence
|
||||
*/
|
||||
CONNECTOR_GET_RETIRE_FENCE,
|
||||
/*
|
||||
* Op: Sets writeback connector destination rect
|
||||
* Arg: uint32_t - Connector ID
|
||||
* DRMRect - Dst Rectangle
|
||||
*/
|
||||
CONNECTOR_SET_OUTPUT_RECT,
|
||||
/*
|
||||
* Op: Sets frame buffer ID for writeback connector.
|
||||
* Arg: uint32_t - Connector ID
|
||||
* uint32_t - Framebuffer ID
|
||||
*/
|
||||
CONNECTOR_SET_OUTPUT_FB_ID,
|
||||
/*
|
||||
* Op: Sets power mode for connector.
|
||||
* Arg: uint32_t - Connector ID
|
||||
* uint32_t - Power Mode
|
||||
*/
|
||||
CONNECTOR_SET_POWER_MODE,
|
||||
/*
|
||||
* Op: Sets panel ROIs.
|
||||
* Arg: uint32_t - Connector ID
|
||||
* uint32_t - number of ROIs
|
||||
* DRMRect * - Array of Connector ROIs
|
||||
*/
|
||||
CONNECTOR_SET_ROI,
|
||||
/*
|
||||
* Op: Sets the connector to autorefresh mode.
|
||||
* Arg: uint32_t - Connector ID
|
||||
* uint32_t - Enable-1, Disable-0
|
||||
*/
|
||||
CONNECTOR_SET_AUTOREFRESH,
|
||||
/*
|
||||
* Op: Set FB secure mode for Writeback connector.
|
||||
* Arg: uint32_t - Connector ID
|
||||
* uint32_t - FB Secure mode
|
||||
*/
|
||||
CONNECTOR_SET_FB_SECURE_MODE,
|
||||
/*
|
||||
* Op: Sets a crtc id to this connector
|
||||
* Arg: uint32_t - Connector ID
|
||||
* uint32_t - CRTC ID
|
||||
*/
|
||||
CONNECTOR_SET_CRTC,
|
||||
/*
|
||||
* Op: Sets PP feature
|
||||
* Arg: uint32_t - Connector ID
|
||||
* DRMPPFeatureInfo * - PP feature data pointer
|
||||
*/
|
||||
CONNECTOR_SET_POST_PROC,
|
||||
/*
|
||||
* Op: Sets connector hdr metadata
|
||||
* Arg: uint32_t - Connector ID
|
||||
* drm_msm_ext_hdr_metadata - hdr_metadata
|
||||
*/
|
||||
CONNECTOR_SET_HDR_METADATA,
|
||||
};
|
||||
|
||||
enum struct DRMRotation {
|
||||
FLIP_H = 0x1,
|
||||
FLIP_V = 0x2,
|
||||
ROT_180 = FLIP_H | FLIP_V,
|
||||
ROT_90 = 0x4,
|
||||
};
|
||||
|
||||
enum struct DRMPowerMode {
|
||||
ON,
|
||||
DOZE,
|
||||
DOZE_SUSPEND,
|
||||
OFF,
|
||||
};
|
||||
|
||||
enum struct DRMBlendType {
|
||||
UNDEFINED = 0,
|
||||
OPAQUE = 1,
|
||||
PREMULTIPLIED = 2,
|
||||
COVERAGE = 3,
|
||||
};
|
||||
|
||||
enum struct DRMSrcConfig {
|
||||
DEINTERLACE = 0,
|
||||
};
|
||||
|
||||
/* Display type to identify a suitable connector */
|
||||
enum struct DRMDisplayType {
|
||||
PERIPHERAL,
|
||||
TV,
|
||||
VIRTUAL,
|
||||
};
|
||||
|
||||
struct DRMRect {
|
||||
uint32_t left; // Left-most pixel coordinate.
|
||||
uint32_t top; // Top-most pixel coordinate.
|
||||
uint32_t right; // Right-most pixel coordinate.
|
||||
uint32_t bottom; // Bottom-most pixel coordinate.
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// DRM Info Query Types
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
enum struct QSEEDVersion {
|
||||
V1,
|
||||
V2,
|
||||
V3,
|
||||
};
|
||||
|
||||
/* QSEED3 Step version */
|
||||
enum struct QSEEDStepVersion {
|
||||
V2,
|
||||
V3,
|
||||
V4,
|
||||
};
|
||||
|
||||
enum struct SmartDMARevision {
|
||||
V1,
|
||||
V2,
|
||||
};
|
||||
|
||||
/* Per CRTC Resource Info*/
|
||||
struct DRMCrtcInfo {
|
||||
bool has_src_split;
|
||||
bool has_hdr;
|
||||
uint32_t max_blend_stages;
|
||||
uint32_t max_solidfill_stages;
|
||||
QSEEDVersion qseed_version;
|
||||
SmartDMARevision smart_dma_rev;
|
||||
float ib_fudge_factor;
|
||||
float clk_fudge_factor;
|
||||
uint32_t dest_scale_prefill_lines;
|
||||
uint32_t undersized_prefill_lines;
|
||||
uint32_t macrotile_prefill_lines;
|
||||
uint32_t nv12_prefill_lines;
|
||||
uint32_t linear_prefill_lines;
|
||||
uint32_t downscale_prefill_lines;
|
||||
uint32_t extra_prefill_lines;
|
||||
uint32_t amortized_threshold;
|
||||
uint64_t max_bandwidth_low;
|
||||
uint64_t max_bandwidth_high;
|
||||
uint32_t max_sde_clk;
|
||||
CompRatioMap comp_ratio_rt_map;
|
||||
CompRatioMap comp_ratio_nrt_map;
|
||||
uint32_t hw_version;
|
||||
uint32_t dest_scaler_count = 0;
|
||||
uint32_t max_dest_scaler_input_width = 0;
|
||||
uint32_t max_dest_scaler_output_width = 0;
|
||||
uint32_t max_dest_scale_up = 1;
|
||||
uint32_t min_prefill_lines = 0;
|
||||
};
|
||||
|
||||
enum struct DRMPlaneType {
|
||||
// Has CSC and scaling capability
|
||||
VIG = 0,
|
||||
// Has scaling capability but no CSC
|
||||
RGB,
|
||||
// No scaling support
|
||||
DMA,
|
||||
// Supports a small dimension and doesn't use a CRTC stage
|
||||
CURSOR,
|
||||
MAX,
|
||||
};
|
||||
|
||||
struct DRMPlaneTypeInfo {
|
||||
DRMPlaneType type;
|
||||
uint32_t master_plane_id;
|
||||
// FourCC format enum and modifier
|
||||
std::vector<std::pair<uint32_t, uint64_t>> formats_supported;
|
||||
uint32_t max_linewidth;
|
||||
uint32_t max_upscale;
|
||||
uint32_t max_downscale;
|
||||
uint32_t max_horizontal_deci;
|
||||
uint32_t max_vertical_deci;
|
||||
uint64_t max_pipe_bandwidth;
|
||||
uint32_t cache_size; // cache size in bytes for inline rotation support.
|
||||
QSEEDStepVersion qseed3_version;
|
||||
bool multirect_prop_present = false;
|
||||
};
|
||||
|
||||
// All DRM Planes as map<Plane_id , plane_type_info> listed from highest to lowest priority
|
||||
typedef std::vector<std::pair<uint32_t, DRMPlaneTypeInfo>> DRMPlanesInfo;
|
||||
|
||||
enum struct DRMTopology {
|
||||
UNKNOWN, // To be compat with driver defs in sde_rm.h
|
||||
SINGLE_LM,
|
||||
SINGLE_LM_DSC,
|
||||
DUAL_LM,
|
||||
DUAL_LM_DSC,
|
||||
DUAL_LM_MERGE,
|
||||
DUAL_LM_MERGE_DSC,
|
||||
DUAL_LM_DSCMERGE,
|
||||
PPSPLIT,
|
||||
};
|
||||
|
||||
enum struct DRMPanelMode {
|
||||
VIDEO,
|
||||
COMMAND,
|
||||
};
|
||||
|
||||
/* Per mode info */
|
||||
struct DRMModeInfo {
|
||||
drmModeModeInfo mode;
|
||||
DRMTopology topology;
|
||||
// Valid only if mode is command
|
||||
int num_roi;
|
||||
int xstart;
|
||||
int ystart;
|
||||
int walign;
|
||||
int halign;
|
||||
int wmin;
|
||||
int hmin;
|
||||
bool roi_merge;
|
||||
};
|
||||
|
||||
/* Per Connector Info*/
|
||||
struct DRMConnectorInfo {
|
||||
uint32_t mmWidth;
|
||||
uint32_t mmHeight;
|
||||
uint32_t type;
|
||||
std::vector<DRMModeInfo> modes;
|
||||
std::string panel_name;
|
||||
DRMPanelMode panel_mode;
|
||||
bool is_primary;
|
||||
// Valid only if DRMPanelMode is VIDEO
|
||||
bool dynamic_fps;
|
||||
// FourCC format enum and modifier
|
||||
std::vector<std::pair<uint32_t, uint64_t>> formats_supported;
|
||||
// Valid only if type is DRM_MODE_CONNECTOR_VIRTUAL
|
||||
uint32_t max_linewidth;
|
||||
DRMRotation panel_orientation;
|
||||
drm_panel_hdr_properties panel_hdr_prop;
|
||||
uint32_t transfer_time_us;
|
||||
drm_msm_ext_hdr_properties ext_hdr_prop;
|
||||
};
|
||||
|
||||
/* Identifier token for a display */
|
||||
struct DRMDisplayToken {
|
||||
uint32_t conn_id;
|
||||
uint32_t crtc_id;
|
||||
uint32_t crtc_index;
|
||||
};
|
||||
|
||||
enum DRMPPFeatureID {
|
||||
kFeaturePcc,
|
||||
kFeatureIgc,
|
||||
kFeaturePgc,
|
||||
kFeatureMixerGc,
|
||||
kFeaturePaV2,
|
||||
kFeatureDither,
|
||||
kFeatureGamut,
|
||||
kFeaturePADither,
|
||||
kFeaturePAHsic,
|
||||
kFeaturePASixZone,
|
||||
kFeaturePAMemColSkin,
|
||||
kFeaturePAMemColSky,
|
||||
kFeaturePAMemColFoliage,
|
||||
kFeaturePAMemColProt,
|
||||
kPPFeaturesMax,
|
||||
};
|
||||
|
||||
enum DRMPPPropType {
|
||||
kPropEnum,
|
||||
kPropRange,
|
||||
kPropBlob,
|
||||
kPropTypeMax,
|
||||
};
|
||||
|
||||
struct DRMPPFeatureInfo {
|
||||
DRMPPFeatureID id;
|
||||
DRMPPPropType type;
|
||||
uint32_t version;
|
||||
uint32_t payload_size;
|
||||
void *payload;
|
||||
uint32_t object_type;
|
||||
};
|
||||
|
||||
enum DRMCscType {
|
||||
kCscYuv2Rgb601L,
|
||||
kCscYuv2Rgb601FR,
|
||||
kCscYuv2Rgb709L,
|
||||
kCscYuv2Rgb2020L,
|
||||
kCscYuv2Rgb2020FR,
|
||||
kCscTypeMax,
|
||||
};
|
||||
|
||||
struct DRMScalerLUTInfo {
|
||||
uint32_t dir_lut_size = 0;
|
||||
uint32_t cir_lut_size = 0;
|
||||
uint32_t sep_lut_size = 0;
|
||||
uint64_t dir_lut = 0;
|
||||
uint64_t cir_lut = 0;
|
||||
uint64_t sep_lut = 0;
|
||||
};
|
||||
|
||||
enum struct DRMSecureMode {
|
||||
NON_SECURE,
|
||||
SECURE,
|
||||
NON_SECURE_DIR_TRANSLATION,
|
||||
SECURE_DIR_TRANSLATION,
|
||||
};
|
||||
|
||||
enum struct DRMSecurityLevel {
|
||||
SECURE_NON_SECURE,
|
||||
SECURE_ONLY,
|
||||
};
|
||||
|
||||
enum struct DRMMultiRectMode {
|
||||
NONE = 0,
|
||||
PARALLEL = 1,
|
||||
SERIAL = 2,
|
||||
};
|
||||
|
||||
struct DRMSolidfillStage {
|
||||
DRMRect bounding_rect {};
|
||||
bool is_exclusion_rect = false;
|
||||
uint32_t color = 0xff000000; // in 8bit argb
|
||||
uint32_t red = 0;
|
||||
uint32_t blue = 0;
|
||||
uint32_t green = 0;
|
||||
uint32_t alpha = 0xff;
|
||||
uint32_t color_bit_depth = 0;
|
||||
uint32_t z_order = 0;
|
||||
uint32_t plane_alpha = 0xff;
|
||||
};
|
||||
|
||||
/* DRM Atomic Request Property Set.
|
||||
*
|
||||
* Helper class to create and populate atomic properties of DRM components
|
||||
* when rendered in DRM atomic mode */
|
||||
class DRMAtomicReqInterface {
|
||||
public:
|
||||
virtual ~DRMAtomicReqInterface() {}
|
||||
/* Perform request operation.
|
||||
*
|
||||
* [input]: opcode: operation code from DRMOps list.
|
||||
* var_arg: arguments for DRMOps's can differ in number and
|
||||
* data type. Refer above DRMOps to details.
|
||||
* [return]: Error code if the API fails, 0 on success.
|
||||
*/
|
||||
virtual int Perform(DRMOps opcode, ...) = 0;
|
||||
|
||||
/*
|
||||
* Commit the params set via Perform(). Also resets the properties after commit. Needs to be
|
||||
* called every frame.
|
||||
* [input]: synchronous: Determines if the call should block until a h/w flip
|
||||
* [input]: retain_planes: Retains already staged planes. Useful when not explicitly programming
|
||||
* planes but still need the previously staged ones to not be unstaged
|
||||
* [return]: Error code if the API fails, 0 on success.
|
||||
*/
|
||||
virtual int Commit(bool synchronous, bool retain_planes) = 0;
|
||||
/*
|
||||
* Validate the params set via Perform().
|
||||
* [return]: Error code if the API fails, 0 on success.
|
||||
*/
|
||||
virtual int Validate() = 0;
|
||||
};
|
||||
|
||||
class DRMManagerInterface;
|
||||
|
||||
/* Populates a singleton instance of DRMManager */
|
||||
typedef int (*GetDRMManager)(int fd, DRMManagerInterface **intf);
|
||||
|
||||
/* Destroy DRMManager instance */
|
||||
typedef int (*DestroyDRMManager)();
|
||||
|
||||
/*
|
||||
* DRM Manager Interface - Any class which plans to implement helper function for vendor
|
||||
* specific DRM driver implementation must implement the below interface routines to work
|
||||
* with SDM.
|
||||
*/
|
||||
|
||||
class DRMManagerInterface {
|
||||
public:
|
||||
virtual ~DRMManagerInterface() {}
|
||||
|
||||
/*
|
||||
* Since SDM completely manages the planes. GetPlanesInfo will provide all
|
||||
* the plane information.
|
||||
* [output]: DRMPlanesInfo: Resource Info for planes.
|
||||
*/
|
||||
virtual void GetPlanesInfo(DRMPlanesInfo *info) = 0;
|
||||
|
||||
/*
|
||||
* Will provide all the information of a selected crtc.
|
||||
* [input]: Use crtc id 0 to obtain system wide info
|
||||
* [output]: DRMCrtcInfo: Resource Info for the given CRTC id.
|
||||
*/
|
||||
virtual void GetCrtcInfo(uint32_t crtc_id, DRMCrtcInfo *info) = 0;
|
||||
|
||||
/*
|
||||
* Will provide all the information of a selected connector.
|
||||
* [output]: DRMConnectorInfo: Resource Info for the given connector id
|
||||
*/
|
||||
virtual void GetConnectorInfo(uint32_t conn_id, DRMConnectorInfo *info) = 0;
|
||||
|
||||
/*
|
||||
* Will query post propcessing feature info of a CRTC.
|
||||
* [output]: DRMPPFeatureInfo: CRTC post processing feature info
|
||||
*/
|
||||
virtual void GetCrtcPPInfo(uint32_t crtc_id, DRMPPFeatureInfo *info) = 0;
|
||||
/*
|
||||
* Register a logical display to receive a token.
|
||||
* Each display pipeline in DRM is identified by its CRTC and Connector(s).
|
||||
* On display connect(bootup or hotplug), clients should invoke this interface to
|
||||
* establish the pipeline for the display and should get a DisplayToken
|
||||
* populated with crtc and connnector(s) id's. Here onwards, Client should
|
||||
* use this token to represent the display for any Perform operations if
|
||||
* needed.
|
||||
*
|
||||
* [input]: disp_type - Peripheral / TV / Virtual
|
||||
* [output]: DRMDisplayToken - CRTC and Connector id's for the display
|
||||
* [return]: 0 on success, a negative error value otherwise
|
||||
*/
|
||||
virtual int RegisterDisplay(DRMDisplayType disp_type, DRMDisplayToken *tok) = 0;
|
||||
|
||||
/* Client should invoke this interface on display disconnect.
|
||||
* [input]: DRMDisplayToken - identifier for the display.
|
||||
*/
|
||||
virtual void UnregisterDisplay(const DRMDisplayToken &token) = 0;
|
||||
|
||||
/*
|
||||
* Creates and returns an instance of DRMAtomicReqInterface corresponding to a display token
|
||||
* returned as part of RegisterDisplay API. Needs to be called per display.
|
||||
* [input]: DRMDisplayToken that identifies a display pipeline
|
||||
* [output]: Pointer to an instance of DRMAtomicReqInterface.
|
||||
* [return]: Error code if the API fails, 0 on success.
|
||||
*/
|
||||
virtual int CreateAtomicReq(const DRMDisplayToken &token, DRMAtomicReqInterface **intf) = 0;
|
||||
|
||||
/*
|
||||
* Destroys the instance of DRMAtomicReqInterface
|
||||
* [input]: Pointer to a DRMAtomicReqInterface
|
||||
* [return]: Error code if the API fails, 0 on success.
|
||||
*/
|
||||
virtual int DestroyAtomicReq(DRMAtomicReqInterface *intf) = 0;
|
||||
/*
|
||||
* Sets the global scaler LUT
|
||||
* [input]: LUT Info
|
||||
* [return]: Error code if the API fails, 0 on success.
|
||||
*/
|
||||
virtual int SetScalerLUT(const DRMScalerLUTInfo &lut_info) = 0;
|
||||
};
|
||||
|
||||
} // namespace sde_drm
|
||||
#endif // __DRM_INTERFACE_H__
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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 <dlfcn.h>
|
||||
|
||||
#include "drm_lib_loader.h"
|
||||
|
||||
#define __CLASS__ "DRMLibLoader"
|
||||
|
||||
using std::mutex;
|
||||
using std::lock_guard;
|
||||
|
||||
namespace drm_utils {
|
||||
|
||||
DRMLibLoader *DRMLibLoader::s_instance = nullptr;
|
||||
mutex DRMLibLoader::s_lock;
|
||||
|
||||
DRMLibLoader *DRMLibLoader::GetInstance() {
|
||||
lock_guard<mutex> obj(s_lock);
|
||||
|
||||
if (!s_instance) {
|
||||
s_instance = new DRMLibLoader();
|
||||
}
|
||||
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
void DRMLibLoader::Destroy() {
|
||||
lock_guard<mutex> obj(s_lock);
|
||||
if (s_instance) {
|
||||
delete s_instance;
|
||||
s_instance = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
DRMLibLoader::DRMLibLoader() {
|
||||
if (Open("libsdedrm.so")) {
|
||||
if (Sym("GetDRMManager", reinterpret_cast<void **>(&func_get_drm_manager_)) &&
|
||||
Sym("DestroyDRMManager", reinterpret_cast<void **>(&func_destroy_drm_manager_))) {
|
||||
is_loaded_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DRMLibLoader::~DRMLibLoader() {
|
||||
if (lib_) {
|
||||
::dlclose(lib_);
|
||||
lib_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool DRMLibLoader::Open(const char *lib_name) {
|
||||
lib_ = ::dlopen(lib_name, RTLD_NOW);
|
||||
|
||||
return (lib_ != nullptr);
|
||||
}
|
||||
|
||||
bool DRMLibLoader::Sym(const char *func_name, void **func_ptr) {
|
||||
if (lib_) {
|
||||
*func_ptr = ::dlsym(lib_, func_name);
|
||||
}
|
||||
|
||||
return (*func_ptr != nullptr);
|
||||
}
|
||||
|
||||
} // namespace drm_utils
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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 __DRM_LIB_LOADER_H__
|
||||
#define __DRM_LIB_LOADER_H__
|
||||
|
||||
#include <drm_interface.h>
|
||||
#include <mutex>
|
||||
|
||||
namespace drm_utils {
|
||||
|
||||
class DRMLibLoader {
|
||||
public:
|
||||
~DRMLibLoader();
|
||||
bool IsLoaded() { return is_loaded_; }
|
||||
sde_drm::GetDRMManager FuncGetDRMManager() { return func_get_drm_manager_; }
|
||||
sde_drm::DestroyDRMManager FuncDestroyDRMManager() { return func_destroy_drm_manager_; }
|
||||
|
||||
static DRMLibLoader *GetInstance();
|
||||
static void Destroy();
|
||||
|
||||
private:
|
||||
DRMLibLoader();
|
||||
bool Open(const char *lib_name);
|
||||
bool Sym(const char *func_name, void **func_ptr);
|
||||
|
||||
void *lib_ = {};
|
||||
sde_drm::GetDRMManager func_get_drm_manager_ = {};
|
||||
sde_drm::DestroyDRMManager func_destroy_drm_manager_ = {};
|
||||
bool is_loaded_ = false;
|
||||
|
||||
static DRMLibLoader *s_instance; // Singleton instance
|
||||
static std::mutex s_lock;
|
||||
};
|
||||
|
||||
} // namespace drm_utils
|
||||
|
||||
#endif // __DRM_LIB_LOADER_H__
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 - 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 __DRM_LOGGER_H__
|
||||
#define __DRM_LOGGER_H__
|
||||
|
||||
#include <debug_handler.h>
|
||||
#include <utility>
|
||||
|
||||
namespace drm_utils {
|
||||
|
||||
#define DRM_LOG_TAG 4 // = kTagRotator
|
||||
|
||||
#define DRM_LOGE(format, ...) DLOGE(format, ##__VA_ARGS__)
|
||||
#define DRM_LOGW(format, ...) DLOGW_IF(DRM_LOG_TAG, format, ##__VA_ARGS__)
|
||||
#define DRM_LOGI(format, ...) DLOGI_IF(DRM_LOG_TAG, format, ##__VA_ARGS__)
|
||||
#define DRM_LOGD(format, ...) DLOGD_IF(DRM_LOG_TAG, format, ##__VA_ARGS__)
|
||||
#define DRM_LOGV(format, ...) DLOGV_IF(DRM_LOG_TAG, format, ##__VA_ARGS__)
|
||||
|
||||
} // namespace drm_utils
|
||||
|
||||
#endif // __DRM_LOGGER_H__
|
||||
@@ -1,155 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 - 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 <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
// Intentionally included after xf86 headers so that they in-turn include libdrm version of drm.h
|
||||
// that doesn't use keyword "virtual" for a variable name. Not doing so leads to the kernel version
|
||||
// of drm.h being included causing compilation to fail
|
||||
#include <drm/msm_drm.h>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
#include "drm_master.h"
|
||||
|
||||
#define __CLASS__ "DRMMaster"
|
||||
|
||||
using std::mutex;
|
||||
using std::lock_guard;
|
||||
using std::begin;
|
||||
using std::copy;
|
||||
using std::end;
|
||||
using std::fill;
|
||||
|
||||
namespace drm_utils {
|
||||
|
||||
DRMMaster *DRMMaster::s_instance = nullptr;
|
||||
mutex DRMMaster::s_lock;
|
||||
|
||||
int DRMMaster::GetInstance(DRMMaster **master) {
|
||||
lock_guard<mutex> obj(s_lock);
|
||||
|
||||
if (!s_instance) {
|
||||
s_instance = new DRMMaster();
|
||||
if (s_instance->Init() < 0) {
|
||||
delete s_instance;
|
||||
s_instance = nullptr;
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
*master = s_instance;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DRMMaster::DestroyInstance() {
|
||||
lock_guard<mutex> obj(s_lock);
|
||||
delete s_instance;
|
||||
s_instance = nullptr;
|
||||
}
|
||||
|
||||
int DRMMaster::Init() {
|
||||
dev_fd_ = drmOpen("msm_drm", nullptr);
|
||||
if (dev_fd_ < 0) {
|
||||
DRM_LOGE("drmOpen failed with error %d", dev_fd_);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DRMMaster::~DRMMaster() {
|
||||
drmClose(dev_fd_);
|
||||
dev_fd_ = -1;
|
||||
}
|
||||
|
||||
int DRMMaster::CreateFbId(const DRMBuffer &drm_buffer, uint32_t *fb_id) {
|
||||
uint32_t gem_handle = 0;
|
||||
int ret = drmPrimeFDToHandle(dev_fd_, drm_buffer.fd, &gem_handle);
|
||||
if (ret) {
|
||||
DRM_LOGW("drmPrimeFDToHandle failed with error %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct drm_mode_fb_cmd2 cmd2 {};
|
||||
cmd2.width = drm_buffer.width;
|
||||
cmd2.height = drm_buffer.height;
|
||||
cmd2.pixel_format = drm_buffer.drm_format;
|
||||
cmd2.flags = DRM_MODE_FB_MODIFIERS;
|
||||
fill(begin(cmd2.handles), begin(cmd2.handles) + drm_buffer.num_planes, gem_handle);
|
||||
copy(begin(drm_buffer.stride), end(drm_buffer.stride), begin(cmd2.pitches));
|
||||
copy(begin(drm_buffer.offset), end(drm_buffer.offset), begin(cmd2.offsets));
|
||||
fill(begin(cmd2.modifier), begin(cmd2.modifier) + drm_buffer.num_planes,
|
||||
drm_buffer.drm_format_modifier);
|
||||
|
||||
if ((ret = drmIoctl(dev_fd_, DRM_IOCTL_MODE_ADDFB2, &cmd2))) {
|
||||
DRM_LOGE("DRM_IOCTL_MODE_ADDFB2 failed with error %d", ret);
|
||||
} else {
|
||||
*fb_id = cmd2.fb_id;
|
||||
}
|
||||
|
||||
struct drm_gem_close gem_close = {};
|
||||
gem_close.handle = gem_handle;
|
||||
int ret1 = drmIoctl(dev_fd_, DRM_IOCTL_GEM_CLOSE, &gem_close);
|
||||
if (ret1) {
|
||||
DRM_LOGE("drmIoctl::DRM_IOCTL_GEM_CLOSE failed with error %d", ret1);
|
||||
return ret1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int DRMMaster::RemoveFbId(uint32_t fb_id) {
|
||||
int ret = 0;
|
||||
#ifdef DRM_IOCTL_MSM_RMFB2
|
||||
ret = drmIoctl(dev_fd_, DRM_IOCTL_MSM_RMFB2, &fb_id);
|
||||
if (ret) {
|
||||
DRM_LOGE("drmIoctl::DRM_IOCTL_MSM_RMFB2 failed for fb_id %d with error %d", fb_id, errno);
|
||||
}
|
||||
#else
|
||||
ret = drmModeRmFB(dev_fd_, fb_id);
|
||||
if (ret) {
|
||||
DRM_LOGE("drmModeRmFB failed for fb_id %d with error %d", fb_id, ret);
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool DRMMaster::IsRmFbRefCounted() {
|
||||
#ifdef DRM_IOCTL_MSM_RMFB2
|
||||
return true;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace drm_utils
|
||||
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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 __DRM_MASTER_H__
|
||||
#define __DRM_MASTER_H__
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include "drm_logger.h"
|
||||
|
||||
namespace drm_utils {
|
||||
|
||||
struct DRMBuffer {
|
||||
int fd = -1;
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
uint32_t drm_format = 0;
|
||||
uint64_t drm_format_modifier = 0;
|
||||
uint32_t stride[4] = {};
|
||||
uint32_t offset[4] = {};
|
||||
uint32_t num_planes = 1;
|
||||
};
|
||||
|
||||
class DRMMaster {
|
||||
public:
|
||||
~DRMMaster();
|
||||
/* Converts from ION fd --> Prime Handle --> FB_ID.
|
||||
* Input:
|
||||
* drm_buffer: A DRMBuffer obj that packages description of buffer
|
||||
* Output:
|
||||
* fb_id: Pointer to store DRM framebuffer id into
|
||||
* Returns:
|
||||
* ioctl error code
|
||||
*/
|
||||
int CreateFbId(const DRMBuffer &drm_buffer, uint32_t *fb_id);
|
||||
/* Removes the fb_id from DRM
|
||||
* Input:
|
||||
* fb_id: DRM FB to be removed
|
||||
* Returns:
|
||||
* ioctl error code
|
||||
*/
|
||||
int RemoveFbId(uint32_t fb_id);
|
||||
/* Poplulates master DRM fd
|
||||
* Input:
|
||||
* fd: Pointer to store master fd into
|
||||
*/
|
||||
void GetHandle(int *fd) { *fd = dev_fd_; }
|
||||
/* Returns true if the ref counted version of rmfb is being used */
|
||||
bool IsRmFbRefCounted();
|
||||
|
||||
/* Creates an instance of DRMMaster if it doesn't exist and initializes it. Threadsafe.
|
||||
* Input:
|
||||
* master: Pointer to store a pointer to the instance
|
||||
* Returns:
|
||||
* -ENODEV if device cannot be opened or initilization fails
|
||||
*/
|
||||
static int GetInstance(DRMMaster **master);
|
||||
static void DestroyInstance();
|
||||
|
||||
private:
|
||||
DRMMaster() {}
|
||||
int Init();
|
||||
|
||||
int dev_fd_ = -1; // Master fd for DRM
|
||||
static DRMMaster *s_instance; // Singleton instance
|
||||
static std::mutex s_lock;
|
||||
};
|
||||
|
||||
} // namespace drm_utils
|
||||
|
||||
#endif // __DRM_MASTER_H__
|
||||
@@ -1,151 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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 <errno.h>
|
||||
|
||||
#include "drm_master.h"
|
||||
#include "drm_res_mgr.h"
|
||||
|
||||
#define DEBUG 0
|
||||
#define __CLASS__ "DRMResMgr"
|
||||
|
||||
using std::mutex;
|
||||
using std::lock_guard;
|
||||
|
||||
namespace drm_utils {
|
||||
|
||||
DRMResMgr *DRMResMgr::s_instance = nullptr;
|
||||
mutex DRMResMgr::s_lock;
|
||||
|
||||
static bool GetConnector(int dev_fd, drmModeRes *res, drmModeConnector **connector) {
|
||||
for (auto i = 0; i < res->count_connectors; i++) {
|
||||
drmModeConnector *conn = drmModeGetConnector(dev_fd, res->connectors[i]);
|
||||
if (conn && conn->connector_type == DRM_MODE_CONNECTOR_DSI && conn->count_modes &&
|
||||
conn->connection == DRM_MODE_CONNECTED) {
|
||||
*connector = conn;
|
||||
DRM_LOGI("Found connector %d", conn->connector_id);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool GetEncoder(int dev_fd, drmModeConnector *conn, drmModeEncoder **encoder) {
|
||||
for (auto i = 0; i < conn->count_encoders; i++) {
|
||||
drmModeEncoder *enc = drmModeGetEncoder(dev_fd, conn->encoders[i]);
|
||||
if (enc && enc->encoder_type == DRM_MODE_ENCODER_DSI) {
|
||||
*encoder = enc;
|
||||
DRM_LOGI("Found encoder %d", enc->encoder_id);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool GetCrtc(int dev_fd, drmModeRes *res, drmModeEncoder *enc, drmModeCrtc **crtc) {
|
||||
for (auto i = 0; i < res->count_crtcs; i++) {
|
||||
if (enc->possible_crtcs & (1 << i)) {
|
||||
drmModeCrtc *c = drmModeGetCrtc(dev_fd, res->crtcs[i]);
|
||||
if (c) {
|
||||
*crtc = c;
|
||||
DRM_LOGI("Found crtc %d", c->crtc_id);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#define __CLASS__ "DRMResMgr"
|
||||
|
||||
int DRMResMgr::GetInstance(DRMResMgr **res_mgr) {
|
||||
lock_guard<mutex> obj(s_lock);
|
||||
|
||||
if (!s_instance) {
|
||||
s_instance = new DRMResMgr();
|
||||
if (s_instance->Init() < 0) {
|
||||
delete s_instance;
|
||||
s_instance = nullptr;
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
*res_mgr = s_instance;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DRMResMgr::Init() {
|
||||
DRMMaster *master = nullptr;
|
||||
int dev_fd = -1;
|
||||
|
||||
int ret = DRMMaster::GetInstance(&master);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
master->GetHandle(&dev_fd);
|
||||
drmModeRes *res = drmModeGetResources(dev_fd);
|
||||
if (res == nullptr) {
|
||||
DRM_LOGE("drmModeGetResources failed");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
drmModeConnector *conn = nullptr;
|
||||
if (!GetConnector(dev_fd, res, &conn)) {
|
||||
DRM_LOGE("Failed to find a connector");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
drmModeEncoder *enc = nullptr;
|
||||
if (!GetEncoder(dev_fd, conn, &enc)) {
|
||||
DRM_LOGE("Failed to find an encoder");
|
||||
drmModeFreeConnector(conn);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
drmModeCrtc *crtc = nullptr;
|
||||
if (!GetCrtc(dev_fd, res, enc, &crtc)) {
|
||||
DRM_LOGE("Failed to find a crtc");
|
||||
drmModeFreeEncoder(enc);
|
||||
drmModeFreeConnector(conn);
|
||||
drmModeFreeResources(res);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
res_ = res;
|
||||
conn_ = conn;
|
||||
enc_ = enc;
|
||||
crtc_ = crtc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace drm_utils
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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 __DRM_RES_MGR_H__
|
||||
#define __DRM_RES_MGR_H__
|
||||
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
namespace drm_utils {
|
||||
|
||||
class DRMResMgr {
|
||||
public:
|
||||
/* Returns the default connector id for primary panel */
|
||||
void GetConnectorId(uint32_t *id) { *id = conn_->connector_id; }
|
||||
/* Returns the default crtc id for primary pipeline */
|
||||
void GetCrtcId(uint32_t *id) { *id = crtc_->crtc_id; }
|
||||
/* Returns the default mode currently used by the connector */
|
||||
void GetMode(drmModeModeInfo *mode) { *mode = conn_->modes[0]; }
|
||||
/* Returns the panel dimensions in mm */
|
||||
void GetDisplayDimInMM(uint32_t *w, uint32_t *h) {
|
||||
*w = conn_->mmWidth;
|
||||
*h = conn_->mmHeight;
|
||||
}
|
||||
|
||||
/* Creates and initializes an instance of DRMResMgr. On success, returns a pointer to it, on
|
||||
* failure returns -ENODEV */
|
||||
static int GetInstance(DRMResMgr **res_mgr);
|
||||
|
||||
private:
|
||||
int Init();
|
||||
|
||||
drmModeRes *res_ = nullptr;
|
||||
drmModeConnector *conn_ = nullptr;
|
||||
drmModeEncoder *enc_ = nullptr;
|
||||
drmModeCrtc *crtc_ = nullptr;
|
||||
|
||||
static DRMResMgr *s_instance;
|
||||
static std::mutex s_lock;
|
||||
};
|
||||
|
||||
} // namespace drm_utils
|
||||
|
||||
#endif // __DRM_RES_MGR_H__
|
||||
@@ -1,33 +0,0 @@
|
||||
# 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.
|
||||
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
# HAL module implemenation stored in
|
||||
# hw/<COPYPIX_HARDWARE_MODULE_ID>.<ro.board.platform>.so
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := lights.c
|
||||
LOCAL_MODULE_RELATIVE_PATH := hw
|
||||
LOCAL_SHARED_LIBRARIES := liblog
|
||||
LOCAL_HEADER_LIBRARIES := libhardware_headers
|
||||
LOCAL_CFLAGS := -DLOG_TAG=\"qdlights\"
|
||||
ifeq ($(LLVM_SA), true)
|
||||
LOCAL_CFLAGS += --compile-and-analyze --analyzer-perf --analyzer-Werror
|
||||
endif
|
||||
LOCAL_CLANG := true
|
||||
LOCAL_MODULE := lights.$(TARGET_BOARD_PLATFORM)
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_VENDOR_MODULE := true
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
190
liblight/NOTICE
190
liblight/NOTICE
@@ -1,190 +0,0 @@
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
@@ -1,382 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014, 2017-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.
|
||||
*/
|
||||
|
||||
|
||||
// #define LOG_NDEBUG 0
|
||||
|
||||
#include <log/log.h>
|
||||
#include <cutils/properties.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <hardware/lights.h>
|
||||
|
||||
#ifndef DEFAULT_LOW_PERSISTENCE_MODE_BRIGHTNESS
|
||||
#define DEFAULT_LOW_PERSISTENCE_MODE_BRIGHTNESS 0x80
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static pthread_once_t g_init = PTHREAD_ONCE_INIT;
|
||||
static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static struct light_state_t g_notification;
|
||||
static struct light_state_t g_battery;
|
||||
static int g_last_backlight_mode = BRIGHTNESS_MODE_USER;
|
||||
static int g_attention = 0;
|
||||
static bool g_has_persistence_node = false;
|
||||
|
||||
char const*const RED_LED_FILE
|
||||
= "/sys/class/leds/red/brightness";
|
||||
|
||||
char const*const GREEN_LED_FILE
|
||||
= "/sys/class/leds/green/brightness";
|
||||
|
||||
char const*const BLUE_LED_FILE
|
||||
= "/sys/class/leds/blue/brightness";
|
||||
|
||||
char const*const LCD_FILE
|
||||
= "/sys/class/leds/lcd-backlight/brightness";
|
||||
|
||||
char const*const LCD_FILE2
|
||||
= "/sys/class/backlight/panel0-backlight/brightness";
|
||||
|
||||
char const*const BUTTON_FILE
|
||||
= "/sys/class/leds/button-backlight/brightness";
|
||||
|
||||
char const*const RED_BLINK_FILE
|
||||
= "/sys/class/leds/red/blink";
|
||||
|
||||
char const*const GREEN_BLINK_FILE
|
||||
= "/sys/class/leds/green/blink";
|
||||
|
||||
char const*const BLUE_BLINK_FILE
|
||||
= "/sys/class/leds/blue/blink";
|
||||
|
||||
char const*const PERSISTENCE_FILE
|
||||
= "/sys/class/graphics/fb0/msm_fb_persist_mode";
|
||||
|
||||
/**
|
||||
* device methods
|
||||
*/
|
||||
|
||||
void init_globals(void)
|
||||
{
|
||||
// init the mutex
|
||||
pthread_mutex_init(&g_lock, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
write_int(char const* path, int value)
|
||||
{
|
||||
int fd;
|
||||
static int already_warned = 0;
|
||||
|
||||
fd = open(path, O_RDWR);
|
||||
if (fd >= 0) {
|
||||
char buffer[20];
|
||||
int bytes = snprintf(buffer, sizeof(buffer), "%d\n", value);
|
||||
ssize_t amt = write(fd, buffer, (size_t)bytes);
|
||||
close(fd);
|
||||
return amt == -1 ? -errno : 0;
|
||||
} else {
|
||||
if (already_warned == 0) {
|
||||
ALOGE("write_int failed to open %s\n", path);
|
||||
already_warned = 1;
|
||||
}
|
||||
return -errno;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
is_lit(struct light_state_t const* state)
|
||||
{
|
||||
return state->color & 0x00ffffff;
|
||||
}
|
||||
|
||||
static int
|
||||
rgb_to_brightness(struct light_state_t const* state)
|
||||
{
|
||||
int color = state->color & 0x00ffffff;
|
||||
return ((77*((color>>16)&0x00ff))
|
||||
+ (150*((color>>8)&0x00ff)) + (29*(color&0x00ff))) >> 8;
|
||||
}
|
||||
|
||||
static int
|
||||
set_light_backlight(struct light_device_t* dev,
|
||||
struct light_state_t const* state)
|
||||
{
|
||||
int err = 0;
|
||||
int brightness = rgb_to_brightness(state);
|
||||
unsigned int lpEnabled =
|
||||
state->brightnessMode == BRIGHTNESS_MODE_LOW_PERSISTENCE;
|
||||
if(!dev) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&g_lock);
|
||||
// Toggle low persistence mode state
|
||||
bool persistence_mode = ((g_last_backlight_mode != state->brightnessMode && lpEnabled) ||
|
||||
(!lpEnabled &&
|
||||
g_last_backlight_mode == BRIGHTNESS_MODE_LOW_PERSISTENCE));
|
||||
bool cannot_handle_persistence = !g_has_persistence_node && persistence_mode;
|
||||
if (g_has_persistence_node) {
|
||||
if (persistence_mode) {
|
||||
if ((err = write_int(PERSISTENCE_FILE, lpEnabled)) != 0) {
|
||||
ALOGE("%s: Failed to write to %s: %s\n", __FUNCTION__,
|
||||
PERSISTENCE_FILE, strerror(errno));
|
||||
}
|
||||
if (lpEnabled != 0) {
|
||||
brightness = DEFAULT_LOW_PERSISTENCE_MODE_BRIGHTNESS;
|
||||
}
|
||||
}
|
||||
g_last_backlight_mode = state->brightnessMode;
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
if (!access(LCD_FILE, F_OK)) {
|
||||
err = write_int(LCD_FILE, brightness);
|
||||
} else {
|
||||
err = write_int(LCD_FILE2, brightness);
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&g_lock);
|
||||
return cannot_handle_persistence ? -ENOSYS : err;
|
||||
}
|
||||
|
||||
static int
|
||||
set_speaker_light_locked(struct light_device_t* dev,
|
||||
struct light_state_t const* state)
|
||||
{
|
||||
int red, green, blue;
|
||||
int blink;
|
||||
int onMS, offMS;
|
||||
unsigned int colorRGB;
|
||||
|
||||
if(!dev) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (state->flashMode) {
|
||||
case LIGHT_FLASH_TIMED:
|
||||
onMS = state->flashOnMS;
|
||||
offMS = state->flashOffMS;
|
||||
break;
|
||||
case LIGHT_FLASH_NONE:
|
||||
default:
|
||||
onMS = 0;
|
||||
offMS = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
colorRGB = state->color;
|
||||
|
||||
#if 0
|
||||
ALOGD("set_speaker_light_locked mode %d, colorRGB=%08X, onMS=%d, offMS=%d\n",
|
||||
state->flashMode, colorRGB, onMS, offMS);
|
||||
#endif
|
||||
|
||||
red = (colorRGB >> 16) & 0xFF;
|
||||
green = (colorRGB >> 8) & 0xFF;
|
||||
blue = colorRGB & 0xFF;
|
||||
|
||||
if (onMS > 0 && offMS > 0) {
|
||||
/*
|
||||
* if ON time == OFF time
|
||||
* use blink mode 2
|
||||
* else
|
||||
* use blink mode 1
|
||||
*/
|
||||
if (onMS == offMS)
|
||||
blink = 2;
|
||||
else
|
||||
blink = 1;
|
||||
} else {
|
||||
blink = 0;
|
||||
}
|
||||
|
||||
if (blink) {
|
||||
if (red) {
|
||||
if (write_int(RED_BLINK_FILE, blink))
|
||||
write_int(RED_LED_FILE, 0);
|
||||
}
|
||||
if (green) {
|
||||
if (write_int(GREEN_BLINK_FILE, blink))
|
||||
write_int(GREEN_LED_FILE, 0);
|
||||
}
|
||||
if (blue) {
|
||||
if (write_int(BLUE_BLINK_FILE, blink))
|
||||
write_int(BLUE_LED_FILE, 0);
|
||||
}
|
||||
} else {
|
||||
write_int(RED_LED_FILE, red);
|
||||
write_int(GREEN_LED_FILE, green);
|
||||
write_int(BLUE_LED_FILE, blue);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_speaker_battery_locked(struct light_device_t* dev)
|
||||
{
|
||||
if (is_lit(&g_battery)) {
|
||||
set_speaker_light_locked(dev, &g_battery);
|
||||
} else {
|
||||
set_speaker_light_locked(dev, &g_notification);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
set_light_battery(struct light_device_t* dev,
|
||||
struct light_state_t const* state)
|
||||
{
|
||||
pthread_mutex_lock(&g_lock);
|
||||
g_battery = *state;
|
||||
handle_speaker_battery_locked(dev);
|
||||
pthread_mutex_unlock(&g_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
set_light_notifications(struct light_device_t* dev,
|
||||
struct light_state_t const* state)
|
||||
{
|
||||
pthread_mutex_lock(&g_lock);
|
||||
g_notification = *state;
|
||||
handle_speaker_battery_locked(dev);
|
||||
pthread_mutex_unlock(&g_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
set_light_attention(struct light_device_t* dev,
|
||||
struct light_state_t const* state)
|
||||
{
|
||||
pthread_mutex_lock(&g_lock);
|
||||
if (state->flashMode == LIGHT_FLASH_HARDWARE) {
|
||||
g_attention = state->flashOnMS;
|
||||
} else if (state->flashMode == LIGHT_FLASH_NONE) {
|
||||
g_attention = 0;
|
||||
}
|
||||
handle_speaker_battery_locked(dev);
|
||||
pthread_mutex_unlock(&g_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
set_light_buttons(struct light_device_t* dev,
|
||||
struct light_state_t const* state)
|
||||
{
|
||||
int err = 0;
|
||||
if(!dev) {
|
||||
return -1;
|
||||
}
|
||||
pthread_mutex_lock(&g_lock);
|
||||
err = write_int(BUTTON_FILE, state->color & 0xFF);
|
||||
pthread_mutex_unlock(&g_lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
/** Close the lights device */
|
||||
static int
|
||||
close_lights(struct light_device_t *dev)
|
||||
{
|
||||
if (dev) {
|
||||
free(dev);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* module methods
|
||||
*/
|
||||
|
||||
/** Open a new instance of a lights device using name */
|
||||
static int open_lights(const struct hw_module_t* module, char const* name,
|
||||
struct hw_device_t** device)
|
||||
{
|
||||
int (*set_light)(struct light_device_t* dev,
|
||||
struct light_state_t const* state);
|
||||
|
||||
if (0 == strcmp(LIGHT_ID_BACKLIGHT, name)) {
|
||||
g_has_persistence_node = !access(PERSISTENCE_FILE, F_OK);
|
||||
set_light = set_light_backlight;
|
||||
} else if (0 == strcmp(LIGHT_ID_BATTERY, name))
|
||||
set_light = set_light_battery;
|
||||
else if (0 == strcmp(LIGHT_ID_NOTIFICATIONS, name))
|
||||
set_light = set_light_notifications;
|
||||
else if (0 == strcmp(LIGHT_ID_BUTTONS, name)) {
|
||||
if (!access(BUTTON_FILE, F_OK)) {
|
||||
// enable light button when the file is present
|
||||
set_light = set_light_buttons;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
else if (0 == strcmp(LIGHT_ID_ATTENTION, name))
|
||||
set_light = set_light_attention;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
pthread_once(&g_init, init_globals);
|
||||
|
||||
struct light_device_t *dev = malloc(sizeof(struct light_device_t));
|
||||
|
||||
if(!dev)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(dev, 0, sizeof(*dev));
|
||||
|
||||
dev->common.tag = HARDWARE_DEVICE_TAG;
|
||||
dev->common.version = LIGHTS_DEVICE_API_VERSION_2_0;
|
||||
dev->common.module = (struct hw_module_t*)module;
|
||||
dev->common.close = (int (*)(struct hw_device_t*))close_lights;
|
||||
dev->set_light = set_light;
|
||||
|
||||
*device = (struct hw_device_t*)dev;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct hw_module_methods_t lights_module_methods = {
|
||||
.open = open_lights,
|
||||
};
|
||||
|
||||
/*
|
||||
* The lights Module
|
||||
*/
|
||||
struct hw_module_t HAL_MODULE_INFO_SYM = {
|
||||
.tag = HARDWARE_MODULE_TAG,
|
||||
.version_major = 1,
|
||||
.version_minor = 0,
|
||||
.id = LIGHTS_HARDWARE_MODULE_ID,
|
||||
.name = "lights Module",
|
||||
.author = "Google, Inc.",
|
||||
.methods = &lights_module_methods,
|
||||
};
|
||||
@@ -1,30 +0,0 @@
|
||||
# Copyright (C) 2013 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.
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
# HAL module implemenation stored in
|
||||
# hw/<POWERS_HARDWARE_MODULE_ID>.<ro.hardware>.so
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE_RELATIVE_PATH := hw
|
||||
LOCAL_VENDOR_MODULE := true
|
||||
LOCAL_C_INCLUDES += hardware/libhardware/include
|
||||
LOCAL_CFLAGS := -Wconversion -Wall -Werror -Wno-sign-conversion
|
||||
LOCAL_CLANG := true
|
||||
LOCAL_SHARED_LIBRARIES := liblog
|
||||
LOCAL_HEADER_LIBRARIES := libhardware_headers
|
||||
LOCAL_SRC_FILES := memtrack_msm.c kgsl.c
|
||||
LOCAL_MODULE := memtrack.$(TARGET_BOARD_PLATFORM)
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
@@ -1,144 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 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.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <hardware/memtrack.h>
|
||||
|
||||
#include "memtrack_msm.h"
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
|
||||
#define min(x, y) ((x) < (y) ? (x) : (y))
|
||||
|
||||
struct memtrack_record record_templates[] = {
|
||||
{
|
||||
.flags = MEMTRACK_FLAG_SMAPS_ACCOUNTED |
|
||||
MEMTRACK_FLAG_PRIVATE |
|
||||
MEMTRACK_FLAG_NONSECURE,
|
||||
},
|
||||
{
|
||||
.flags = MEMTRACK_FLAG_SMAPS_UNACCOUNTED |
|
||||
MEMTRACK_FLAG_PRIVATE |
|
||||
MEMTRACK_FLAG_NONSECURE,
|
||||
},
|
||||
};
|
||||
|
||||
int kgsl_memtrack_get_memory(pid_t pid, enum memtrack_type type,
|
||||
struct memtrack_record *records,
|
||||
size_t *num_records)
|
||||
{
|
||||
size_t allocated_records = min(*num_records, ARRAY_SIZE(record_templates));
|
||||
FILE *fp;
|
||||
char line[1024];
|
||||
char tmp[128];
|
||||
size_t accounted_size = 0;
|
||||
size_t unaccounted_size = 0;
|
||||
|
||||
*num_records = ARRAY_SIZE(record_templates);
|
||||
|
||||
/* fastpath to return the necessary number of records */
|
||||
if (allocated_records == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(records, record_templates,
|
||||
sizeof(struct memtrack_record) * allocated_records);
|
||||
|
||||
snprintf(tmp, sizeof(tmp), "/d/kgsl/proc/%d/mem", pid);
|
||||
fp = fopen(tmp, "r");
|
||||
if (fp == NULL) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
/* Go through each line of <pid>/mem file and for every entry of type "gpumem"
|
||||
* check if the gpubuffer entry is usermapped or not. If the entry is usermapped
|
||||
* count the entry as accounted else count the entry as unaccounted.
|
||||
*/
|
||||
while (1) {
|
||||
unsigned long size, mapsize;
|
||||
char line_type[7];
|
||||
char flags[10];
|
||||
char line_usage[19];
|
||||
int ret, egl_surface_count = 0, egl_image_count = 0;
|
||||
|
||||
if (fgets(line, sizeof(line), fp) == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Format:
|
||||
* gpuaddr useraddr size id flags type usage sglen mapsize eglsrf eglimg
|
||||
* 545ba000 545ba000 4096 1 -----pY gpumem arraybuffer 1 4096 0 0
|
||||
*/
|
||||
ret = sscanf(line, "%*x %*x %lu %*d %9s %6s %18s %*d %lu %6d %6d\n",
|
||||
&size, flags, line_type, line_usage, &mapsize,
|
||||
&egl_surface_count, &egl_image_count);
|
||||
if (ret != 7) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (size == 0) {
|
||||
fclose(fp);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (unaccounted_size + size < size) {
|
||||
fclose(fp);
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
if (type == MEMTRACK_TYPE_GL && strcmp(line_type, "gpumem") == 0) {
|
||||
|
||||
if (flags[6] == 'Y') {
|
||||
if (accounted_size + mapsize < accounted_size) {
|
||||
fclose(fp);
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
accounted_size += mapsize;
|
||||
|
||||
if (mapsize > size) {
|
||||
fclose(fp);
|
||||
return -EINVAL;
|
||||
}
|
||||
unaccounted_size += size - mapsize;
|
||||
} else {
|
||||
unaccounted_size += size;
|
||||
}
|
||||
} else if (type == MEMTRACK_TYPE_GRAPHICS && strcmp(line_type, "ion") == 0) {
|
||||
if (strcmp(line_usage, "egl_surface") == 0) {
|
||||
unaccounted_size += size;
|
||||
}
|
||||
else if (egl_surface_count == 0) {
|
||||
unaccounted_size += size / (egl_image_count ? egl_image_count : 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (allocated_records > 0) {
|
||||
records[0].size_in_bytes = accounted_size;
|
||||
}
|
||||
if (allocated_records > 1) {
|
||||
records[1].size_in_bytes = unaccounted_size;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 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.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <hardware/memtrack.h>
|
||||
|
||||
#include "memtrack_msm.h"
|
||||
|
||||
int msm_memtrack_init(const struct memtrack_module *module)
|
||||
{
|
||||
if(!module)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_memtrack_get_memory(const struct memtrack_module *module,
|
||||
pid_t pid,
|
||||
int type,
|
||||
struct memtrack_record *records,
|
||||
size_t *num_records)
|
||||
{
|
||||
if(!module)
|
||||
return -1;
|
||||
if (type == MEMTRACK_TYPE_GL || type == MEMTRACK_TYPE_GRAPHICS) {
|
||||
return kgsl_memtrack_get_memory(pid, type, records, num_records);
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static struct hw_module_methods_t memtrack_module_methods = {
|
||||
.open = NULL,
|
||||
};
|
||||
|
||||
struct memtrack_module HAL_MODULE_INFO_SYM = {
|
||||
.common = {
|
||||
.tag = HARDWARE_MODULE_TAG,
|
||||
.module_api_version = MEMTRACK_MODULE_API_VERSION_0_1,
|
||||
.hal_api_version = HARDWARE_HAL_API_VERSION,
|
||||
.id = MEMTRACK_HARDWARE_MODULE_ID,
|
||||
.name = "MSM Memory Tracker HAL",
|
||||
.author = "The Android Open Source Project",
|
||||
.methods = &memtrack_module_methods,
|
||||
},
|
||||
|
||||
.init = msm_memtrack_init,
|
||||
.getMemory = msm_memtrack_get_memory,
|
||||
};
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 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 _MEMTRACK_MSM_H_
|
||||
#define _MEMTRACK_MSM_H_
|
||||
|
||||
int kgsl_memtrack_get_memory(pid_t pid, enum memtrack_type type,
|
||||
struct memtrack_record *records,
|
||||
size_t *num_records);
|
||||
|
||||
#endif
|
||||
34
libqdmetadata/Android.bp
Normal file
34
libqdmetadata/Android.bp
Normal file
@@ -0,0 +1,34 @@
|
||||
cc_library_shared {
|
||||
name: "libqdMetaData",
|
||||
vendor_available: true,
|
||||
cflags: [
|
||||
"-Wno-sign-conversion",
|
||||
"-DLOG_TAG=\"qdmetadata\"",
|
||||
],
|
||||
shared_libs: [
|
||||
"liblog",
|
||||
"libcutils",
|
||||
"libutils",
|
||||
],
|
||||
header_libs: ["libhardware_headers", "display_intf_headers"],
|
||||
srcs: ["qdMetaData.cpp", "qd_utils.cpp"],
|
||||
export_header_lib_headers: ["display_intf_headers"],
|
||||
}
|
||||
|
||||
// Remove after WFD moves to use libqdMetaData directly
|
||||
cc_library_shared {
|
||||
name: "libqdMetaData.system",
|
||||
vendor_available: true,
|
||||
cflags: [
|
||||
"-Wno-sign-conversion",
|
||||
"-DLOG_TAG=\"qdmetadata\"",
|
||||
],
|
||||
shared_libs: [
|
||||
"liblog",
|
||||
"libcutils",
|
||||
"libutils",
|
||||
],
|
||||
header_libs: ["libhardware_headers", "display_intf_headers"],
|
||||
srcs: ["qdMetaData.cpp", "qd_utils.cpp"],
|
||||
export_header_lib_headers: ["display_intf_headers"],
|
||||
}
|
||||
100
libqdmetadata/qd_utils.cpp
Normal file
100
libqdmetadata/qd_utils.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 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 <unistd.h>
|
||||
#include <gralloc_priv.h>
|
||||
#include "qd_utils.h"
|
||||
|
||||
static const int kFBNodeMax = 4;
|
||||
namespace qdutils {
|
||||
|
||||
static int getExternalNode(const char *type) {
|
||||
FILE *displayDeviceFP = NULL;
|
||||
char fbType[MAX_FRAME_BUFFER_NAME_SIZE];
|
||||
char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE];
|
||||
int j = 0;
|
||||
|
||||
for(j = 0; j < kFBNodeMax; j++) {
|
||||
snprintf (msmFbTypePath, sizeof(msmFbTypePath),
|
||||
"/sys/devices/virtual/graphics/fb%d/msm_fb_type", j);
|
||||
displayDeviceFP = fopen(msmFbTypePath, "r");
|
||||
if(displayDeviceFP) {
|
||||
fread(fbType, sizeof(char), MAX_FRAME_BUFFER_NAME_SIZE,
|
||||
displayDeviceFP);
|
||||
if(strncmp(fbType, type, strlen(type)) == 0) {
|
||||
ALOGD("%s: %s is at fb%d", __func__, type, j);
|
||||
fclose(displayDeviceFP);
|
||||
break;
|
||||
}
|
||||
fclose(displayDeviceFP);
|
||||
} else {
|
||||
ALOGE("%s: Failed to open fb node %s", __func__, msmFbTypePath);
|
||||
}
|
||||
}
|
||||
|
||||
if (j < kFBNodeMax)
|
||||
return j;
|
||||
else
|
||||
ALOGE("%s: Failed to find %s node", __func__, type);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int getHDMINode(void) {
|
||||
return getExternalNode("dtv panel");
|
||||
}
|
||||
|
||||
int getEdidRawData(char *buffer)
|
||||
{
|
||||
int size;
|
||||
int edidFile;
|
||||
char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE];
|
||||
int node_id = getHDMINode();
|
||||
|
||||
if (node_id < 0) {
|
||||
ALOGE("%s no HDMI node found", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
snprintf(msmFbTypePath, sizeof(msmFbTypePath),
|
||||
"/sys/devices/virtual/graphics/fb%d/edid_raw_data", node_id);
|
||||
|
||||
edidFile = open(msmFbTypePath, O_RDONLY, 0);
|
||||
|
||||
if (edidFile < 0) {
|
||||
ALOGE("%s no edid raw data found %s", __func__,msmFbTypePath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
size = (int)read(edidFile, (char*)buffer, EDID_RAW_DATA_SIZE);
|
||||
close(edidFile);
|
||||
return size;
|
||||
}
|
||||
|
||||
}; //namespace qdutils
|
||||
@@ -1,40 +0,0 @@
|
||||
cc_library_shared {
|
||||
name: "libqdutils",
|
||||
vendor: true,
|
||||
defaults: ["display_defaults"],
|
||||
header_libs: ["libhardware_headers", "libutils_headers"],
|
||||
shared_libs: [
|
||||
"libbinder",
|
||||
"libqservice",
|
||||
],
|
||||
cflags: [
|
||||
"-DLOG_TAG=\"qdutils\"",
|
||||
"-Wno-sign-conversion",
|
||||
],
|
||||
srcs: [
|
||||
"qd_utils.cpp",
|
||||
"display_config.cpp",
|
||||
],
|
||||
}
|
||||
|
||||
cc_library_shared {
|
||||
name: "libqdMetaData",
|
||||
vendor: true,
|
||||
defaults: ["display_defaults"],
|
||||
cflags: [
|
||||
"-Wno-sign-conversion",
|
||||
"-DLOG_TAG=\"qdmetadata\"",
|
||||
],
|
||||
srcs: ["qdMetaData.cpp","qd_utils.cpp"],
|
||||
}
|
||||
|
||||
// Remove after WFD moves to use libqdMetaData directly
|
||||
cc_library_shared {
|
||||
name: "libqdMetaData.system",
|
||||
defaults: ["display_defaults"],
|
||||
cflags: [
|
||||
"-Wno-sign-conversion",
|
||||
"-DLOG_TAG=\"qdmetadata\"",
|
||||
],
|
||||
srcs: ["qdMetaData.cpp","qd_utils.cpp"],
|
||||
}
|
||||
@@ -1,390 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014, 2016, 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 <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <display_config.h>
|
||||
#include <QServiceUtils.h>
|
||||
#include <qd_utils.h>
|
||||
|
||||
using namespace android;
|
||||
using namespace qService;
|
||||
|
||||
namespace qdutils {
|
||||
|
||||
//=============================================================================
|
||||
// The functions below run in the client process and wherever necessary
|
||||
// do a binder call to HWC to get/set data.
|
||||
|
||||
int isExternalConnected(void) {
|
||||
int ret;
|
||||
status_t err = (status_t) FAILED_TRANSACTION;
|
||||
sp<IQService> binder = getBinder();
|
||||
Parcel inParcel, outParcel;
|
||||
if(binder != NULL) {
|
||||
err = binder->dispatch(IQService::CHECK_EXTERNAL_STATUS,
|
||||
&inParcel , &outParcel);
|
||||
}
|
||||
if(err) {
|
||||
ALOGE("%s: Failed to get external status err=%d", __FUNCTION__, err);
|
||||
ret = err;
|
||||
} else {
|
||||
ret = outParcel.readInt32();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int getDisplayAttributes(int dpy, DisplayAttributes_t& dpyattr) {
|
||||
status_t err = (status_t) FAILED_TRANSACTION;
|
||||
sp<IQService> binder = getBinder();
|
||||
Parcel inParcel, outParcel;
|
||||
inParcel.writeInt32(dpy);
|
||||
if(binder != NULL) {
|
||||
err = binder->dispatch(IQService::GET_DISPLAY_ATTRIBUTES,
|
||||
&inParcel, &outParcel);
|
||||
}
|
||||
if(!err) {
|
||||
dpyattr.vsync_period = outParcel.readInt32();
|
||||
dpyattr.xres = outParcel.readInt32();
|
||||
dpyattr.yres = outParcel.readInt32();
|
||||
dpyattr.xdpi = outParcel.readFloat();
|
||||
dpyattr.ydpi = outParcel.readFloat();
|
||||
dpyattr.panel_type = outParcel.readInt32();
|
||||
} else {
|
||||
ALOGE("%s() failed with err %d", __FUNCTION__, err);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int setHSIC(int dpy, const HSICData_t& hsic_data) {
|
||||
status_t err = (status_t) FAILED_TRANSACTION;
|
||||
sp<IQService> binder = getBinder();
|
||||
Parcel inParcel, outParcel;
|
||||
inParcel.writeInt32(dpy);
|
||||
inParcel.writeInt32(hsic_data.hue);
|
||||
inParcel.writeFloat(hsic_data.saturation);
|
||||
inParcel.writeInt32(hsic_data.intensity);
|
||||
inParcel.writeFloat(hsic_data.contrast);
|
||||
if(binder != NULL) {
|
||||
err = binder->dispatch(IQService::SET_HSIC_DATA, &inParcel, &outParcel);
|
||||
}
|
||||
if(err)
|
||||
ALOGE("%s: Failed to get external status err=%d", __FUNCTION__, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
int getDisplayVisibleRegion(int dpy, hwc_rect_t &rect) {
|
||||
status_t err = (status_t) FAILED_TRANSACTION;
|
||||
sp<IQService> binder = getBinder();
|
||||
Parcel inParcel, outParcel;
|
||||
inParcel.writeInt32(dpy);
|
||||
if(binder != NULL) {
|
||||
err = binder->dispatch(IQService::GET_DISPLAY_VISIBLE_REGION,
|
||||
&inParcel, &outParcel);
|
||||
}
|
||||
if(!err) {
|
||||
rect.left = outParcel.readInt32();
|
||||
rect.top = outParcel.readInt32();
|
||||
rect.right = outParcel.readInt32();
|
||||
rect.bottom = outParcel.readInt32();
|
||||
} else {
|
||||
ALOGE("%s: Failed to getVisibleRegion for dpy =%d: err = %d",
|
||||
__FUNCTION__, dpy, err);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int setViewFrame(int dpy, int l, int t, int r, int b) {
|
||||
status_t err = (status_t) FAILED_TRANSACTION;
|
||||
sp<IQService> binder = getBinder();
|
||||
Parcel inParcel, outParcel;
|
||||
inParcel.writeInt32(dpy);
|
||||
inParcel.writeInt32(l);
|
||||
inParcel.writeInt32(t);
|
||||
inParcel.writeInt32(r);
|
||||
inParcel.writeInt32(b);
|
||||
|
||||
if(binder != NULL) {
|
||||
err = binder->dispatch(IQService::SET_VIEW_FRAME,
|
||||
&inParcel, &outParcel);
|
||||
}
|
||||
if(err)
|
||||
ALOGE("%s: Failed to set view frame for dpy %d err=%d",
|
||||
__FUNCTION__, dpy, err);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int setSecondaryDisplayStatus(int dpy, uint32_t status) {
|
||||
status_t err = (status_t) FAILED_TRANSACTION;
|
||||
sp<IQService> binder = getBinder();
|
||||
Parcel inParcel, outParcel;
|
||||
inParcel.writeInt32(dpy);
|
||||
inParcel.writeInt32(status);
|
||||
|
||||
if(binder != NULL) {
|
||||
err = binder->dispatch(IQService::SET_SECONDARY_DISPLAY_STATUS,
|
||||
&inParcel, &outParcel);
|
||||
}
|
||||
if(err)
|
||||
ALOGE("%s: Failed for dpy %d status = %d err=%d", __FUNCTION__, dpy,
|
||||
status, err);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int configureDynRefreshRate(uint32_t op, uint32_t refreshRate) {
|
||||
status_t err = (status_t) FAILED_TRANSACTION;
|
||||
sp<IQService> binder = getBinder();
|
||||
Parcel inParcel, outParcel;
|
||||
inParcel.writeInt32(op);
|
||||
inParcel.writeInt32(refreshRate);
|
||||
|
||||
if(binder != NULL) {
|
||||
err = binder->dispatch(IQService::CONFIGURE_DYN_REFRESH_RATE,
|
||||
&inParcel, &outParcel);
|
||||
}
|
||||
|
||||
if(err)
|
||||
ALOGE("%s: Failed setting op %d err=%d", __FUNCTION__, op, err);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int getConfigCount(int /*dpy*/) {
|
||||
int numConfigs = -1;
|
||||
sp<IQService> binder = getBinder();
|
||||
if(binder != NULL) {
|
||||
Parcel inParcel, outParcel;
|
||||
inParcel.writeInt32(DISPLAY_PRIMARY);
|
||||
status_t err = binder->dispatch(IQService::GET_CONFIG_COUNT,
|
||||
&inParcel, &outParcel);
|
||||
if(!err) {
|
||||
numConfigs = outParcel.readInt32();
|
||||
ALOGI("%s() Received num configs %d", __FUNCTION__, numConfigs);
|
||||
} else {
|
||||
ALOGE("%s() failed with err %d", __FUNCTION__, err);
|
||||
}
|
||||
}
|
||||
return numConfigs;
|
||||
}
|
||||
|
||||
int getActiveConfig(int dpy) {
|
||||
int configIndex = -1;
|
||||
sp<IQService> binder = getBinder();
|
||||
if(binder != NULL) {
|
||||
Parcel inParcel, outParcel;
|
||||
inParcel.writeInt32(dpy);
|
||||
status_t err = binder->dispatch(IQService::GET_ACTIVE_CONFIG,
|
||||
&inParcel, &outParcel);
|
||||
if(!err) {
|
||||
configIndex = outParcel.readInt32();
|
||||
ALOGI("%s() Received active config index %d", __FUNCTION__,
|
||||
configIndex);
|
||||
} else {
|
||||
ALOGE("%s() failed with err %d", __FUNCTION__, err);
|
||||
}
|
||||
}
|
||||
return configIndex;
|
||||
}
|
||||
|
||||
int setActiveConfig(int configIndex, int /*dpy*/) {
|
||||
status_t err = (status_t) FAILED_TRANSACTION;
|
||||
sp<IQService> binder = getBinder();
|
||||
if(binder != NULL) {
|
||||
Parcel inParcel, outParcel;
|
||||
inParcel.writeInt32(configIndex);
|
||||
inParcel.writeInt32(DISPLAY_PRIMARY);
|
||||
err = binder->dispatch(IQService::SET_ACTIVE_CONFIG,
|
||||
&inParcel, &outParcel);
|
||||
if(!err) {
|
||||
ALOGI("%s() Successfully set active config index %d", __FUNCTION__,
|
||||
configIndex);
|
||||
} else {
|
||||
ALOGE("%s() failed with err %d", __FUNCTION__, err);
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
DisplayAttributes getDisplayAttributes(int configIndex, int dpy) {
|
||||
DisplayAttributes dpyattr = {};
|
||||
sp<IQService> binder = getBinder();
|
||||
if(binder != NULL) {
|
||||
Parcel inParcel, outParcel;
|
||||
inParcel.writeInt32(configIndex);
|
||||
inParcel.writeInt32(dpy);
|
||||
status_t err = binder->dispatch(
|
||||
IQService::GET_DISPLAY_ATTRIBUTES_FOR_CONFIG, &inParcel,
|
||||
&outParcel);
|
||||
if(!err) {
|
||||
dpyattr.vsync_period = outParcel.readInt32();
|
||||
dpyattr.xres = outParcel.readInt32();
|
||||
dpyattr.yres = outParcel.readInt32();
|
||||
dpyattr.xdpi = outParcel.readFloat();
|
||||
dpyattr.ydpi = outParcel.readFloat();
|
||||
dpyattr.panel_type = outParcel.readInt32();
|
||||
dpyattr.is_yuv = outParcel.readInt32();
|
||||
ALOGI("%s() Received attrs for index %d: xres %d, yres %d",
|
||||
__FUNCTION__, configIndex, dpyattr.xres, dpyattr.yres);
|
||||
} else {
|
||||
ALOGE("%s() failed with err %d", __FUNCTION__, err);
|
||||
}
|
||||
}
|
||||
return dpyattr;
|
||||
}
|
||||
|
||||
int setPanelMode(int mode) {
|
||||
status_t err = (status_t) FAILED_TRANSACTION;
|
||||
sp<IQService> binder = getBinder();
|
||||
if(binder != NULL) {
|
||||
Parcel inParcel, outParcel;
|
||||
inParcel.writeInt32(mode);
|
||||
err = binder->dispatch(IQService::SET_DISPLAY_MODE,
|
||||
&inParcel, &outParcel);
|
||||
if(!err) {
|
||||
ALOGI("%s() Successfully set the display mode to %d", __FUNCTION__,
|
||||
mode);
|
||||
} else {
|
||||
ALOGE("%s() failed with err %d", __FUNCTION__, err);
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int setPanelBrightness(int level) {
|
||||
status_t err = (status_t) FAILED_TRANSACTION;
|
||||
sp<IQService> binder = getBinder();
|
||||
Parcel inParcel, outParcel;
|
||||
|
||||
if(binder != NULL) {
|
||||
inParcel.writeInt32(level);
|
||||
status_t err = binder->dispatch(IQService::SET_PANEL_BRIGHTNESS,
|
||||
&inParcel, &outParcel);
|
||||
if(err) {
|
||||
ALOGE("%s() failed with err %d", __FUNCTION__, err);
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int getPanelBrightness() {
|
||||
int panel_brightness = -1;
|
||||
sp<IQService> binder = getBinder();
|
||||
Parcel inParcel, outParcel;
|
||||
|
||||
if(binder != NULL) {
|
||||
status_t err = binder->dispatch(IQService::GET_PANEL_BRIGHTNESS,
|
||||
&inParcel, &outParcel);
|
||||
if(!err) {
|
||||
panel_brightness = outParcel.readInt32();
|
||||
ALOGI("%s() Current panel brightness value %d", __FUNCTION__,
|
||||
panel_brightness);
|
||||
} else {
|
||||
ALOGE("%s() failed with err %d", __FUNCTION__, err);
|
||||
}
|
||||
}
|
||||
return panel_brightness;
|
||||
}
|
||||
|
||||
}// namespace
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Functions for linking dynamically to libqdutils
|
||||
// ----------------------------------------------------------------------------
|
||||
extern "C" int minHdcpEncryptionLevelChanged(int dpy, int min_enc_level) {
|
||||
status_t err = (status_t) FAILED_TRANSACTION;
|
||||
sp<IQService> binder = getBinder();
|
||||
Parcel inParcel, outParcel;
|
||||
inParcel.writeInt32(dpy);
|
||||
inParcel.writeInt32(min_enc_level);
|
||||
|
||||
if(binder != NULL) {
|
||||
err = binder->dispatch(IQService::MIN_HDCP_ENCRYPTION_LEVEL_CHANGED,
|
||||
&inParcel, &outParcel);
|
||||
}
|
||||
|
||||
if(err) {
|
||||
ALOGE("%s: Failed for dpy %d err=%d", __FUNCTION__, dpy, err);
|
||||
} else {
|
||||
err = outParcel.readInt32();
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
extern "C" int refreshScreen() {
|
||||
int ret = 0;
|
||||
ret = screenRefresh();
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" int controlPartialUpdate(int dpy, int mode) {
|
||||
status_t err = (status_t) FAILED_TRANSACTION;
|
||||
sp<IQService> binder = getBinder();
|
||||
if(binder != NULL) {
|
||||
Parcel inParcel, outParcel;
|
||||
inParcel.writeInt32(dpy);
|
||||
inParcel.writeInt32(mode);
|
||||
err = binder->dispatch(IQService::CONTROL_PARTIAL_UPDATE, &inParcel, &outParcel);
|
||||
if(err != 0) {
|
||||
ALOGE_IF(getBinder(), "%s() failed with err %d", __FUNCTION__, err);
|
||||
} else {
|
||||
return outParcel.readInt32();
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
// returns 0 if composer is up
|
||||
extern "C" int waitForComposerInit() {
|
||||
int status = false;
|
||||
sp<IQService> binder = getBinder();
|
||||
if (binder == NULL) {
|
||||
sleep(2);
|
||||
binder = getBinder();
|
||||
}
|
||||
|
||||
if (binder != NULL) {
|
||||
Parcel inParcel, outParcel;
|
||||
binder->dispatch(IQService::GET_COMPOSER_STATUS, &inParcel, &outParcel);
|
||||
status = !!outParcel.readInt32();
|
||||
if (!status) {
|
||||
sleep(2);
|
||||
binder->dispatch(IQService::GET_COMPOSER_STATUS, &inParcel, &outParcel);
|
||||
status = !!outParcel.readInt32();
|
||||
}
|
||||
}
|
||||
|
||||
return !status;
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013 - 2016 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 _DISPLAY_CONFIG_H
|
||||
#define _DISPLAY_CONFIG_H
|
||||
|
||||
#include <gralloc_priv.h>
|
||||
#include <qdMetaData.h>
|
||||
#include <hardware/hwcomposer.h>
|
||||
|
||||
// This header is for clients to use to set/get global display configuration.
|
||||
// Only primary and external displays are supported here.
|
||||
|
||||
namespace qdutils {
|
||||
|
||||
|
||||
/* TODO: Have all the common enums that need be exposed to clients and which
|
||||
* are also needed in hwc defined here. Remove such definitions we have in
|
||||
* hwc_utils.h
|
||||
*/
|
||||
|
||||
// Use this enum to specify the dpy parameters where needed
|
||||
enum {
|
||||
DISPLAY_PRIMARY = HWC_DISPLAY_PRIMARY,
|
||||
DISPLAY_EXTERNAL = HWC_DISPLAY_EXTERNAL,
|
||||
#ifdef QTI_BSP
|
||||
DISPLAY_TERTIARY = HWC_DISPLAY_TERTIARY,
|
||||
#endif
|
||||
DISPLAY_VIRTUAL = HWC_DISPLAY_VIRTUAL,
|
||||
};
|
||||
|
||||
// External Display states - used in setSecondaryDisplayStatus()
|
||||
// To be consistent with the same defined in hwc_utils.h
|
||||
enum {
|
||||
EXTERNAL_OFFLINE = 0,
|
||||
EXTERNAL_ONLINE,
|
||||
EXTERNAL_PAUSE,
|
||||
EXTERNAL_RESUME,
|
||||
};
|
||||
|
||||
enum {
|
||||
DISABLE_METADATA_DYN_REFRESH_RATE = 0,
|
||||
ENABLE_METADATA_DYN_REFRESH_RATE,
|
||||
SET_BINDER_DYN_REFRESH_RATE,
|
||||
};
|
||||
|
||||
enum {
|
||||
DEFAULT_MODE = 0,
|
||||
VIDEO_MODE,
|
||||
COMMAND_MODE,
|
||||
};
|
||||
|
||||
enum {
|
||||
DISPLAY_PORT_DEFAULT = 0,
|
||||
DISPLAY_PORT_DSI,
|
||||
DISPLAY_PORT_DTV,
|
||||
DISPLAY_PORT_WRITEBACK,
|
||||
DISPLAY_PORT_LVDS,
|
||||
DISPLAY_PORT_EDP,
|
||||
DISPLAY_PORT_DP,
|
||||
};
|
||||
|
||||
// Display Attributes that are available to clients of this library
|
||||
// Not to be confused with a similar struct in hwc_utils (in the hwc namespace)
|
||||
typedef struct DisplayAttributes {
|
||||
uint32_t vsync_period = 0; //nanoseconds
|
||||
uint32_t xres = 0;
|
||||
uint32_t yres = 0;
|
||||
float xdpi = 0.0f;
|
||||
float ydpi = 0.0f;
|
||||
int panel_type = DISPLAY_PORT_DEFAULT;
|
||||
bool is_yuv = false;
|
||||
} DisplayAttributes_t;
|
||||
|
||||
//=============================================================================
|
||||
// The functions below run in the client process and wherever necessary
|
||||
// do a binder call to HWC to get/set data.
|
||||
|
||||
// Check if external display is connected. Useful to check before making
|
||||
// calls for external displays
|
||||
// Returns 1 if connected, 0 if disconnected, negative values on errors
|
||||
int isExternalConnected(void);
|
||||
|
||||
// Get display vsync period which is in nanoseconds
|
||||
// i.e vsync_period = 1000000000l / fps
|
||||
// Returns 0 on success, negative values on errors
|
||||
int getDisplayAttributes(int dpy, DisplayAttributes_t& dpyattr);
|
||||
|
||||
// Set HSIC data on a given display ID
|
||||
// Returns 0 on success, negative values on errors
|
||||
int setHSIC(int dpy, const HSICData_t& hsic_data);
|
||||
|
||||
// get the active visible region for the display
|
||||
// Returns 0 on success, negative values on errors
|
||||
int getDisplayVisibleRegion(int dpy, hwc_rect_t &rect);
|
||||
|
||||
// set the view frame information in hwc context from surfaceflinger
|
||||
int setViewFrame(int dpy, int l, int t, int r, int b);
|
||||
|
||||
// Set the secondary display status(pause/resume/offline etc.,)
|
||||
int setSecondaryDisplayStatus(int dpy, uint32_t status);
|
||||
|
||||
// Enable/Disable/Set refresh rate dynamically
|
||||
int configureDynRefreshRate(uint32_t op, uint32_t refreshRate);
|
||||
|
||||
// Returns the number of configs supported for the display on success.
|
||||
// Returns -1 on error.
|
||||
// Only primary display supported for now, value of dpy ignored.
|
||||
int getConfigCount(int dpy);
|
||||
|
||||
// Returns the index of config that is current set for the display on success.
|
||||
// Returns -1 on error.
|
||||
// Only primary display supported for now, value of dpy ignored.
|
||||
int getActiveConfig(int dpy);
|
||||
|
||||
// Sets the config for the display on success and returns 0.
|
||||
// Returns -1 on error.
|
||||
// Only primary display supported for now, value of dpy ignored
|
||||
int setActiveConfig(int configIndex, int dpy);
|
||||
|
||||
// Returns the attributes for the specified config for the display on success.
|
||||
// Returns xres and yres as 0 on error.
|
||||
// Only primary display supported for now, value of dpy ignored
|
||||
DisplayAttributes getDisplayAttributes(int configIndex, int dpy);
|
||||
|
||||
// Set the primary display mode to command or video mode
|
||||
int setDisplayMode(int mode);
|
||||
|
||||
// Sets the panel brightness of the primary display
|
||||
int setPanelBrightness(int level);
|
||||
|
||||
// Retrieves the current panel brightness value
|
||||
int getPanelBrightness();
|
||||
|
||||
}; //namespace
|
||||
|
||||
|
||||
extern "C" int waitForComposerInit();
|
||||
#endif
|
||||
@@ -1,365 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 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 <unistd.h>
|
||||
#include <gralloc_priv.h>
|
||||
#include "qd_utils.h"
|
||||
|
||||
static const int kFBNodeMax = 4;
|
||||
namespace qdutils {
|
||||
|
||||
static int parseLine(char *input, char *tokens[], const uint32_t maxToken, uint32_t *count) {
|
||||
char *tmpToken = NULL;
|
||||
char *tmpPtr;
|
||||
uint32_t index = 0;
|
||||
const char *delim = ", =\n";
|
||||
if (!input) {
|
||||
return -1;
|
||||
}
|
||||
tmpToken = strtok_r(input, delim, &tmpPtr);
|
||||
while (tmpToken && index < maxToken) {
|
||||
tokens[index++] = tmpToken;
|
||||
tmpToken = strtok_r(NULL, delim, &tmpPtr);
|
||||
}
|
||||
*count = index;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int getExternalNode(const char *type) {
|
||||
FILE *displayDeviceFP = NULL;
|
||||
char fbType[MAX_FRAME_BUFFER_NAME_SIZE];
|
||||
char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE];
|
||||
int j = 0;
|
||||
|
||||
for(j = 0; j < kFBNodeMax; j++) {
|
||||
snprintf (msmFbTypePath, sizeof(msmFbTypePath),
|
||||
"/sys/devices/virtual/graphics/fb%d/msm_fb_type", j);
|
||||
displayDeviceFP = fopen(msmFbTypePath, "r");
|
||||
if(displayDeviceFP) {
|
||||
fread(fbType, sizeof(char), MAX_FRAME_BUFFER_NAME_SIZE,
|
||||
displayDeviceFP);
|
||||
if(strncmp(fbType, type, strlen(type)) == 0) {
|
||||
ALOGD("%s: %s is at fb%d", __func__, type, j);
|
||||
fclose(displayDeviceFP);
|
||||
break;
|
||||
}
|
||||
fclose(displayDeviceFP);
|
||||
} else {
|
||||
ALOGE("%s: Failed to open fb node %s", __func__, msmFbTypePath);
|
||||
}
|
||||
}
|
||||
|
||||
if (j < kFBNodeMax)
|
||||
return j;
|
||||
else
|
||||
ALOGE("%s: Failed to find %s node", __func__, type);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int querySDEInfoDRM(HWQueryType type, int *value) {
|
||||
char property[PROPERTY_VALUE_MAX] = {0};
|
||||
|
||||
// TODO(user): If future targets don't support WB UBWC, add separate
|
||||
// properties in target specific system.prop and have clients like WFD
|
||||
// directly rely on those.
|
||||
switch(type) {
|
||||
case HAS_UBWC:
|
||||
case HAS_WB_UBWC: // WFD stack still uses this
|
||||
*value = 1;
|
||||
property_get(DISABLE_UBWC_PROP, property, "0");
|
||||
if(!(strncmp(property, "1", PROPERTY_VALUE_MAX)) ||
|
||||
!(strncmp(property, "true", PROPERTY_VALUE_MAX))) {
|
||||
*value = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ALOGE("Invalid query type %d", type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int querySDEInfoFB(HWQueryType type, int *value) {
|
||||
FILE *fileptr = NULL;
|
||||
const char *featureName;
|
||||
char stringBuffer[MAX_STRING_LENGTH];
|
||||
uint32_t tokenCount = 0;
|
||||
const uint32_t maxCount = 10;
|
||||
char *tokens[maxCount] = { NULL };
|
||||
|
||||
switch(type) {
|
||||
case HAS_UBWC:
|
||||
featureName = "ubwc";
|
||||
break;
|
||||
case HAS_WB_UBWC:
|
||||
featureName = "wb_ubwc";
|
||||
break;
|
||||
default:
|
||||
ALOGE("Invalid query type %d", type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
fileptr = fopen("/sys/devices/virtual/graphics/fb0/mdp/caps", "rb");
|
||||
if (!fileptr) {
|
||||
ALOGE("File '%s' not found", stringBuffer);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
size_t len = MAX_STRING_LENGTH;
|
||||
ssize_t read;
|
||||
char *line = stringBuffer;
|
||||
while ((read = getline(&line, &len, fileptr)) != -1) {
|
||||
// parse the line and update information accordingly
|
||||
if (parseLine(line, tokens, maxCount, &tokenCount)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strncmp(tokens[0], "features", strlen("features"))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < tokenCount; i++) {
|
||||
if (!strncmp(tokens[i], featureName, strlen(featureName))) {
|
||||
*value = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fileptr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int querySDEInfo(HWQueryType type, int *value) {
|
||||
if (!value) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (getDriverType() == DriverType::DRM) {
|
||||
return querySDEInfoDRM(type, value);
|
||||
}
|
||||
|
||||
return querySDEInfoFB(type, value);
|
||||
}
|
||||
|
||||
int getHDMINode(void) {
|
||||
return getExternalNode("dtv panel");
|
||||
}
|
||||
|
||||
int getEdidRawData(char *buffer)
|
||||
{
|
||||
int size;
|
||||
int edidFile;
|
||||
char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE];
|
||||
int node_id = getHDMINode();
|
||||
|
||||
if (node_id < 0) {
|
||||
ALOGE("%s no HDMI node found", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
snprintf(msmFbTypePath, sizeof(msmFbTypePath),
|
||||
"/sys/devices/virtual/graphics/fb%d/edid_raw_data", node_id);
|
||||
|
||||
edidFile = open(msmFbTypePath, O_RDONLY, 0);
|
||||
|
||||
if (edidFile < 0) {
|
||||
ALOGE("%s no edid raw data found %s", __func__,msmFbTypePath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
size = (int)read(edidFile, (char*)buffer, EDID_RAW_DATA_SIZE);
|
||||
close(edidFile);
|
||||
return size;
|
||||
}
|
||||
|
||||
bool isDPConnected() {
|
||||
char connectPath[MAX_FRAME_BUFFER_NAME_SIZE];
|
||||
FILE *connectFile = NULL;
|
||||
size_t len = MAX_STRING_LENGTH;
|
||||
char stringBuffer[MAX_STRING_LENGTH];
|
||||
char *line = stringBuffer;
|
||||
|
||||
int nodeId = getExternalNode("dp panel");
|
||||
if (nodeId < 0) {
|
||||
ALOGE("%s no DP node found", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
snprintf(connectPath, sizeof(connectPath),
|
||||
"/sys/devices/virtual/graphics/fb%d/connected", nodeId);
|
||||
|
||||
connectFile = fopen(connectPath, "rb");
|
||||
if (!connectFile) {
|
||||
ALOGW("Failed to open connect node for device node %s", connectPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getline(&line, &len, connectFile) < 0) {
|
||||
fclose(connectFile);
|
||||
return false;
|
||||
}
|
||||
|
||||
fclose(connectFile);
|
||||
|
||||
return atoi(line);
|
||||
}
|
||||
|
||||
int getDPTestConfig(uint32_t *panelBpp, uint32_t *patternType) {
|
||||
if (!panelBpp || !patternType) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
char configPath[MAX_FRAME_BUFFER_NAME_SIZE];
|
||||
FILE *configFile = NULL;
|
||||
uint32_t tokenCount = 0;
|
||||
const uint32_t maxCount = 10;
|
||||
char *tokens[maxCount] = { NULL };
|
||||
size_t len = MAX_STRING_LENGTH;
|
||||
char stringBuffer[MAX_STRING_LENGTH];
|
||||
char *line = stringBuffer;
|
||||
|
||||
int nodeId = getExternalNode("dp panel");
|
||||
if (nodeId < 0) {
|
||||
ALOGE("%s no DP node found", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
snprintf(configPath, sizeof(configPath),
|
||||
"/sys/devices/virtual/graphics/fb%d/config", nodeId);
|
||||
|
||||
configFile = fopen(configPath, "rb");
|
||||
if (!configFile) {
|
||||
ALOGW("Failed to open config node for device node %s", configPath);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
while (getline(&line, &len, configFile) != -1) {
|
||||
if (!parseLine(line, tokens, maxCount, &tokenCount)) {
|
||||
if (tokens[0] != NULL) {
|
||||
if (!strncmp(tokens[0], "bpp", strlen("bpp"))) {
|
||||
*panelBpp = static_cast<uint32_t>(atoi(tokens[1]));
|
||||
} else if (!strncmp(tokens[0], "pattern", strlen("pattern"))) {
|
||||
*patternType = static_cast<uint32_t>(atoi(tokens[1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(configFile);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DriverType getDriverType() {
|
||||
const char *fb_caps = "/sys/devices/virtual/graphics/fb0/mdp/caps";
|
||||
// 0 - File exists
|
||||
return access(fb_caps, F_OK) ? DriverType::DRM : DriverType::FB;
|
||||
}
|
||||
|
||||
const char *GetHALPixelFormatString(int format) {
|
||||
switch (format) {
|
||||
case HAL_PIXEL_FORMAT_RGBA_8888:
|
||||
return "RGBA_8888";
|
||||
case HAL_PIXEL_FORMAT_RGBX_8888:
|
||||
return "RGBX_8888";
|
||||
case HAL_PIXEL_FORMAT_RGB_888:
|
||||
return "RGB_888";
|
||||
case HAL_PIXEL_FORMAT_RGB_565:
|
||||
return "RGB_565";
|
||||
case HAL_PIXEL_FORMAT_BGR_565:
|
||||
return "BGR_565";
|
||||
case HAL_PIXEL_FORMAT_BGRA_8888:
|
||||
return "BGRA_8888";
|
||||
case HAL_PIXEL_FORMAT_RGBA_5551:
|
||||
return "RGBA_5551";
|
||||
case HAL_PIXEL_FORMAT_RGBA_4444:
|
||||
return "RGBA_4444";
|
||||
case HAL_PIXEL_FORMAT_YV12:
|
||||
return "YV12";
|
||||
case HAL_PIXEL_FORMAT_YCbCr_422_SP:
|
||||
return "YCbCr_422_SP_NV16";
|
||||
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
|
||||
return "YCrCb_420_SP_NV21";
|
||||
case HAL_PIXEL_FORMAT_YCbCr_422_I:
|
||||
return "YCbCr_422_I_YUY2";
|
||||
case HAL_PIXEL_FORMAT_YCrCb_422_I:
|
||||
return "YCrCb_422_I_YVYU";
|
||||
case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
|
||||
return "NV12_ENCODEABLE";
|
||||
case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
|
||||
return "YCbCr_420_SP_TILED_TILE_4x2";
|
||||
case HAL_PIXEL_FORMAT_YCbCr_420_SP:
|
||||
return "YCbCr_420_SP";
|
||||
case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
|
||||
return "YCrCb_420_SP_ADRENO";
|
||||
case HAL_PIXEL_FORMAT_YCrCb_422_SP:
|
||||
return "YCrCb_422_SP";
|
||||
case HAL_PIXEL_FORMAT_R_8:
|
||||
return "R_8";
|
||||
case HAL_PIXEL_FORMAT_RG_88:
|
||||
return "RG_88";
|
||||
case HAL_PIXEL_FORMAT_INTERLACE:
|
||||
return "INTERLACE";
|
||||
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
|
||||
return "YCbCr_420_SP_VENUS";
|
||||
case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
|
||||
return "YCrCb_420_SP_VENUS";
|
||||
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
|
||||
return "YCbCr_420_SP_VENUS_UBWC";
|
||||
case HAL_PIXEL_FORMAT_RGBA_1010102:
|
||||
return "RGBA_1010102";
|
||||
case HAL_PIXEL_FORMAT_ARGB_2101010:
|
||||
return "ARGB_2101010";
|
||||
case HAL_PIXEL_FORMAT_RGBX_1010102:
|
||||
return "RGBX_1010102";
|
||||
case HAL_PIXEL_FORMAT_XRGB_2101010:
|
||||
return "XRGB_2101010";
|
||||
case HAL_PIXEL_FORMAT_BGRA_1010102:
|
||||
return "BGRA_1010102";
|
||||
case HAL_PIXEL_FORMAT_ABGR_2101010:
|
||||
return "ABGR_2101010";
|
||||
case HAL_PIXEL_FORMAT_BGRX_1010102:
|
||||
return "BGRX_1010102";
|
||||
case HAL_PIXEL_FORMAT_XBGR_2101010:
|
||||
return "XBGR_2101010";
|
||||
case HAL_PIXEL_FORMAT_YCbCr_420_P010:
|
||||
return "YCbCr_420_P010";
|
||||
case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
|
||||
return "YCbCr_420_TP10_UBWC";
|
||||
case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
|
||||
return "YCbCr_420_P010_VENUS";
|
||||
default:
|
||||
return "Unknown_format";
|
||||
}
|
||||
}
|
||||
|
||||
}; //namespace qdutils
|
||||
@@ -1,16 +0,0 @@
|
||||
cc_library_shared {
|
||||
name: "libqservice",
|
||||
vendor: true,
|
||||
defaults: ["display_defaults"],
|
||||
shared_libs: ["libbinder"],
|
||||
cflags: [
|
||||
"-DLOG_TAG=\"qdqservice\"",
|
||||
"-Wno-sign-conversion",
|
||||
],
|
||||
srcs: [
|
||||
"QService.cpp",
|
||||
"IQService.cpp",
|
||||
"IQClient.cpp",
|
||||
"IQHDMIClient.cpp",
|
||||
],
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
* Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Not a Contribution, Apache license notifications and license are
|
||||
* retained for attribution purposes only.
|
||||
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <binder/Parcel.h>
|
||||
#include <binder/IBinder.h>
|
||||
#include <binder/IInterface.h>
|
||||
#include <utils/Errors.h>
|
||||
#include <IQClient.h>
|
||||
|
||||
using namespace android;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// XXX: Since qservice currently runs as part of hwc instead of a standalone
|
||||
// process, the implementation below is overridden and the notifyCallback in
|
||||
// hwc_qclient is directly called.
|
||||
|
||||
namespace qClient {
|
||||
|
||||
enum {
|
||||
NOTIFY_CALLBACK = IBinder::FIRST_CALL_TRANSACTION,
|
||||
};
|
||||
|
||||
class BpQClient : public BpInterface<IQClient>
|
||||
{
|
||||
public:
|
||||
BpQClient(const sp<IBinder>& impl)
|
||||
: BpInterface<IQClient>(impl) {}
|
||||
|
||||
virtual status_t notifyCallback(uint32_t command,
|
||||
const Parcel* inParcel,
|
||||
Parcel* outParcel) {
|
||||
Parcel data;
|
||||
Parcel *reply = outParcel;
|
||||
data.writeInterfaceToken(IQClient::getInterfaceDescriptor());
|
||||
data.writeInt32(command);
|
||||
if (inParcel->dataAvail())
|
||||
data.appendFrom(inParcel, inParcel->dataPosition(),
|
||||
inParcel->dataAvail());
|
||||
status_t result = remote()->transact(NOTIFY_CALLBACK, data, reply);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
IMPLEMENT_META_INTERFACE(QClient, "android.display.IQClient");
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
//Stub implementation - nothing needed here
|
||||
status_t BnQClient::onTransact(
|
||||
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
|
||||
{
|
||||
switch(code) {
|
||||
case NOTIFY_CALLBACK: {
|
||||
CHECK_INTERFACE(IQClient, data, reply);
|
||||
uint32_t command = data.readInt32();
|
||||
notifyCallback(command, &data, reply);
|
||||
return NO_ERROR;
|
||||
} break;
|
||||
default:
|
||||
return BBinder::onTransact(code, data, reply, flags);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}; // namespace qClient
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
* Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Not a Contribution, Apache license notifications and license are
|
||||
* retained for attribution purposes only.
|
||||
|
||||
* 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 ANDROID_IQCLIENT_H
|
||||
#define ANDROID_IQCLIENT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/RefBase.h>
|
||||
#include <binder/IInterface.h>
|
||||
|
||||
namespace qClient {
|
||||
// ----------------------------------------------------------------------------
|
||||
class IQClient : public android::IInterface
|
||||
{
|
||||
public:
|
||||
DECLARE_META_INTERFACE(QClient);
|
||||
virtual android::status_t notifyCallback(uint32_t command,
|
||||
const android::Parcel* inParcel,
|
||||
android::Parcel* outParcel) = 0;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class BnQClient : public android::BnInterface<IQClient>
|
||||
{
|
||||
public:
|
||||
virtual android::status_t onTransact( uint32_t code,
|
||||
const android::Parcel& data,
|
||||
android::Parcel* reply,
|
||||
uint32_t flags = 0);
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
}; // namespace qClient
|
||||
|
||||
#endif // ANDROID_IQCLIENT_H
|
||||
@@ -1,103 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 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 <binder/Parcel.h>
|
||||
#include "IQHDMIClient.h"
|
||||
|
||||
using namespace android;
|
||||
namespace qClient {
|
||||
|
||||
enum {
|
||||
HDMI_CONNECTED = IBinder::FIRST_CALL_TRANSACTION,
|
||||
CEC_MESSAGE_RECEIVED
|
||||
};
|
||||
|
||||
class BpQHDMIClient : public BpInterface<IQHDMIClient>
|
||||
{
|
||||
public:
|
||||
BpQHDMIClient(const sp<IBinder>& impl)
|
||||
:BpInterface<IQHDMIClient>(impl)
|
||||
{
|
||||
}
|
||||
|
||||
void onHdmiHotplug(int connected)
|
||||
{
|
||||
Parcel data, reply;
|
||||
data.writeInterfaceToken(IQHDMIClient::getInterfaceDescriptor());
|
||||
data.writeInt32(connected);
|
||||
remote()->transact(HDMI_CONNECTED, data, &reply, IBinder::FLAG_ONEWAY);
|
||||
}
|
||||
|
||||
void onCECMessageRecieved(char *msg, ssize_t len)
|
||||
{
|
||||
Parcel data, reply;
|
||||
data.writeInterfaceToken(IQHDMIClient::getInterfaceDescriptor());
|
||||
data.writeInt32((int32_t)len);
|
||||
void *buf = data.writeInplace(len);
|
||||
if (buf != NULL)
|
||||
memcpy(buf, msg, len);
|
||||
remote()->transact(CEC_MESSAGE_RECEIVED, data, &reply,
|
||||
IBinder::FLAG_ONEWAY);
|
||||
}
|
||||
};
|
||||
|
||||
IMPLEMENT_META_INTERFACE(QHDMIClient,
|
||||
"android.display.IQHDMIClient");
|
||||
|
||||
status_t BnQHDMIClient::onTransact(uint32_t code, const Parcel& data,
|
||||
Parcel* reply, uint32_t flags)
|
||||
{
|
||||
switch(code) {
|
||||
case HDMI_CONNECTED: {
|
||||
CHECK_INTERFACE(IQHDMIClient, data, reply);
|
||||
int connected = data.readInt32();
|
||||
onHdmiHotplug(connected);
|
||||
return NO_ERROR;
|
||||
}
|
||||
case CEC_MESSAGE_RECEIVED: {
|
||||
CHECK_INTERFACE(IQHDMIClient, data, reply);
|
||||
ssize_t len = data.readInt32();
|
||||
const void* msg;
|
||||
if(len >= 0 && len <= (ssize_t) data.dataAvail()) {
|
||||
msg = data.readInplace(len);
|
||||
} else {
|
||||
msg = NULL;
|
||||
len = 0;
|
||||
}
|
||||
if (msg != NULL)
|
||||
onCECMessageRecieved((char*) msg, len);
|
||||
return NO_ERROR;
|
||||
}
|
||||
default: {
|
||||
return BBinder::onTransact(code, data, reply, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}; //namespace qClient
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 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 HDMI_EVENTS_LISTENER_H_
|
||||
#define HDMI_EVENTS_LISTENER_H_
|
||||
|
||||
#include <utils/RefBase.h>
|
||||
#include <binder/IInterface.h>
|
||||
|
||||
namespace qClient {
|
||||
|
||||
class IQHDMIClient : public android::IInterface
|
||||
{
|
||||
public:
|
||||
DECLARE_META_INTERFACE(QHDMIClient);
|
||||
virtual void onHdmiHotplug(int connected) = 0;
|
||||
virtual void onCECMessageRecieved(char *msg, ssize_t len) = 0;
|
||||
};
|
||||
|
||||
class BnQHDMIClient : public android::BnInterface<IQHDMIClient>
|
||||
{
|
||||
public:
|
||||
virtual android::status_t onTransact( uint32_t code,
|
||||
const android::Parcel& data,
|
||||
android::Parcel* reply, uint32_t flags = 0);
|
||||
};
|
||||
|
||||
}; //namespace qhdmi
|
||||
|
||||
#endif // HDMI_EVENTS_LISTENER_H_
|
||||
|
||||
@@ -1,135 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
* Copyright (C) 2012-2016, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Not a Contribution, Apache license notifications and license are
|
||||
* retained for attribution purposes only.
|
||||
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <binder/Parcel.h>
|
||||
#include <binder/IBinder.h>
|
||||
#include <binder/IInterface.h>
|
||||
#include <binder/IPCThreadState.h>
|
||||
#include <cutils/android_filesystem_config.h>
|
||||
#include <utils/Errors.h>
|
||||
#include <IQService.h>
|
||||
|
||||
#define QSERVICE_DEBUG 0
|
||||
|
||||
using namespace android;
|
||||
using namespace qClient;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
namespace qService {
|
||||
|
||||
class BpQService : public BpInterface<IQService>
|
||||
{
|
||||
public:
|
||||
BpQService(const sp<IBinder>& impl)
|
||||
: BpInterface<IQService>(impl) {}
|
||||
|
||||
virtual void connect(const sp<IQClient>& client) {
|
||||
ALOGD_IF(QSERVICE_DEBUG, "%s: connect HWC client", __FUNCTION__);
|
||||
Parcel data, reply;
|
||||
data.writeInterfaceToken(IQService::getInterfaceDescriptor());
|
||||
data.writeStrongBinder(IInterface::asBinder(client));
|
||||
remote()->transact(CONNECT_HWC_CLIENT, data, &reply);
|
||||
}
|
||||
|
||||
virtual void connect(const sp<IQHDMIClient>& client) {
|
||||
ALOGD_IF(QSERVICE_DEBUG, "%s: connect HDMI client", __FUNCTION__);
|
||||
Parcel data, reply;
|
||||
data.writeInterfaceToken(IQService::getInterfaceDescriptor());
|
||||
data.writeStrongBinder(IInterface::asBinder(client));
|
||||
remote()->transact(CONNECT_HDMI_CLIENT, data, &reply);
|
||||
}
|
||||
|
||||
|
||||
virtual android::status_t dispatch(uint32_t command, const Parcel* inParcel,
|
||||
Parcel* outParcel) {
|
||||
ALOGD_IF(QSERVICE_DEBUG, "%s: dispatch in:%p", __FUNCTION__, inParcel);
|
||||
status_t err = (status_t) android::FAILED_TRANSACTION;
|
||||
Parcel data;
|
||||
Parcel *reply = outParcel;
|
||||
data.writeInterfaceToken(IQService::getInterfaceDescriptor());
|
||||
if (inParcel && inParcel->dataSize() > 0)
|
||||
data.appendFrom(inParcel, 0, inParcel->dataSize());
|
||||
err = remote()->transact(command, data, reply);
|
||||
return err;
|
||||
}
|
||||
};
|
||||
|
||||
IMPLEMENT_META_INTERFACE(QService, "android.display.IQService");
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
status_t BnQService::onTransact(
|
||||
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
|
||||
{
|
||||
ALOGD_IF(QSERVICE_DEBUG, "%s: code: %d", __FUNCTION__, code);
|
||||
// IPC should be from certain processes only
|
||||
IPCThreadState* ipc = IPCThreadState::self();
|
||||
const int callerPid = ipc->getCallingPid();
|
||||
const int callerUid = ipc->getCallingUid();
|
||||
|
||||
const bool permission = (callerUid == AID_MEDIA ||
|
||||
callerUid == AID_GRAPHICS ||
|
||||
callerUid == AID_ROOT ||
|
||||
callerUid == AID_CAMERASERVER ||
|
||||
callerUid == AID_AUDIO ||
|
||||
callerUid == AID_SYSTEM ||
|
||||
callerUid == AID_MEDIA_CODEC);
|
||||
|
||||
if (code == CONNECT_HWC_CLIENT) {
|
||||
CHECK_INTERFACE(IQService, data, reply);
|
||||
if(callerUid != AID_GRAPHICS) {
|
||||
ALOGE("display.qservice CONNECT_HWC_CLIENT access denied: pid=%d uid=%d",
|
||||
callerPid, callerUid);
|
||||
return PERMISSION_DENIED;
|
||||
}
|
||||
sp<IQClient> client =
|
||||
interface_cast<IQClient>(data.readStrongBinder());
|
||||
connect(client);
|
||||
return NO_ERROR;
|
||||
} else if(code == CONNECT_HDMI_CLIENT) {
|
||||
CHECK_INTERFACE(IQService, data, reply);
|
||||
if(callerUid != AID_SYSTEM && callerUid != AID_ROOT) {
|
||||
ALOGE("display.qservice CONNECT_HDMI_CLIENT access denied: pid=%d uid=%d",
|
||||
callerPid, callerUid);
|
||||
return PERMISSION_DENIED;
|
||||
}
|
||||
sp<IQHDMIClient> client =
|
||||
interface_cast<IQHDMIClient>(data.readStrongBinder());
|
||||
connect(client);
|
||||
return NO_ERROR;
|
||||
} else if (code > COMMAND_LIST_START && code < COMMAND_LIST_END) {
|
||||
if(!permission) {
|
||||
ALOGE("display.qservice access denied: command=%d pid=%d uid=%d",
|
||||
code, callerPid, callerUid);
|
||||
return PERMISSION_DENIED;
|
||||
}
|
||||
CHECK_INTERFACE(IQService, data, reply);
|
||||
dispatch(code, &data, reply);
|
||||
return NO_ERROR;
|
||||
} else {
|
||||
return BBinder::onTransact(code, data, reply, flags);
|
||||
}
|
||||
}
|
||||
|
||||
}; // namespace qService
|
||||
@@ -1,138 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
* Copyright (C) 2012-2014, 2016-2017 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Not a Contribution, Apache license notifications and license are
|
||||
* retained for attribution purposes only.
|
||||
|
||||
* 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 ANDROID_IQSERVICE_H
|
||||
#define ANDROID_IQSERVICE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/RefBase.h>
|
||||
#include <binder/IInterface.h>
|
||||
#include <binder/IBinder.h>
|
||||
#include <IQClient.h>
|
||||
#include <IQHDMIClient.h>
|
||||
|
||||
|
||||
namespace qService {
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class IQService : public android::IInterface
|
||||
{
|
||||
public:
|
||||
DECLARE_META_INTERFACE(QService);
|
||||
enum {
|
||||
COMMAND_LIST_START = android::IBinder::FIRST_CALL_TRANSACTION,
|
||||
GET_PANEL_BRIGHTNESS = 2, // Provides ability to set the panel brightness
|
||||
SET_PANEL_BRIGHTNESS = 3, // Provides ability to get the panel brightness
|
||||
CONNECT_HWC_CLIENT = 4, // Connect to qservice
|
||||
SCREEN_REFRESH = 5, // Refresh screen through SF invalidate
|
||||
EXTERNAL_ORIENTATION = 6,// Set external orientation
|
||||
BUFFER_MIRRORMODE = 7, // Buffer mirrormode
|
||||
CHECK_EXTERNAL_STATUS = 8,// Check status of external display
|
||||
GET_DISPLAY_ATTRIBUTES = 9,// Get display attributes
|
||||
SET_HSIC_DATA = 10, // Set HSIC on dspp
|
||||
GET_DISPLAY_VISIBLE_REGION = 11,// Get the visibleRegion for dpy
|
||||
SET_SECONDARY_DISPLAY_STATUS = 12,// Sets secondary display status
|
||||
SET_MAX_PIPES_PER_MIXER = 13,// Set max pipes per mixer for MDPComp
|
||||
SET_VIEW_FRAME = 14, // Set view frame of display
|
||||
DYNAMIC_DEBUG = 15, // Enable more logging on the fly
|
||||
SET_IDLE_TIMEOUT = 16, // Set idle timeout for GPU fallback
|
||||
TOGGLE_BWC = 17, // Toggle BWC On/Off on targets that support
|
||||
/* Enable/Disable/Set refresh rate dynamically */
|
||||
CONFIGURE_DYN_REFRESH_RATE = 18,
|
||||
CONTROL_PARTIAL_UPDATE = 19, // Provides ability to enable/disable partial update
|
||||
TOGGLE_SCREEN_UPDATES = 20, // Provides ability to set the panel brightness
|
||||
SET_FRAME_DUMP_CONFIG = 21, // Provides ability to set the frame dump config
|
||||
SET_S3D_MODE = 22, // Set the 3D mode as specified in msm_hdmi_modes.h
|
||||
CONNECT_HDMI_CLIENT = 23, // Connect HDMI CEC HAL Client
|
||||
QDCM_SVC_CMDS = 24, // request QDCM services.
|
||||
SET_ACTIVE_CONFIG = 25, //Set a specified display config
|
||||
GET_ACTIVE_CONFIG = 26, //Get the current config index
|
||||
GET_CONFIG_COUNT = 27, //Get the number of supported display configs
|
||||
GET_DISPLAY_ATTRIBUTES_FOR_CONFIG = 28, //Get attr for specified config
|
||||
SET_DISPLAY_MODE = 29, // Set display mode to command or video mode
|
||||
SET_CAMERA_STATUS = 30, // To notify display when camera is on and off
|
||||
MIN_HDCP_ENCRYPTION_LEVEL_CHANGED = 31,
|
||||
GET_BW_TRANSACTION_STATUS = 32, //Client can query BW transaction status.
|
||||
SET_LAYER_MIXER_RESOLUTION = 33, // Enables client to set layer mixer resolution.
|
||||
SET_COLOR_MODE = 34, // Overrides the QDCM mode on the display
|
||||
GET_HDR_CAPABILITIES = 35, // Get HDR capabilities for legacy HWC interface
|
||||
SET_COLOR_MODE_BY_ID = 36, // Overrides the QDCM mode using the given mode ID
|
||||
GET_COMPOSER_STATUS = 37, // Get composer init status-true if primary display init is done
|
||||
COMMAND_LIST_END = 400,
|
||||
};
|
||||
|
||||
enum {
|
||||
END = 0,
|
||||
START,
|
||||
};
|
||||
|
||||
enum {
|
||||
DEBUG_ALL,
|
||||
DEBUG_MDPCOMP,
|
||||
DEBUG_VSYNC,
|
||||
DEBUG_VD,
|
||||
DEBUG_PIPE_LIFECYCLE,
|
||||
DEBUG_DRIVER_CONFIG,
|
||||
DEBUG_ROTATOR,
|
||||
DEBUG_QDCM,
|
||||
DEBUG_SCALAR,
|
||||
DEBUG_CLIENT,
|
||||
DEBUG_DISPLAY,
|
||||
DEBUG_MAX_VAL = DEBUG_DISPLAY, // Used to check each bit of the debug command paramater.
|
||||
// Update DEBUG_MAX_VAL when adding new debug tag.
|
||||
};
|
||||
|
||||
enum {
|
||||
PREF_POST_PROCESSING,
|
||||
PREF_PARTIAL_UPDATE,
|
||||
ENABLE_PARTIAL_UPDATE,
|
||||
};
|
||||
|
||||
// Register a HWC client that can be notified
|
||||
// This client is generic and is intended to get
|
||||
// dispatches of all events calling into QService
|
||||
virtual void connect(const android::sp<qClient::IQClient>& client) = 0;
|
||||
// Register an HDMI client. This client gets notification of HDMI events
|
||||
// such as plug/unplug and CEC messages
|
||||
virtual void connect(const android::sp<qClient::IQHDMIClient>& client) = 0;
|
||||
// Generic function to dispatch binder commands
|
||||
// The type of command decides how the data is parceled
|
||||
virtual android::status_t dispatch(uint32_t command,
|
||||
const android::Parcel* inParcel,
|
||||
android::Parcel* outParcel) = 0;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class BnQService : public android::BnInterface<IQService>
|
||||
{
|
||||
public:
|
||||
virtual android::status_t onTransact( uint32_t code,
|
||||
const android::Parcel& data,
|
||||
android::Parcel* reply,
|
||||
uint32_t flags = 0);
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
}; // namespace qService
|
||||
|
||||
#endif // ANDROID_IQSERVICE_H
|
||||
@@ -1,18 +0,0 @@
|
||||
h_sources = IQService.h \
|
||||
IQClient.h
|
||||
|
||||
cpp_sources = QService.cpp \
|
||||
IQService.cpp \
|
||||
IQClient.cpp \
|
||||
IQHDMIClient.cpp
|
||||
|
||||
library_includedir = $(includedir)
|
||||
library_include_HEADERS = $(h_sources)
|
||||
|
||||
lib_LTLIBRARIES = libqservice.la
|
||||
libqservice_la_CC = @CC@
|
||||
libqservice_la_SOURCES = $(cpp_sources)
|
||||
libqservice_la_CFLAGS = $(COMMON_CFLAGS) -DLOG_TAG=\"qdqservice\"
|
||||
libqservice_la_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
libqservice_LDADD = -lhardware -lcutils -llog -lbinder
|
||||
libqservice_la_LDFLAGS = -shared -avoid-version
|
||||
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2014, 2016, 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 <QService.h>
|
||||
#include <binder/Parcel.h>
|
||||
#include <binder/IPCThreadState.h>
|
||||
|
||||
#define QSERVICE_DEBUG 0
|
||||
|
||||
using namespace android;
|
||||
|
||||
namespace qService {
|
||||
|
||||
QService* QService::sQService = NULL;
|
||||
// ----------------------------------------------------------------------------
|
||||
QService::QService()
|
||||
{
|
||||
ALOGD_IF(QSERVICE_DEBUG, "QService Constructor invoked");
|
||||
}
|
||||
|
||||
QService::~QService()
|
||||
{
|
||||
ALOGD_IF(QSERVICE_DEBUG,"QService Destructor invoked");
|
||||
}
|
||||
|
||||
void QService::connect(const sp<qClient::IQClient>& client) {
|
||||
ALOGD_IF(QSERVICE_DEBUG,"HWC client connected");
|
||||
mClient = client;
|
||||
}
|
||||
|
||||
void QService::connect(const sp<qClient::IQHDMIClient>& client) {
|
||||
ALOGD_IF(QSERVICE_DEBUG,"HDMI client connected");
|
||||
mHDMIClient = client;
|
||||
}
|
||||
|
||||
status_t QService::dispatch(uint32_t command, const Parcel* inParcel,
|
||||
Parcel* outParcel) {
|
||||
status_t err = (status_t) FAILED_TRANSACTION;
|
||||
IPCThreadState* ipc = IPCThreadState::self();
|
||||
//Rewind parcel in case we're calling from the same process
|
||||
bool sameProcess = (ipc->getCallingPid() == getpid());
|
||||
if(sameProcess)
|
||||
inParcel->setDataPosition(0);
|
||||
if (mClient.get()) {
|
||||
ALOGD_IF(QSERVICE_DEBUG, "Dispatching command: %d", command);
|
||||
err = mClient->notifyCallback(command, inParcel, outParcel);
|
||||
//Rewind parcel in case we're calling from the same process
|
||||
if (sameProcess)
|
||||
outParcel->setDataPosition(0);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
void QService::onHdmiHotplug(int connected) {
|
||||
if(mHDMIClient.get()) {
|
||||
ALOGD_IF(QSERVICE_DEBUG, "%s: HDMI hotplug", __FUNCTION__);
|
||||
mHDMIClient->onHdmiHotplug(connected);
|
||||
} else {
|
||||
ALOGW("%s: Failed to get a valid HDMI client", __FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
void QService::onCECMessageReceived(char *msg, ssize_t len) {
|
||||
if(mHDMIClient.get()) {
|
||||
ALOGD_IF(QSERVICE_DEBUG, "%s: CEC message received", __FUNCTION__);
|
||||
mHDMIClient->onCECMessageRecieved(msg, len);
|
||||
} else {
|
||||
ALOGW("%s: Failed to get a valid HDMI client", __FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void QService::init()
|
||||
{
|
||||
if(!sQService) {
|
||||
sQService = new QService();
|
||||
sp<IServiceManager> sm = defaultServiceManager();
|
||||
sm->addService(String16("display.qservice"), sQService);
|
||||
if(sm->checkService(String16("display.qservice")) != NULL)
|
||||
ALOGD_IF(QSERVICE_DEBUG, "adding display.qservice succeeded");
|
||||
else
|
||||
ALOGD_IF(QSERVICE_DEBUG, "adding display.qservice failed");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2013, 2016, 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 ANDROID_QSERVICE_H
|
||||
#define ANDROID_QSERVICE_H
|
||||
|
||||
#include <utils/Errors.h>
|
||||
#include <sys/types.h>
|
||||
#include <log/log.h>
|
||||
#include <binder/IServiceManager.h>
|
||||
#include <IQService.h>
|
||||
#include <IQClient.h>
|
||||
|
||||
struct hwc_context_t;
|
||||
|
||||
namespace qService {
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class QService : public BnQService {
|
||||
public:
|
||||
virtual ~QService();
|
||||
virtual void connect(const android::sp<qClient::IQClient>& client);
|
||||
virtual void connect(const android::sp<qClient::IQHDMIClient>& client);
|
||||
virtual android::status_t dispatch(uint32_t command,
|
||||
const android::Parcel* data,
|
||||
android::Parcel* reply);
|
||||
virtual void onHdmiHotplug(int connected);
|
||||
virtual void onCECMessageReceived(char *msg, ssize_t len);
|
||||
static void init();
|
||||
private:
|
||||
QService();
|
||||
android::sp<qClient::IQClient> mClient;
|
||||
android::sp<qClient::IQHDMIClient> mHDMIClient;
|
||||
static QService *sQService;
|
||||
};
|
||||
}; // namespace qService
|
||||
#endif // ANDROID_QSERVICE_H
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013-14 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 QSERVICEUTILS_H
|
||||
#define QSERVICEUTILS_H
|
||||
#include <binder/Parcel.h>
|
||||
#include <binder/IServiceManager.h>
|
||||
#include <utils/RefBase.h>
|
||||
#include <IQService.h>
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Helpers
|
||||
// ----------------------------------------------------------------------------
|
||||
inline android::sp<qService::IQService> getBinder() {
|
||||
android::sp<android::IServiceManager> sm = android::defaultServiceManager();
|
||||
android::sp<qService::IQService> binder =
|
||||
android::interface_cast<qService::IQService>
|
||||
(sm->getService(android::String16("display.qservice")));
|
||||
if (binder == NULL) {
|
||||
ALOGE("%s: invalid binder object", __FUNCTION__);
|
||||
}
|
||||
return binder;
|
||||
}
|
||||
|
||||
inline android::status_t sendSingleParam(uint32_t command, uint32_t value) {
|
||||
android::status_t err = (android::status_t) android::FAILED_TRANSACTION;
|
||||
android::sp<qService::IQService> binder = getBinder();
|
||||
android::Parcel inParcel, outParcel;
|
||||
inParcel.writeInt32(value);
|
||||
if(binder != NULL) {
|
||||
err = binder->dispatch(command, &inParcel , &outParcel);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Convenience wrappers that clients can call
|
||||
// ----------------------------------------------------------------------------
|
||||
inline android::status_t screenRefresh() {
|
||||
return sendSingleParam(qService::IQService::SCREEN_REFRESH, 1);
|
||||
}
|
||||
|
||||
inline android::status_t toggleScreenUpdate(uint32_t on) {
|
||||
return sendSingleParam(qService::IQService::TOGGLE_SCREEN_UPDATES, on);
|
||||
}
|
||||
|
||||
inline android::status_t setExtOrientation(uint32_t orientation) {
|
||||
return sendSingleParam(qService::IQService::EXTERNAL_ORIENTATION,
|
||||
orientation);
|
||||
}
|
||||
|
||||
inline android::status_t setBufferMirrorMode(uint32_t enable) {
|
||||
return sendSingleParam(qService::IQService::BUFFER_MIRRORMODE, enable);
|
||||
}
|
||||
|
||||
inline android::status_t setCameraLaunchStatus(uint32_t on) {
|
||||
return sendSingleParam(qService::IQService::SET_CAMERA_STATUS, on);
|
||||
}
|
||||
|
||||
inline bool displayBWTransactionPending() {
|
||||
android::status_t err = (android::status_t) android::FAILED_TRANSACTION;
|
||||
bool ret = false;
|
||||
android::sp<qService::IQService> binder = getBinder();
|
||||
android::Parcel inParcel, outParcel;
|
||||
if(binder != NULL) {
|
||||
err = binder->dispatch(qService::IQService::GET_BW_TRANSACTION_STATUS,
|
||||
&inParcel , &outParcel);
|
||||
if(err != android::NO_ERROR){
|
||||
ALOGE("GET_BW_TRANSACTION_STATUS binder call failed err=%d", err);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
ret = outParcel.readInt32();
|
||||
return ret;
|
||||
}
|
||||
#endif /* end of include guard: QSERVICEUTILS_H */
|
||||
@@ -1,159 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015 - 2017, 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.
|
||||
*/
|
||||
|
||||
/*! @file buffer_allocator.h
|
||||
@brief Interface file for platform specific buffer allocator.
|
||||
|
||||
@details This interface is used by SDM to allocate internal buffers.
|
||||
*/
|
||||
|
||||
#ifndef __BUFFER_ALLOCATOR_H__
|
||||
#define __BUFFER_ALLOCATOR_H__
|
||||
|
||||
#include "layer_buffer.h"
|
||||
|
||||
namespace sdm {
|
||||
/*! @brief Input configuration set by the client for buffer allocation.
|
||||
|
||||
@sa BufferInfo::BufferConfig
|
||||
*/
|
||||
|
||||
struct BufferConfig {
|
||||
uint32_t width = 0; //!< Specifies buffer width for buffer allocation.
|
||||
uint32_t height = 0; //!< Specifies buffer height for buffer allocation.
|
||||
LayerBufferFormat format = kFormatInvalid; //!< Specifies buffer format for buffer allocation.
|
||||
uint32_t buffer_count = 0; //!< Specifies number of buffers to be allocated.
|
||||
bool secure = false; //!< Specifies buffer to be allocated from
|
||||
//!< secure region.
|
||||
bool cache = false; //!< Specifies whether the buffer needs to be cache.
|
||||
bool secure_camera = false; //!< Specifies buffer to be allocated from specific
|
||||
//!< secure heap and with a specific alignment.
|
||||
bool gfx_client = false; //!< Specifies whether buffer is used by gfx.
|
||||
};
|
||||
|
||||
/*! @brief Holds the information about the allocated buffer.
|
||||
|
||||
@sa BufferAllocator::AllocateBuffer
|
||||
@sa BufferAllocator::FreeBuffer
|
||||
@sa BufferAllocator::GetAllocatedBufferInfo
|
||||
*/
|
||||
struct AllocatedBufferInfo {
|
||||
int fd = -1; //!< Specifies the fd of the allocated buffer.
|
||||
uint32_t stride = 0; //!< Specifies allocated buffer stride in bytes.
|
||||
uint32_t aligned_width = 0; //!< Specifies aligned allocated buffer width in pixels.
|
||||
uint32_t aligned_height = 0; //!< Specifies aligned allocated buffer height in pixels.
|
||||
LayerBufferFormat format = kFormatInvalid; // Specifies buffer format for allocated buffer.
|
||||
uint32_t size = 0; //!< Specifies the size of the allocated buffer.
|
||||
};
|
||||
|
||||
/*! @brief Holds the information about the input/output configuration of an output buffer.
|
||||
|
||||
@sa BufferAllocator::AllocateBuffer
|
||||
@sa BufferAllocator::FreeBuffer
|
||||
*/
|
||||
struct BufferInfo {
|
||||
BufferConfig buffer_config; //!< Specifies configuration of a buffer to be allocated.
|
||||
AllocatedBufferInfo alloc_buffer_info; //!< Specifies buffer information of allocated buffer.
|
||||
|
||||
void *private_data = NULL; //!< Pointer to private data.
|
||||
};
|
||||
|
||||
/*! @brief Buffer allocator implemented by the client
|
||||
|
||||
@details This class declares prototype for BufferAllocator methods which must be
|
||||
implemented by the client. Buffer manager in display manager will use these methods to
|
||||
allocate/deallocate buffers for display manager.
|
||||
|
||||
@sa CoreInterface::CreateCore
|
||||
*/
|
||||
class BufferAllocator {
|
||||
public:
|
||||
/*! @brief Method to allocate ouput buffer for the given input configuration.
|
||||
|
||||
@details This method allocates memory based on input configuration.
|
||||
|
||||
@param[in] buffer_info \link BufferInfo \endlink
|
||||
|
||||
@return \link DisplayError \endlink
|
||||
*/
|
||||
virtual DisplayError AllocateBuffer(BufferInfo *buffer_info) = 0;
|
||||
|
||||
|
||||
/*! @brief Method to deallocate the ouput buffer.
|
||||
|
||||
@details This method deallocates the memory allocated using AllocateBuffer method.
|
||||
|
||||
@param[in] buffer_info \link BufferInfo \endlink
|
||||
|
||||
@return \link DisplayError \endlink
|
||||
*/
|
||||
virtual DisplayError FreeBuffer(BufferInfo *buffer_info) = 0;
|
||||
|
||||
|
||||
/*! @brief Method to get the buffer size.
|
||||
|
||||
@details This method returns buffer size for a specific configuration mentioned in buffer info.
|
||||
|
||||
@param[in] buffer_info \link BufferInfo \endlink
|
||||
|
||||
@return \link unsigned int \endlink
|
||||
*/
|
||||
virtual uint32_t GetBufferSize(BufferInfo *buffer_info) = 0;
|
||||
|
||||
/*! @brief Method to Get the AllocatedBufferInfo only.
|
||||
|
||||
@details This method populates the AllocatedBufferInfo as per the configuration in BufferInfo,
|
||||
but fd will be invalid.
|
||||
|
||||
@param[in] buffer_info \link BufferInfo \endlink
|
||||
|
||||
@param[out] allocated_buffer_info \link AllocatedBufferInfo \endlink
|
||||
|
||||
@return \link DisplayError \endlink
|
||||
*/
|
||||
virtual DisplayError GetAllocatedBufferInfo(const BufferConfig &buffer_config,
|
||||
AllocatedBufferInfo *allocated_buffer_info) = 0;
|
||||
|
||||
/*
|
||||
* Retuns a buffer's layout in terms of number of planes, stride and offset of each plane
|
||||
* Input: AllocatedBufferInfo with a valid aligned width, aligned height, SDM format
|
||||
* Output: stride for each plane, offset of each plane from base, number of planes
|
||||
*/
|
||||
virtual DisplayError GetBufferLayout(const AllocatedBufferInfo &buf_info,
|
||||
uint32_t stride[4], uint32_t offset[4],
|
||||
uint32_t *num_planes) { return kErrorNotSupported; }
|
||||
|
||||
protected:
|
||||
virtual ~BufferAllocator() { }
|
||||
};
|
||||
|
||||
} // namespace sdm
|
||||
|
||||
#endif // __BUFFER_ALLOCATOR_H__
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user