commonsys-intf: display: Add display folders

Add libdisplayconfig and libqdmetadata to support
Single system image

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

View File

@@ -1,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",
]

View File

@@ -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

View File

@@ -1,5 +0,0 @@
# Makefile.am - Automake script for sdm
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = libqservice libqdutils sdm/libs/utils sdm/libs/core

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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));
}

View File

@@ -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__

View File

@@ -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;
}

View File

@@ -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__

View File

@@ -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;
}

View File

@@ -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__

View File

@@ -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;
}

View File

@@ -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__

View File

@@ -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__

View File

@@ -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";

View File

@@ -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";

View File

@@ -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;
}

View File

@@ -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__

View File

@@ -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";

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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)

View File

@@ -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));
}
};

View File

@@ -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;
};
};

View File

@@ -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,
}
};

View File

@@ -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 */

View File

@@ -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)

View File

@@ -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:
@@ -35,6 +35,7 @@ extern "C" {
typedef enum ColorRange {
Range_Limited = 0,
Range_Full = 1,
Range_Extended = 2,
Range_Max = 0xff,
} ColorRange;

View File

@@ -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__

View File

@@ -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)

View File

@@ -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

View File

@@ -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_ */

View File

@@ -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: &copybit_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;
}

View File

@@ -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

View File

@@ -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;
};

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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)

View File

@@ -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

View File

@@ -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__

View File

@@ -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)

View File

@@ -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__

View File

@@ -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

View File

@@ -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__

View File

@@ -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__

View File

@@ -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

View File

@@ -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__

View File

@@ -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

View File

@@ -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__

View File

@@ -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)

View File

@@ -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

View File

@@ -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,
};

View File

@@ -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)

View File

@@ -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;
}

View File

@@ -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,
};

View File

@@ -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
View 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
View 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

View File

@@ -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"],
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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",
],
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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_

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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");
}
}
}

View File

@@ -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

View File

@@ -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 */

View File

@@ -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