replace common qcom sources with samsung ones

This commit is contained in:
SaschaNes
2025-08-12 22:13:00 +02:00
parent ba24dcded9
commit 6f7753de11
5682 changed files with 2450203 additions and 103634 deletions

View File

@@ -0,0 +1,5 @@
# Makefile.am - Automake script for sdm
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = libformatutils/src liballocator/src libsdmcomposer/src

View File

@@ -0,0 +1,3 @@
vendor.display.enable_demura=0
vendor.display.enable_spr=0
vendor.display.enable_rounded_corner=1

View File

@@ -0,0 +1,49 @@
# -*- 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 ])
AC_SUBST([AM_CPPFLAGS], [--std=c++14])
AC_ARG_WITH(sanitized-headers,
AS_HELP_STRING([--with-sanitized-headers=DIR],
[Specify the location of the sanitized Linux headers]),
[CPPFLAGS="$CPPFLAGS -I$withval"])
PKG_CHECK_MODULES([LIBDMABUFHEAP], [libdmabufheap])
AC_SUBST([LIBDMABUFHEAP_CFLAGS])
AC_SUBST([LIBDMABUFHEAP_LIBS])
# 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 \
libformatutils/src/Makefile \
liballocator/src/Makefile \
libsdmcomposer/src/Makefile
])
AC_OUTPUT

View File

@@ -0,0 +1,155 @@
/*
* Copyright (c) 2020, 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.
*/
/*
* Changes from Qualcomm Innovation Center, Inc. are provided under the following license:
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#ifndef __ALLOC_INTERFACE_H__
#define __ALLOC_INTERFACE_H__
#include "buffer_interface.h"
namespace sdm {
enum CacheOp {
kCacheReadStart = 0x1, //!< Invalidate the cache before the buffer read
kCacheReadDone, //!< Flush the cache after the buffer read
kCacheWriteStart, //!< Invalidate the cache before the buffer write
kCacheWriteDone, //!< Flush the cache after the buffer write
kCacheInvalidate, //!< Invalidate the cache before the buffer read/write
kCacheClean, //!< Flush the cache after the buffer read/write
};
struct AllocData {
bool uncached = false; //!< Specifies the buffer to be cached or uncached
uint32_t width; //!< Width of the buffer to be allocated.
uint32_t height; //!< Height of the buffer to be allocated.
BufferFormat format; //!< Format of the buffer to be allocated.
uint32_t size; //!< Size of the buffer to be allocated. Allocator allocates the
//!< buffer of this size, if size is non zero otherwise allocator
//!< allocates the buffer based on width, height and format.
struct UsageHints {
union {
struct {
uint32_t trusted_ui : 1; //!< Denotes buffer to be allocated from trusted ui heap.
uint32_t tui_demura : 2; //!< Denotes buffer to be allocated from trusted ui demura heap.
};
uint64_t hints;
};
};
UsageHints usage_hints; //!< Hints to know about the producer of the buffer
};
struct CloneData {
int fd = -1; //!< Buffer fd to be cloned.
uint32_t width; //!< Width of the buffer to be cloned.
uint32_t height; //!< Height of the buffer to be cloned.
BufferFormat format; //!< Format of the buffer to be cloned.
};
class AllocInterface {
public:
/*! @brief Method to get the instance of allocator interface.
@details This function opens the ion device and provides the ion allocator interface
@return Returns AllocInterface pointer on sucess otherwise NULL
*/
static AllocInterface *GetInstance();
/*! @brief Method to to allocate buffer for a given buffer attributes
@param[in] data - \link AllocData \endlink
@param[out] buffer_handle - \link BufferHandle \endlink
@return Returns 0 on sucess otherwise errno
*/
virtual int AllocBuffer(AllocData *data, BufferHandle *buffer_handle) = 0;
/*! @brief Method to deallocate buffer
@param[in] buffer_handle - \link BufferHandle \endlink
@return Returns 0 on sucess otherwise errno
*/
virtual int FreeBuffer(BufferHandle *buffer_handle) = 0;
/*! @brief This creates a new mapping in the virtual address space of the calling process and
provides the pointer.
@param[in] fd - fd of the buffer to be mapped
@param[in] size - size of the buffer to be mapped
@param[out] base - virtual base address after mapping
@return Returns 0 on sucess otherwise errno
*/
virtual int MapBuffer(int fd, unsigned int size, void **base) = 0;
/*! @brief This function unmaps the buffer for the given pointer.
@param[in] base - virtual base address to be unmapped
@param[in] size - size of the buffer to be unmapped
@return Returns 0 on sucess otherwise errno
*/
virtual int UnmapBuffer(void *base, unsigned int size) = 0;
/*! @brief This function helps to invalidate and flush the cache for the read write operation.
@param[in] CacheOp - \link CacheOp \endlink
@param[in] fd - fd of the buffer to be mapped
@return Returns 0 on sucess otherwise errno
*/
virtual int SyncBuffer(CacheOp op, int fd) = 0;
/*! @brief This function helps to clone the buffer handle for the given buffer parameters
@param[in] clone_data - \link CloneData \endlink
@param[out] buffer_handle - \link BufferHandle \endlink
@return Returns 0 on sucess otherwise errno
*/
virtual int CloneBuffer(const CloneData &clone_data, BufferHandle *buffer_handle) = 0;
protected:
virtual ~AllocInterface() { }
};
} // namespace sdm
#endif // __ALLOC_INTERFACE_H__

View File

@@ -0,0 +1,122 @@
/*
* Copyright (c) 2020-2021, 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.
*/
/*
* Changes from Qualcomm Innovation Center are provided under the following license:
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#ifndef __BUFFER_INTERFACE_H__
#define __BUFFER_INTERFACE_H__
namespace sdm {
typedef void * Handle;
enum BufferFormat {
/* All RGB formats, Any new format will be added towards end of this group to maintain backward
compatibility.
*/
kBufferFormatInvalid = -1, //!< Invalid buffer format
kBufferFormatARGB8888, //!< 8-bits Alpha, Red, Green, Blue interleaved in ARGB order.
kBufferFormatRGBA8888, //!< 8-bits Red, Green, Blue, Alpha interleaved in RGBA order.
kBufferFormatBGRA8888, //!< 8-bits Blue, Green, Red, Alpha interleaved in BGRA order.
kBufferFormatXRGB8888, //!< 8-bits Padding, Red, Green, Blue interleaved in XRGB order.
//!< NoAlpha.
kBufferFormatRGBX8888, //!< 8-bits Red, Green, Blue, Padding interleaved in RGBX order.
//!< NoAlpha.
kBufferFormatBGRX8888, //!< 8-bits Blue, Green, Red, Padding interleaved in BGRX order.
//!< NoAlpha.
kBufferFormatRGBA5551, //!< 5-bits Red, Green, Blue, and 1 bit Alpha interleaved in
//!< RGBA order.
kBufferFormatRGBA4444, //!< 4-bits Red, Green, Blue, Alpha interleaved in RGBA order.
kBufferFormatRGB888, //!< 8-bits Red, Green, Blue interleaved in RGB order. No Alpha.
kBufferFormatBGR888, //!< 8-bits Blue, Green, Red interleaved in BGR order. No Alpha.
kBufferFormatRGB565, //!< 5-bit Red, 6-bit Green, 5-bit Blue interleaved in RGB order.
//!< NoAlpha.
kBufferFormatBGR565, //!< 5-bit Blue, 6-bit Green, 5-bit Red interleaved in BGR order.
//!< NoAlpha.
kBufferFormatRGBA1010102, //!< 10-bits Red, Green, Blue, Alpha interleaved in RGBA order.
kBufferFormatARGB2101010, //!< 10-bits Alpha, Red, Green, Blue interleaved in ARGB order.
kBufferFormatRGBX1010102, //!< 10-bits Red, Green, Blue, Padding interleaved in RGBX order.
//!< NoAlpha.
kBufferFormatXRGB2101010, //!< 10-bits Padding, Red, Green, Blue interleaved in XRGB order.
//!< NoAlpha.
kBufferFormatBGRA1010102, //!< 10-bits Blue, Green, Red, Alpha interleaved in BGRA order.
kBufferFormatABGR2101010, //!< 10-bits Alpha, Blue, Green, Red interleaved in ABGR order.
kBufferFormatBGRX1010102, //!< 10-bits Blue, Green, Red, Padding interleaved in BGRX order.
//!< NoAlpha.
kBufferFormatXBGR2101010, //!< 10-bits Padding, Blue, Green, Red interleaved in XBGR order.
//!< NoAlpha.
kBufferFormatRGB101010, //!< 10-bits Red, Green, Blue, interleaved in RGB order. No Alpha.
kBufferFormatRGBA8888Ubwc, //!< UBWC aligned RGBA8888 format
kBufferFormatRGBX8888Ubwc, //!< UBWC aligned RGBX8888 format
kBufferFormatBGR565Ubwc, //!< UBWC aligned BGR565 format
kBufferFormatRGBA1010102Ubwc, //!< UBWC aligned RGBA1010102 format
kBufferFormatRGBX1010102Ubwc, //!< UBWC aligned RGBX1010102 format
};
struct Rect {
float left = 0.0f; //!< Specifies the left coordinates of the pixel buffer
float top = 0.0f; //!< Specifies the top coordinates of the pixel buffer
float right = 0.0f; //!< Specifies the right coordinates of the pixel buffer
float bottom = 0.0f; //!< Specifies the bottom coordinates of the pixel buffer
bool operator==(const Rect& rect) const {
return left == rect.left && right == rect.right && top == rect.top && bottom == rect.bottom;
}
bool operator!=(const Rect& rect) const {
return !operator==(rect);
}
};
struct BufferHandle {
int32_t fd = -1; //!< fd of the allocated buffer to be displayed.
int32_t producer_fence_fd = -1; //!< Created and signaled by the producer. Consumer
//!< needs to wait on this before the buffer
//!< is being accessed
int32_t consumer_fence_fd = -1; //!< Created and signaled by the consumer. Producer
//!< needs to wait on this before the buffer
//!< is being modified
uint32_t width = 0; //!< Actual width of the buffer in pixels
uint32_t height = 0; //!< Actual height of the buffer in pixels.
uint32_t aligned_width = 0; //!< Aligned width of the buffer in pixels
uint32_t aligned_height = 0; //!< Aligned height of the buffer in pixels
BufferFormat format = kBufferFormatInvalid; //!< Format of the buffer refer BufferFormat
uint32_t stride_in_bytes = 0; //!< Stride of the buffer in bytes
uint32_t size = 0; //!< Allocated buffer size
bool uncached = false; //!< Enable or disable buffer caching during R/W
int64_t buffer_id = -1; //!< Unique Id of the allocated buffer for the
//!< internal use only
Rect src_crop = {}; //!< Crop rectangle of src buffer, if client doesn't
//!< specify, its default to {0, 0, width, height}
};
} // namespace sdm
#endif // __BUFFER_INTERFACE_H__

View File

@@ -0,0 +1,86 @@
/*
Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted (subject to the limitations in the
disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 __PROPERTY_PARSER_INTERFACE__
#define __PROPERTY_PARSER_INTERFACE__
class PropertyParserInterface {
public:
/*! @brief Method to create property parser interface.
@details This function to be called once per the device life cycle. This function creates
property parser interface which parses the property and its value from
vendor_build.prop property file. Property and value should be stored in following
format "property_name=value" to parse the file appropriately.
@param[out] intf - Populates property parser interface pointer.
@return Returns 0 on sucess otherwise errno
*/
static int Create(PropertyParserInterface **intf);
/*! @brief Method to destroy property parser interface.
@details This function to be called once per the device life cycle.
@param[in] intf - Property parser interface pointer which was populated by Create() function.
@return Returns 0 on sucess otherwise errno
*/
static int Destroy(PropertyParserInterface *intf);
/*! @brief Method to get the value of the property as integer.
@param[in] property_name - property name for which you want to retrieve the value.
@param[out] value - Integer pointer stores the value of the property.
@return Returns 0 on sucess otherwise errno
*/
virtual int GetProperty(const char *property_name, int *value) = 0;
/*! @brief Method to get the value of the property as char string.
@param[in] property_name - property name for which you want to retrieve the value.
@param[out] value - char pointer stores the value of the property.
@return Returns 0 on sucess otherwise errno
*/
virtual int GetProperty(const char *property_name, char *value) = 0;
protected:
virtual ~PropertyParserInterface() { }
};
#endif // __PROPERTY_PARSER_INTERFACE__

View File

@@ -0,0 +1,284 @@
/*
* Copyright (c) 2020, 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 __SDM_COMP_INTERFACE_H__
#define __SDM_COMP_INTERFACE_H__
#include "buffer_interface.h"
namespace sdm {
typedef void * Handle;
enum SDMCompDisplayType {
kSDMCompDisplayTypePrimary, // Defines the display type for primary display
kSDMCompDisplayTypeSecondary1, // Defines the display type for secondary builtin display
kSDMCompDisplayTypeMax,
};
// The following values matches the HEVC spec
typedef enum ColorPrimaries {
// Unused = 0;
ColorPrimaries_BT709_5 = 1, // ITU-R BT.709-5 or equivalent
/* Unspecified = 2, Reserved = 3*/
ColorPrimaries_BT470_6M = 4, // ITU-R BT.470-6 System M or equivalent
ColorPrimaries_BT601_6_625 = 5, // ITU-R BT.601-6 625 or equivalent
ColorPrimaries_BT601_6_525 = 6, // ITU-R BT.601-6 525 or equivalent
ColorPrimaries_SMPTE_240M = 7, // SMPTE_240M
ColorPrimaries_GenericFilm = 8, // Generic Film
ColorPrimaries_BT2020 = 9, // ITU-R BT.2020 or equivalent
ColorPrimaries_SMPTE_ST428 = 10, // SMPTE_240M
ColorPrimaries_AdobeRGB = 11,
ColorPrimaries_DCIP3 = 12,
ColorPrimaries_EBU3213 = 22,
ColorPrimaries_Max = 0xff,
} ColorPrimaries;
typedef enum GammaTransfer {
// Unused = 0;
Transfer_sRGB = 1, // ITR-BT.709-5
/* Unspecified = 2, Reserved = 3 */
Transfer_Gamma2_2 = 4,
Transfer_Gamma2_8 = 5,
Transfer_SMPTE_170M = 6, // BT.601-6 525 or 625
Transfer_SMPTE_240M = 7, // SMPTE_240M
Transfer_Linear = 8,
Transfer_Log = 9,
Transfer_Log_Sqrt = 10,
Transfer_XvYCC = 11, // IEC 61966-2-4
Transfer_BT1361 = 12, // Rec.ITU-R BT.1361 extended gamut
Transfer_sYCC = 13, // IEC 61966-2-1 sRGB or sYCC
Transfer_BT2020_2_1 = 14, // Rec. ITU-R BT.2020-2 (same as the values 1, 6, and 15)
Transfer_BT2020_2_2 = 15, // Rec. ITU-R BT.2020-2 (same as the values 1, 6, and 14)
Transfer_SMPTE_ST2084 = 16, // 2084
Transfer_ST_428 = 17, // SMPTE ST 428-1
Transfer_HLG = 18, // ARIB STD-B67
Transfer_Max = 0xff,
} GammaTransfer;
enum RenderIntent {
//<! Colors with vendor defined gamut
kRenderIntentNative,
//<! Colors with in gamut are left untouched, out side the gamut are hard clipped
kRenderIntentColorimetric,
//<! Colors with in gamut are ehanced, out side the gamuat are hard clipped
kRenderIntentEnhance,
//<! Tone map hdr colors to display's dynamic range, mapping to display gamut is
//<! defined in colormertic.
kRenderIntentToneMapColorimetric,
//<! Tone map hdr colors to display's dynamic range, mapping to display gamut is
//<! defined in enhance.
kRenderIntentToneMapEnhance,
//<! Custom render intents range
kRenderIntentOemCustomStart = 0x100,
kRenderIntentOemCustomEnd = 0x1ff,
//<! If STC implementation returns kOemModulateHw render intent, STC manager will
//<! call the implementation for all the render intent/blend space combination.
//<! STC implementation can modify/modulate the HW assets.
kRenderIntentOemModulateHw = 0xffff - 1,
kRenderIntentMaxRenderIntent = 0xffff
};
struct SDMCompDisplayAttributes {
uint32_t vsync_period = 0; //!< VSync period in nanoseconds.
uint32_t x_res = 0; //!< Total number of pixels in X-direction on the display panel.
uint32_t y_res = 0; //!< Total number of pixels in Y-direction on the display panel.
float x_dpi = 0.0f; //!< Dots per inch in X-direction.
float y_dpi = 0.0f; //!< Dots per inch in Y-direction.
bool is_yuv = false; //!< If the display output is in YUV format.
uint32_t fps = 0; //!< fps of the display.
bool smart_panel = false; //!< Speficies the panel is video mode or command mode
};
struct SDMCompMixerConfig {
uint32_t width = 0;
uint32_t height = 0;
};
struct ColorMode {
//<! Blend-Space gamut
ColorPrimaries gamut = ColorPrimaries_Max;
//<! Blend-space Gamma
GammaTransfer gamma = Transfer_Max;
//<! Intent of the mode
RenderIntent intent = kRenderIntentMaxRenderIntent ;
};
class CallbackInterface {
public:
/*! @brief Callback method to handle any asyn error.
@details This function need to be implemented by the client which will be called
by the sdm composer on any hardware hang etc.
*/
virtual void OnError() = 0;
protected:
virtual ~CallbackInterface() { }
// callbackdata where client can store the context information about display type
// for which this callback corresponds to.
Handle callback_data_ = nullptr;
};
class SDMCompInterface {
public:
/*! @brief Method to create display composer interface for TUI service.
@details This function to be called once per the device life cycle. This function creates
sdm core and opens up the display driver drm interface.
@param[out] intf - Populates composer interface pointer.
@return Returns 0 on sucess otherwise errno
*/
static int Create(SDMCompInterface **intf);
/*! @brief Method to destroy display composer interface for TUI service.
@details This function to be called once per the device life cycle. This function destroys
sdm core and closes the display driver drm interface.
@param[in] intf - Composer interface pointer which was populated by Create() function.
@return Returns 0 on sucess otherwise errno
*/
static int Destroy(SDMCompInterface *intf);
/*! @brief Method to create display for composer where the TUI to be rendered.
@details This function to be called on start of TUI session. This function creates primary or
secondary display based on the display type passed by the client and intialize the
display.to its appropriate state This function to be called once per display. This is
also responsible to create single layer to the created display
@param[in] display_type - Specifies the type of a display. \link SDMCompDisplayType \endlink
@param[in] callback - Pointer to callback interface which handles the async error.
\link CallbackInterface \endlink
@param[out] disp_hnd - pointer to display handle which stores the context of the client.
@return Returns 0 on sucess otherwise errno
*/
virtual int CreateDisplay(SDMCompDisplayType display_type, CallbackInterface *callback,
Handle *disp_hnd) = 0;
/*! @brief Method to destroy display for composer where the TUI to be rendered.
@details This function to be called on end of TUI session. This function destroys primary or
secondary display based on the display type passed by the client and relinquish all the
MDP hw resources. This function to be called once per display.
@param[in] disp_hnd - pointer to display handle which was created during CreateDisplay()
@return Returns 0 on sucess otherwise errno
*/
virtual int DestroyDisplay(Handle disp_hnd) = 0;
/*! @brief Method to get display attributes for a given display handle.
@param[in] disp_hnd - pointer to display handle which was created during CreateDisplay()
@param[out] display_attributes - pointer to display attributes to b populated for a given
display handle. \link SDMCompDisplayAttributes \endlink.
@return Returns 0 on sucess otherwise errno
*/
virtual int GetDisplayAttributes(Handle disp_hnd,
SDMCompDisplayAttributes *display_attributes) = 0;
/*! @brief Method to prepare and render buffer to display
@param[in] disp_hnd - pointer to display handle which was created during CreateDisplay()
@param[in] buf_handle - pointer to buffer handle which specifies the attributes of a buffer
@param[out] retire_fence - pointer to retire fence which will be signaled once display hw
picks up the buf_handle for rendering.
@return Returns 0 on sucess otherwise errno
*/
virtual int ShowBuffer(Handle disp_hnd, BufferHandle *buf_handle, int32_t *retire_fence) = 0;
/*! @brief Method to set color mode with render intent
@param[in] disp_hnd - pointer to display handle which was created during CreateDisplay()
@param[in] mode - ColorMode struct which contains blend space and render intent info
@return Returns 0 on sucess otherwise errno
*/
virtual int SetColorModeWithRenderIntent(Handle disp_hnd, struct ColorMode mode) = 0;
/*! @brief Method to get all the supported color modesDprepare and render buffer to display
* ut
@param[in] disp_hnd - pointer to display handle which was created during CreateDisplay()
@param[out] out_num_modes - pointer to uint32_t which specifies the number of color modes
@param[out] out_modes - pointer to ColorMode struct which contains all color modes that
are parsed from xml files
@return Returns 0 on sucess otherwise errno
*/
virtual int GetColorModes(Handle disp_hnd, uint32_t *out_num_modes,
struct ColorMode *out_modes) = 0;
/*! @brief Method to set panel brightness
@detail This api enables client to set the panel brightness of a given display, If the set
brightness level is below the minimum panel brightness values set by the API
SetMinPanelBrightness(), then it ignores the request.
@param[in] disp_hnd - pointer to display handle which was created during CreateDisplay()
@param[in] brightness_level - brightness_level of the panel varies from 0.0f to 1.0f
@return Returns 0 on sucess otherwise errno
*/
virtual int SetPanelBrightness(Handle disp_hnd, float brightness_level) = 0;
/*! @brief Method to set minimum panel brightness level
@detail This api enables client to set minimum panel brightness threshold of a given display,
If the set brightness level is below the minimum panel brightness threshold, Reset the
panel brightness level to minimum panel brightness value
@param[in] disp_hnd - pointer to display handle which was created during CreateDisplay()
@param[in] min_brightness_level - min_brightness_level of the panel varies from 0.0f to 1.0f
@return Returns 0 on sucess otherwise errno
*/
virtual int SetMinPanelBrightness(Handle disp_hnd, float min_brightness_level) = 0;
protected:
virtual ~SDMCompInterface() { }
};
} // namespace sdm
#endif // __SDM_COMP_INTERFACE_H__

View File

@@ -0,0 +1,52 @@
/*
* Copyright (c) 2020, 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 __SDMCOMP_SERVICE_EXTN_INTF_H__
#define __SDMCOMP_SERVICE_EXTN_INTF_H__
#include "libqrtr.h"
#define EXTN_LIB_NAME "libsdmcompserviceextn.so"
#define CREATE_SDMCOMP_SERVICE_EXTN "CreateSDMCompServiceExtn"
#define DESTROY_SDMCOMP_SERVICE_EXTN "DestroySDMCompServiceExtn"
class SDMCompServiceExtnIntf;
typedef int (*CreateSDMCompExtnIntf)(int qrtr_fd, SDMCompServiceExtnIntf **intf);
typedef int (*DestroySDMCompExtnIntf)(SDMCompServiceExtnIntf *intf);
class SDMCompServiceExtnIntf {
public:
virtual void CommandHandler(const struct qrtr_packet &qrtr_pkt) = 0;
protected:
virtual ~SDMCompServiceExtnIntf() { }
};
#endif // __SDMCOMP_SERVICE_EXTN_INTF_H__

View File

@@ -0,0 +1,114 @@
/*
* Copyright (c) 2020-2021, 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.
*/
/*
Changes from Qualcomm Innovation Center are provided under the following license:
Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted (subject to the limitations in the
disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 __SDMCOMP_SERVICE_INTF_H__
#define __SDMCOMP_SERVICE_INTF_H__
#include <stdarg.h>
#include "libqrtr.h"
namespace sdm {
class SDMCompServiceIntf;
enum SDMCompServiceEvents {
kEventSetPanelBrightness,
kEventSetDisplayConfig,
kEventImportDemuraBuffers,
kEventMax,
};
struct SDMCompServiceDispConfigs {
uint32_t h_total = 0;
uint32_t v_total = 0;
uint32_t fps = 0;
bool smart_panel = false;
uint32_t mixer_width = 0;
uint32_t mixer_height = 0;
};
struct SDMCompServiceDemuraBufInfo {
int hfc_buf_fd = -1;
uint32_t hfc_buf_size = 0;
uint64_t panel_id = 0;
};
class SDMCompServiceCbIntf {
public:
virtual int OnEvent(SDMCompServiceEvents event_type, ...) = 0;
protected:
virtual ~SDMCompServiceCbIntf() { }
};
class SDMCompServiceIntf {
public:
static int Create(SDMCompServiceCbIntf *callback, SDMCompServiceIntf **intf);
static int Destroy(SDMCompServiceIntf *intf);
protected:
virtual ~SDMCompServiceIntf() { }
};
}
#endif // __SDMCOMP_SERVICE_INTF_H__

View File

@@ -0,0 +1,18 @@
SDM_PATH := ${WORKSPACE}/display/vendor/qcom/opensource/display-core/sdm
AM_CPPFLAGS += "-I$(SDM_PATH)/include"
AM_CPPFLAGS += "-I$(SDM_PATH)/../libdebug"
AM_CPPFLAGS += "-I$(SDM_PATH)/../include"
AM_CPPFLAGS += "-I${WORKSPACE}/display/vendor/qcom/opensource/commonsys-intf/display/include/"
c_sources = alloc_interface.cpp \
ion_alloc_impl.cpp \
dma_buf_alloc_impl.cpp
lib_LTLIBRARIES = liballocator.la
liballocator_la_CC = @CC@
liballocator_la_SOURCES = $(c_sources)
liballocator_la_CFLAGS = $(COMMON_CFLAGS)
liballocator_la_CPPFLAGS = $(AM_CPPFLAGS) -DLOG_TAG=\"ION_ALLOCATOR\" @LIBDMABUFHEAP_CFLAGS@ -std=c++17
liballocator_la_LIBADD = ../../libformatutils/src/libformatutils.la
liballocator_la_LDFLAGS = -shared -avoid-version @LIBDMABUFHEAP_LIBS@

View File

@@ -0,0 +1,49 @@
/*
* Copyright (c) 2020-2021, 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 <utils/debug.h>
#include <utils/utils.h>
#include "alloc_interface.h"
#include "ion_alloc_impl.h"
#include "dma_buf_alloc_impl.h"
#define __CLASS__ "AllocInterface"
namespace sdm {
AllocInterface *AllocInterface::GetInstance() {
AllocInterface *alloc_intf = sdm::DmaBufAllocator::GetInstance();
if (alloc_intf == NULL) {
alloc_intf = IonAllocator::GetInstance();
}
return alloc_intf;
}
} // namespace sdm

View File

@@ -0,0 +1,263 @@
/*
* Copyright (c) 2021, 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.
*/
/*
* Changes from Qualcomm Innovation Center, Inc. are provided under the following license:
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <string.h>
#include <linux/dma-buf.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <utils/constants.h>
#include <string>
#include "debug_handler.h"
#include "dma_buf_alloc_impl.h"
#include "formats.h"
#define SZ_4K 0x1000
#define DEBUG 0
#define __CLASS__ "DmaBufAllocator"
namespace sdm {
template <class Type>
inline Type ALIGN(Type x, Type align) {
return (x + align - 1) & ~(align - 1);
}
DmaBufAllocator* DmaBufAllocator::dma_buf_allocator_ = NULL;
BufferAllocator DmaBufAllocator::buffer_allocator_ = {};
int64_t DmaBufAllocator::id_ = -1;
DmaBufAllocator *DmaBufAllocator::GetInstance() {
if (!dma_buf_allocator_) {
dma_buf_allocator_ = new DmaBufAllocator();
}
return dma_buf_allocator_;
}
int DmaBufAllocator::AllocBuffer(AllocData *data, BufferHandle *buffer_handle) {
if (!data || !buffer_handle) {
DLOGE("Invalid parameter data %p buffer_handle %p", data, buffer_handle);
return -EINVAL;
}
DLOGD_IF(DEBUG, "AllocData WxHxF %dx%dx%d uncached %d usage_hints %x size %d", data->width,
data->height, data->format, data->uncached, data->usage_hints, data->size);
int fd = -1;
uint32_t flags = 0;
std::string heap_name = {};
uint32_t align = SZ_4K;
uint32_t aligned_w = 0;
uint32_t aligned_h = 0;
GetAlignedWidthAndHeight(data->width, data->height, &aligned_w, &aligned_h);
uint32_t size = data->size;
if (!size) {
size = GetBufferSize(data->width, data->height, data->format);
}
GetHeapInfo(data, &heap_name);
fd = buffer_allocator_.Alloc(heap_name, size, flags, align);
if (fd < 0) {
DLOGE("Dmabuf alloc failed buf_fd %d size %d align %d heap_name %x flags %x",
fd, size, align, heap_name.c_str(), flags);
return -ENOMEM;
}
buffer_handle->fd = fd;
buffer_handle->width = data->width;
buffer_handle->height = data->height;
buffer_handle->format = data->format;
buffer_handle->aligned_width = aligned_w;
buffer_handle->aligned_height = aligned_h;
buffer_handle->size = size;
buffer_handle->stride_in_bytes = aligned_w * GetBpp(data->format);
buffer_handle->uncached = data->uncached;
buffer_handle->buffer_id = id_++;
DLOGD_IF(DEBUG, "Allocated buffer Aligned WxHxF %dx%dx%d stride_in_bytes %d size:%u fd:%d",
buffer_handle->aligned_width, buffer_handle->aligned_height, buffer_handle->format,
buffer_handle->stride_in_bytes, buffer_handle->size, buffer_handle->fd);
return 0;
}
int DmaBufAllocator::FreeBuffer(BufferHandle *buffer_handle) {
if (!buffer_handle) {
return -EINVAL;
}
close(buffer_handle->fd);
return 0;
}
int DmaBufAllocator::SyncBuffer(CacheOp op, int dma_buf_fd) {
struct dma_buf_sync sync;
int err = 0;
switch (op) {
case kCacheReadStart:
sync.flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_READ;
break;
case kCacheReadDone:
sync.flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_READ;
break;
case kCacheWriteStart:
sync.flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_WRITE;
break;
case kCacheWriteDone:
sync.flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_WRITE;
break;
case kCacheInvalidate:
sync.flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_RW;
break;
case kCacheClean:
sync.flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_RW;
break;
default:
DLOGE("%s: Invalid operation %d", __FUNCTION__, op);
return -1;
}
if (ioctl(dma_buf_fd, INT(DMA_BUF_IOCTL_SYNC), &sync)) {
err = -errno;
DLOGE("%s: DMA_BUF_IOCTL_SYNC failed with error - %s", __FUNCTION__, strerror(errno));
return err;
}
return 0;
}
int DmaBufAllocator::MapBuffer(int fd, unsigned int size, void **base) {
if (!base || fd < 0 || !size) {
DLOGE("Invalid parameters base %p, fd %d, size %d", base, fd, size);
return -EINVAL;
}
int err = 0;
void *addr = 0;
addr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
*base = addr;
if (addr == MAP_FAILED) {
err = -errno;
DLOGE("Failed to map memory in the client: %s", strerror(errno));
} else {
DLOGD_IF(DEBUG, "Mapped buffer base:%p size:%u fd:%d", addr, size, fd);
}
return err;
}
int DmaBufAllocator::UnmapBuffer(void *base, unsigned int size) {
if (!base || !size) {
DLOGE("Invalid parameters base %p, size %d", base, size);
return -EINVAL;
}
DLOGD_IF(DEBUG, "Unmapping buffer base:%p size:%u", base, size);
int err = 0;
if (munmap(base, size)) {
err = -errno;
DLOGE("Failed to unmap memory at %p : %s", base, strerror(errno));
}
return err;
}
int DmaBufAllocator::CloneBuffer(const CloneData &data, BufferHandle *buffer_handle) {
if (!buffer_handle) {
DLOGE("Invalid parameter data %p buffer_handle %p", buffer_handle);
return -EINVAL;
}
DLOGD_IF(DEBUG, "CloneData WxHxF %dx%dx%d fd %d", data.width, data.height, data.format, data.fd);
int err = 0;
uint32_t aligned_w = 0;
uint32_t aligned_h = 0;
GetAlignedWidthAndHeight(data.width, data.height, &aligned_w, &aligned_h);
uint32_t size = GetBufferSize(data.width, data.height, data.format);
buffer_handle->fd = dup(data.fd);
buffer_handle->width = data.width;
buffer_handle->height = data.height;
buffer_handle->format = data.format;
buffer_handle->aligned_width = aligned_w;
buffer_handle->aligned_height = aligned_h;
buffer_handle->size = size;
buffer_handle->stride_in_bytes = aligned_w * GetBpp(data.format);
buffer_handle->buffer_id = id_++;
DLOGD_IF(DEBUG, "Cloned buffer Aligned WxHxF %dx%dx%d stride_in_bytes %d size:%u fd:%d",
buffer_handle->aligned_width, buffer_handle->aligned_height, buffer_handle->format,
buffer_handle->stride_in_bytes, buffer_handle->size, buffer_handle->fd);
return 0;
}
void DmaBufAllocator::GetHeapInfo(AllocData *data, std::string *heap_name) {
if (data->usage_hints.trusted_ui) {
*heap_name = "qcom,tui";
} else if (data->usage_hints.tui_demura) {
*heap_name = "qcom,tui_demura";
}
}
void DmaBufAllocator::GetAlignedWidthAndHeight(int width, int height, uint32_t *aligned_width,
uint32_t *aligned_height) {
if (!aligned_width || !aligned_height) {
return;
}
*aligned_width = ALIGN(width, 32);
*aligned_height = ALIGN(height, 32);
}
uint32_t DmaBufAllocator::GetBufferSize(int width, int height, BufferFormat format) {
uint32_t aligned_w = 0;
uint32_t aligned_h = 0;
GetAlignedWidthAndHeight(width, height, &aligned_w, &aligned_h);
return (aligned_w * aligned_h * GetBpp(format));
}
} // namespace sdm

View File

@@ -0,0 +1,65 @@
/*
* Copyright (c) 2021, 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 __DMA_BUF_ALLOC_IMPL_H__
#define __DMA_BUF_ALLOC_IMPL_H__
#include <BufferAllocator/BufferAllocator.h>
#include "alloc_interface.h"
namespace sdm {
class DmaBufAllocator : public AllocInterface {
public:
~DmaBufAllocator() { }
virtual int AllocBuffer(AllocData *data, BufferHandle *buffer_handle);
virtual int FreeBuffer(BufferHandle *buffer_handle);
virtual int MapBuffer(int fd, unsigned int size, void **base);
virtual int UnmapBuffer(void *base, unsigned int size);
virtual int SyncBuffer(CacheOp op, int fd);
virtual int CloneBuffer (const CloneData &data, BufferHandle *buffer_handle);
static DmaBufAllocator *GetInstance();
private:
DmaBufAllocator() {}
void GetHeapInfo(AllocData *data, std::string *heap_name);
void GetAlignedWidthAndHeight(int width, int height, uint32_t *aligned_width,
uint32_t *aligned_height);
uint32_t GetBufferSize(int width, int height, BufferFormat format);
static DmaBufAllocator* dma_buf_allocator_;
static BufferAllocator buffer_allocator_;
static int64_t id_;
};
} // namespace sdm
#endif // __DMA_BUF_ALLOC_IMPL_H__

View File

@@ -0,0 +1,293 @@
/*
* Copyright (c) 2020, 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 <sys/ioctl.h>
#include <sys/mman.h>
#include <string.h>
#include <linux/dma-buf.h>
#include <linux/msm_ion.h>
#include <linux/msm_ion_ids.h>
#include <ion/ion.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <utils/constants.h>
#include "debug_handler.h"
#include "ion_alloc_impl.h"
#include "formats.h"
#define SZ_2M 0x200000
#define SZ_4K 0x1000
#define DEBUG 0
#define __CLASS__ "IonAllocator"
namespace sdm {
template <class Type>
inline Type ALIGN(Type x, Type align) {
return (x + align - 1) & ~(align - 1);
}
IonAllocator* IonAllocator::ion_allocator_ = NULL;
int64_t IonAllocator::id_ = -1;
IonAllocator *IonAllocator::GetInstance() {
if (!ion_allocator_) {
ion_allocator_ = new IonAllocator();
int error = ion_allocator_->Init();
if (error != 0) {
DLOGE("Ion initialization failed");
return NULL;
}
}
return ion_allocator_;
}
int IonAllocator::Init() {
if (ion_dev_fd_ == -1) {
ion_dev_fd_ = ion_open();
}
if (ion_dev_fd_ < 0) {
DLOGE("%s: Failed to open ion device - %s", __FUNCTION__, strerror(errno));
ion_dev_fd_ = -1;
return -EINVAL;
}
return 0;
}
void IonAllocator::Deinit() {
if (ion_dev_fd_ > -1) {
ion_close(ion_dev_fd_);
}
ion_dev_fd_ = -1;
}
int IonAllocator::AllocBuffer(AllocData *data, BufferHandle *buffer_handle) {
if (!data || !buffer_handle) {
DLOGE("Invalid parameter data %p buffer_handle %p", data, buffer_handle);
return -EINVAL;
}
DLOGD_IF(DEBUG, "AllocData WxHxF %dx%dx%d uncached %d usage_hints %x size %d", data->width,
data->height, data->format, data->uncached, data->usage_hints, data->size);
int err = 0;
int fd = -1;
uint32_t flags = 0;
uint32_t heap_id = 0;
// TODO(user): Revisit here
uint32_t align = SZ_4K;
uint32_t aligned_w = 0;
uint32_t aligned_h = 0;
GetAlignedWidthAndHeight(data->width, data->height, &aligned_w, &aligned_h);
uint32_t size = data->size;
if (!size) {
size = GetBufferSize(data->width, data->height, data->format);
}
GetIonHeapInfo(data, &heap_id, &flags);
err = ion_alloc_fd(ion_dev_fd_, size, align, heap_id, flags, &fd);
if (err) {
DLOGE("Ion alloc failed ion_fd %d size %d align %d heap_id %x flags %x err %d",
ion_dev_fd_, size, align, heap_id, flags, err);
return err;
}
buffer_handle->fd = fd;
buffer_handle->width = data->width;
buffer_handle->height = data->height;
buffer_handle->format = data->format;
buffer_handle->aligned_width = aligned_w;
buffer_handle->aligned_height = aligned_h;
buffer_handle->size = size;
buffer_handle->stride_in_bytes = aligned_w * GetBpp(data->format);
buffer_handle->uncached = data->uncached;
buffer_handle->buffer_id = id_++;
DLOGD_IF(DEBUG, "Allocated buffer Aligned WxHxF %dx%dx%d stride_in_bytes %d size:%u fd:%d",
buffer_handle->aligned_width, buffer_handle->aligned_height, buffer_handle->format,
buffer_handle->stride_in_bytes, buffer_handle->size, buffer_handle->fd);
return 0;
}
int IonAllocator::FreeBuffer(BufferHandle *buffer_handle) {
if (!buffer_handle) {
return -EINVAL;
}
close(buffer_handle->fd);
return 0;
}
int IonAllocator::SyncBuffer(CacheOp op, int dma_buf_fd) {
struct dma_buf_sync sync;
int err = 0;
switch (op) {
case kCacheReadStart:
sync.flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_READ;
break;
case kCacheReadDone:
sync.flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_READ;
break;
case kCacheWriteStart:
sync.flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_WRITE;
break;
case kCacheWriteDone:
sync.flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_WRITE;
break;
case kCacheInvalidate:
sync.flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_RW;
break;
case kCacheClean:
sync.flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_RW;
break;
default:
DLOGE("%s: Invalid operation %d", __FUNCTION__, op);
return -1;
}
if (ioctl(dma_buf_fd, INT(DMA_BUF_IOCTL_SYNC), &sync)) {
err = -errno;
DLOGE("%s: DMA_BUF_IOCTL_SYNC failed with error - %s", __FUNCTION__, strerror(errno));
return err;
}
return 0;
}
int IonAllocator::MapBuffer(int fd, unsigned int size, void **base) {
if (!base || fd < 0 || !size) {
DLOGE("Invalid parameters base %p, fd %d, size %d", base, fd, size);
return -EINVAL;
}
int err = 0;
void *addr = 0;
addr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
*base = addr;
if (addr == MAP_FAILED) {
err = -errno;
DLOGE("ion: Failed to map memory in the client: %s", strerror(errno));
} else {
DLOGD_IF(DEBUG, "ion: Mapped buffer base:%p size:%u fd:%d", addr, size, fd);
}
return err;
}
int IonAllocator::UnmapBuffer(void *base, unsigned int size) {
if (!base || !size) {
DLOGE("Invalid parameters base %p, size %d", base, size);
return -EINVAL;
}
DLOGD_IF(DEBUG, "ion: Unmapping buffer base:%p size:%u", base, size);
int err = 0;
if (munmap(base, size)) {
err = -errno;
DLOGE("ion: Failed to unmap memory at %p : %s", base, strerror(errno));
}
return err;
}
int IonAllocator::CloneBuffer(const CloneData &data, BufferHandle *buffer_handle) {
if (!buffer_handle) {
DLOGE("Invalid parameter data %p buffer_handle %p", buffer_handle);
return -EINVAL;
}
DLOGD_IF(DEBUG, "CloneData WxHxF %dx%dx%d fd %d", data.width, data.height, data.format, data.fd);
int err = 0;
uint32_t aligned_w = 0;
uint32_t aligned_h = 0;
GetAlignedWidthAndHeight(data.width, data.height, &aligned_w, &aligned_h);
uint32_t size = GetBufferSize(data.width, data.height, data.format);
buffer_handle->fd = dup(data.fd);
buffer_handle->width = data.width;
buffer_handle->height = data.height;
buffer_handle->format = data.format;
buffer_handle->aligned_width = aligned_w;
buffer_handle->aligned_height = aligned_h;
buffer_handle->size = size;
buffer_handle->stride_in_bytes = aligned_w * GetBpp(data.format);
buffer_handle->buffer_id = id_++;
DLOGD_IF(DEBUG, "Cloned buffer Aligned WxHxF %dx%dx%d stride_in_bytes %d size:%u fd:%d",
buffer_handle->aligned_width, buffer_handle->aligned_height, buffer_handle->format,
buffer_handle->stride_in_bytes, buffer_handle->size, buffer_handle->fd);
return 0;
}
void IonAllocator::GetIonHeapInfo(AllocData *data, uint32_t *ion_heap_id,
uint32_t *ion_flags) {
uint32_t heap_id = ION_HEAP(ION_SYSTEM_HEAP_ID);
uint32_t flags = 0;
if (data->usage_hints.trusted_ui) {
heap_id = ION_HEAP(ION_TUI_CARVEOUT_HEAP_ID);
}
flags |= data->uncached ? 0 : ION_FLAG_CACHED;
*ion_flags = flags;
*ion_heap_id = heap_id;
}
void IonAllocator::GetAlignedWidthAndHeight(int width, int height, uint32_t *aligned_width,
uint32_t *aligned_height) {
if (!aligned_width || !aligned_height) {
return;
}
*aligned_width = ALIGN(width, 32);
*aligned_height = ALIGN(height, 32);
}
uint32_t IonAllocator::GetBufferSize(int width, int height, BufferFormat format) {
uint32_t aligned_w = 0;
uint32_t aligned_h = 0;
GetAlignedWidthAndHeight(width, height, &aligned_w, &aligned_h);
return (aligned_w * aligned_h * GetBpp(format));
}
} // namespace sdm

View File

@@ -0,0 +1,65 @@
/*
* Copyright (c) 2020, 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 __ION_ALLOC_IMPL_H__
#define __ION_ALLOC_IMPL_H__
#include "alloc_interface.h"
namespace sdm {
class IonAllocator : public AllocInterface {
public:
~IonAllocator() { Deinit(); }
virtual int AllocBuffer(AllocData *data, BufferHandle *buffer_handle);
virtual int FreeBuffer(BufferHandle *buffer_handle);
virtual int MapBuffer(int fd, unsigned int size, void **base);
virtual int UnmapBuffer(void *base, unsigned int size);
virtual int SyncBuffer(CacheOp op, int fd);
virtual int CloneBuffer (const CloneData &data, BufferHandle *buffer_handle);
static IonAllocator *GetInstance();
private:
IonAllocator() {}
int Init();
void Deinit();
void GetIonHeapInfo(AllocData *data, uint32_t *ion_heap_id, uint32_t *ion_flags);
void GetAlignedWidthAndHeight(int width, int height, uint32_t *aligned_width,
uint32_t *aligned_height);
uint32_t GetBufferSize(int width, int height, BufferFormat format);
int ion_dev_fd_ = -1;
static IonAllocator* ion_allocator_;
static int64_t id_;
};
} // namespace sdm
#endif // __ION_ALLOC_IMPL_H__

View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) 2020, 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 __FORMATS_H__
#define __FORMATS_H__
#include <core/layer_buffer.h>
#include "sdm_comp_interface.h"
namespace sdm {
float GetBpp(BufferFormat format);
LayerBufferFormat GetSDMFormat(BufferFormat buf_format);
BufferFormat GetSDMCompFormat(LayerBufferFormat sdm_format);
} // namespace sdm
#endif // __FORMATS_H__

View File

@@ -0,0 +1,14 @@
DISPLAY_CORE_PATH := ${WORKSPACE}/display/vendor/qcom/opensource/display-core
AM_CPPFLAGS += "-I$(DISPLAY_CORE_PATH)/sdm/include"
AM_CPPFLAGS += "-I$(DISPLAY_CORE_PATH)/include"
AM_CPPFLAGS += "-I${WORKSPACE}/display/vendor/qcom/opensource/commonsys-intf/display/include/"
c_sources = formats.cpp
lib_LTLIBRARIES = libformatutils.la
libformatutils_la_CC = @CC@
libformatutils_la_SOURCES = $(c_sources)
libformatutils_la_CFLAGS = $(COMMON_CFLAGS)
libformatutils_la_CPPFLAGS = $(AM_CPPFLAGS) -DLOG_TAG=\"FORMATUTILS\"
libformatutils_la_LDFLAGS = -shared -avoid-version

View File

@@ -0,0 +1,187 @@
/*
* Copyright (c) 2020, 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 "formats.h"
namespace sdm {
float GetBpp(BufferFormat format) {
float bpp = 0.0f;
switch (format) {
case kBufferFormatARGB8888:
case kBufferFormatRGBA8888:
case kBufferFormatBGRA8888:
case kBufferFormatXRGB8888:
case kBufferFormatRGBX8888:
case kBufferFormatBGRX8888:
case kBufferFormatRGBA1010102:
case kBufferFormatARGB2101010:
case kBufferFormatRGBX1010102:
case kBufferFormatXRGB2101010:
case kBufferFormatBGRA1010102:
case kBufferFormatABGR2101010:
case kBufferFormatBGRX1010102:
case kBufferFormatXBGR2101010:
case kBufferFormatRGBA8888Ubwc:
case kBufferFormatRGBX8888Ubwc:
case kBufferFormatRGBA1010102Ubwc:
case kBufferFormatRGBX1010102Ubwc:
return 4.0f;
case kBufferFormatRGB888:
case kBufferFormatBGR888:
return 3.0f;
case kBufferFormatRGB565:
case kBufferFormatBGR565:
case kBufferFormatRGBA5551:
case kBufferFormatRGBA4444:
case kBufferFormatBGR565Ubwc:
return 2.0f;
default:
return 0.0f;
}
return bpp;
}
LayerBufferFormat GetSDMFormat(BufferFormat buf_format) {
switch (buf_format) {
case kBufferFormatARGB8888:
return kFormatARGB8888;
case kBufferFormatRGBA8888:
return kFormatRGBA8888;
case kBufferFormatBGRA8888:
return kFormatBGRA8888;
case kBufferFormatXRGB8888:
return kFormatXRGB8888;
case kBufferFormatRGBX8888:
return kFormatRGBX8888;
case kBufferFormatBGRX8888:
return kFormatBGRX8888;
case kBufferFormatRGBA1010102:
return kFormatRGBA1010102;
case kBufferFormatARGB2101010:
return kFormatARGB2101010;
case kBufferFormatRGBX1010102:
return kFormatRGBX1010102;
case kBufferFormatXRGB2101010:
return kFormatXRGB2101010;
case kBufferFormatBGRA1010102:
return kFormatBGRA1010102;
case kBufferFormatABGR2101010:
return kFormatABGR2101010;
case kBufferFormatBGRX1010102:
return kFormatBGRX1010102;
case kBufferFormatXBGR2101010:
return kFormatXBGR2101010;
case kBufferFormatRGB888:
return kFormatRGB888;
case kBufferFormatBGR888:
return kFormatBGR888;
case kBufferFormatRGB565:
return kFormatRGB565;
case kBufferFormatBGR565:
return kFormatBGR565;
case kBufferFormatRGBA5551:
return kFormatRGBA5551;
case kBufferFormatRGBA4444:
return kFormatRGBA4444;
case kBufferFormatRGBA8888Ubwc:
return kFormatRGBA8888Ubwc;
case kBufferFormatRGBX8888Ubwc:
return kFormatRGBX8888Ubwc;
case kBufferFormatBGR565Ubwc:
return kFormatBGR565Ubwc;
case kBufferFormatRGBA1010102Ubwc:
return kFormatRGBA1010102Ubwc;
case kBufferFormatRGBX1010102Ubwc:
return kFormatRGBX1010102Ubwc;
default:
return kFormatInvalid;
}
}
BufferFormat GetSDMCompFormat(LayerBufferFormat sdm_format) {
switch (sdm_format) {
case kFormatARGB8888:
return kBufferFormatARGB8888;
case kFormatRGBA8888:
return kBufferFormatRGBA8888;
case kFormatBGRA8888:
return kBufferFormatBGRA8888;
case kFormatXRGB8888:
return kBufferFormatXRGB8888;
case kFormatRGBX8888:
return kBufferFormatRGBX8888;
case kFormatBGRX8888:
return kBufferFormatBGRX8888;
case kFormatRGBA1010102:
return kBufferFormatRGBA1010102;
case kFormatARGB2101010:
return kBufferFormatARGB2101010;
case kFormatRGBX1010102:
return kBufferFormatRGBX1010102;
case kFormatXRGB2101010:
return kBufferFormatXRGB2101010;
case kFormatBGRA1010102:
return kBufferFormatBGRA1010102;
case kFormatABGR2101010:
return kBufferFormatABGR2101010;
case kFormatBGRX1010102:
return kBufferFormatBGRX1010102;
case kFormatXBGR2101010:
return kBufferFormatXBGR2101010;
case kFormatRGB888:
return kBufferFormatRGB888;
case kFormatBGR888:
return kBufferFormatBGR888;
case kFormatRGB565:
return kBufferFormatRGB565;
case kFormatBGR565:
return kBufferFormatBGR565;
case kFormatRGBA5551:
return kBufferFormatRGBA5551;
case kFormatRGBA4444:
return kBufferFormatRGBA4444;
case kFormatRGBA8888Ubwc:
return kBufferFormatRGBA8888Ubwc;
case kFormatRGBX8888Ubwc:
return kBufferFormatRGBX8888Ubwc;
case kFormatBGR565Ubwc:
return kBufferFormatBGR565Ubwc;
case kFormatRGBA1010102Ubwc:
return kBufferFormatRGBA1010102Ubwc;
case kFormatRGBX1010102Ubwc:
return kBufferFormatRGBX1010102Ubwc;
default:
return kBufferFormatInvalid;
}
}
} // namespace sdm

View File

@@ -0,0 +1,33 @@
SDM_PATH := ${WORKSPACE}/display/vendor/qcom/opensource/display-core/sdm
SDM_COMP_PATH := ${WORKSPACE}/display/vendor/qcom/opensource/display/sdm-composer
AM_CPPFLAGS += "-I$(SDM_PATH)/include"
AM_CPPFLAGS += "-I$(SDM_PATH)/../libdebug"
AM_CPPFLAGS += "-I$(SDM_PATH)/../include"
AM_CPPFLAGS += "-I${WORKSPACE}/display/vendor/qcom/opensource/commonsys-intf/display/include/"
AM_CPPFLAGS += "-I$(SDM_PATH)/../libmemutils"
AM_CPPFLAGS += "-I${PKG_CONFIG_SYSROOT_DIR}/${includedir}/qmi-framework"
AM_CPPFLAGS += "-I$(SDM_COMP_PATH)/include"
c_sources = sdm_comp_buffer_allocator.cpp \
sdm_comp_buffer_sync_handler.cpp \
sdm_comp_debugger.cpp \
sdm_comp_display_builtin.cpp \
sdm_comp_impl.cpp \
sdm_comp_interface.cpp \
sdm_comp_service.cpp \
sdm_comp_service_intf.cpp \
sdm_comp_service_client.cpp \
property_parser_interface.cpp \
property_parser_impl.cpp
lib_LTLIBRARIES = libsdmcomposer.la
libsdmcomposer_la_CC = @CC@
libsdmcomposer_la_SOURCES = $(c_sources)
libsdmcomposer_la_CFLAGS = $(COMMON_CFLAGS)
libsdmcomposer_la_CPPFLAGS = $(AM_CPPFLAGS) -DLOG_TAG=\"SDM\"
libsdmcomposer_la_LIBADD := ../../libformatutils/src/libformatutils.la \
../../liballocator/src/liballocator.la
libsdmcomposer_la_LDFLAGS := -shared -avoid-version -lsdmcore -lsdmutils -lsdmdal -ldl \
-lpthread -lmemutils -lsystemdq

View File

@@ -0,0 +1,134 @@
/*
Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted (subject to the limitations in the
disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 <string.h>
#include <fstream>
#include "property_parser_impl.h"
#include "debug_handler.h"
#define __CLASS__ "PropertyParserImpl"
#define PERSIST_PROPERTY_FILE_PATH "/persist/display/vendor_display_build.prop"
#define PROPERTY_FILE_PATH "/usr/data/display/vendor_display_build.prop"
PropertyParserImpl *PropertyParserImpl::property_parser_impl_ = nullptr;
uint32_t PropertyParserImpl::ref_count_ = 0;
recursive_mutex PropertyParserImpl::recursive_mutex_;
PropertyParserImpl *PropertyParserImpl::GetInstance() {
if (!property_parser_impl_) {
property_parser_impl_= new PropertyParserImpl();
}
return property_parser_impl_;
}
int PropertyParserImpl::Init() {
lock_guard<recursive_mutex> obj(recursive_mutex_);
if (ref_count_) {
ref_count_++;
return 0;
}
bool prop_file_found = false;
std::fstream prop_file;
prop_file.open(PERSIST_PROPERTY_FILE_PATH, std::fstream::in);
if (prop_file.is_open()) {
prop_file_found = true;
DLOGI("found prop file %s", PERSIST_PROPERTY_FILE_PATH);
} else {
prop_file.open(PROPERTY_FILE_PATH, std::fstream::in);
if (prop_file.is_open()) {
DLOGI("found prop file %s", PROPERTY_FILE_PATH);
prop_file_found = true;
}
}
if (prop_file_found) {
std::string line = {};
while (std::getline(prop_file, line)) {
auto pos = line.find('=');
if (pos != std::string::npos) {
std::string prop_name = line.substr(0, pos);
std::string value = line.substr(pos + 1, std::string::npos);
DLOGI("%s=%s", prop_name.c_str(), value.c_str());
properties_map_.emplace(std::make_pair(prop_name, value));
}
}
}
ref_count_++;
return 0;
}
int PropertyParserImpl::Deinit() {
lock_guard<recursive_mutex> obj(recursive_mutex_);
if (ref_count_) {
ref_count_--;
if (!ref_count_) {
delete property_parser_impl_;
property_parser_impl_ = nullptr;
}
}
return 0;
}
int PropertyParserImpl::GetProperty(const char *property_name, int *value) {
lock_guard<recursive_mutex> obj(recursive_mutex_);
if (!property_name || !value)
return -EINVAL;
*value = 0;
auto it = properties_map_.find(property_name);
if (it != properties_map_.end())
*value = std::stoi(it->second);
else
return -ENOKEY;
return 0;
}
int PropertyParserImpl::GetProperty(const char *property_name, char *value) {
lock_guard<recursive_mutex> obj(recursive_mutex_);
if (!property_name || !value)
return -EINVAL;
auto it = properties_map_.find(property_name);
if (it != properties_map_.end())
std::snprintf(value, it->second.size(), "%s", it->second.c_str());
else
return -ENOKEY;
return 0;
}

View File

@@ -0,0 +1,70 @@
/*
Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted (subject to the limitations in the
disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 __PROPERTY_PARSER_IMPL_H__
#define __PROPERTY_PARSER_IMPL_H__
#include <errno.h>
#include <map>
#include <string>
#include <mutex>
#include "property_parser_interface.h"
using std::recursive_mutex;
using std::lock_guard;
class PropertyParserImpl : public PropertyParserInterface {
public:
static PropertyParserImpl *GetInstance();
virtual ~PropertyParserImpl() { }
int Init();
int Deinit();
virtual int GetProperty(const char *property_name, int *value);
virtual int GetProperty(const char *property_name, char *value);
private:
static PropertyParserImpl *property_parser_impl_;
static uint32_t ref_count_;
static recursive_mutex recursive_mutex_;
std::map<std::string, std::string> properties_map_ = {};
};
#endif // __PROPERTY_PARSER_IMPL_H__

View File

@@ -0,0 +1,77 @@
/*
Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted (subject to the limitations in the
disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 <utils/debug.h>
#include <utils/utils.h>
#include "property_parser_interface.h"
#include "property_parser_impl.h"
#define __CLASS__ "PropertyParserInterface"
int PropertyParserInterface::Create(PropertyParserInterface **intf) {
if (!intf) {
DLOGE("intf pointer is NULL");
return -EINVAL;
}
PropertyParserImpl *property_parser_impl = PropertyParserImpl::GetInstance();
if (!property_parser_impl) {
return -EINVAL;
}
int error = property_parser_impl->Init();
if (error != 0) {
DLOGE("Init failed with %d", error);
return error;
}
*intf = property_parser_impl;
return error;
}
int PropertyParserInterface::Destroy(PropertyParserInterface *intf) {
if (!intf) {
DLOGE("intf pointer is NULL");
return -EINVAL;
}
PropertyParserImpl *property_parser_impl = static_cast<PropertyParserImpl *>(intf);
int error = property_parser_impl->Deinit();
if (error != 0) {
DLOGE("Deinit failed with %d", error);
return error;
}
return 0;
}

View File

@@ -0,0 +1,184 @@
/*
* Copyright (c) 2020, 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.
*/
/*
* Changes from Qualcomm Innovation Center, Inc. are provided under the following license:
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#include <core/buffer_allocator.h>
#include <utils/constants.h>
#include <utils/debug.h>
#include "sdm_comp_buffer_allocator.h"
#include "sdm_comp_debugger.h"
#include "formats.h"
#include "alloc_interface.h"
#define __CLASS__ "SDMCompBufferAllocator"
namespace sdm {
int SDMCompBufferAllocator::AllocateBuffer(BufferInfo *buffer_info) {
AllocInterface *alloc_intf = AllocInterface::GetInstance();
if (!alloc_intf) {
return -ENOMEM;
}
const BufferConfig &buffer_config = buffer_info->buffer_config;
AllocatedBufferInfo *alloc_buffer_info = &buffer_info->alloc_buffer_info;
BufferHandle *buffer_handle = new BufferHandle();
AllocData data = {};
data.width = buffer_config.width;
data.height = buffer_config.height;
data.format = GetSDMCompFormat(buffer_config.format);
data.uncached = true;
data.usage_hints.trusted_ui = true;
if (buffer_config.tui_demura) {
data.usage_hints.trusted_ui = false;
data.usage_hints.tui_demura = true;
}
int error = alloc_intf->AllocBuffer(&data, buffer_handle);
if (error != 0) {
DLOGE("Allocation failed WxHxF %dx%dx%d, uncached %d", data.width, data.height, data.format,
data.uncached);
delete buffer_handle;
return -ENOMEM;
}
alloc_buffer_info->fd = buffer_handle->fd;
alloc_buffer_info->stride = buffer_handle->stride_in_bytes;
alloc_buffer_info->aligned_width = buffer_handle->aligned_width;
alloc_buffer_info->aligned_height = buffer_handle->aligned_height;
alloc_buffer_info->format = buffer_config.format;
alloc_buffer_info->size = buffer_handle->size;
alloc_buffer_info->id = buffer_handle->buffer_id;
buffer_info->private_data = buffer_handle;
return 0;
}
int SDMCompBufferAllocator::FreeBuffer(BufferInfo *buffer_info) {
AllocInterface *alloc_intf = AllocInterface::GetInstance();
if (!alloc_intf) {
return -ENOMEM;
}
AllocatedBufferInfo &alloc_buffer_info = buffer_info->alloc_buffer_info;
BufferHandle *buffer_handle = reinterpret_cast<BufferHandle *>(buffer_info->private_data);
alloc_intf->FreeBuffer(buffer_handle);
delete buffer_handle;
alloc_buffer_info.fd = -1;
alloc_buffer_info.stride = 0;
alloc_buffer_info.size = 0;
buffer_info->private_data = NULL;
return 0;
}
uint32_t SDMCompBufferAllocator::GetBufferSize(BufferInfo *buffer_info) {
const BufferConfig &buffer_config = buffer_info->buffer_config;
uint32_t aligned_w = 0;
uint32_t aligned_h = 0;
BufferFormat buf_format = GetSDMCompFormat(buffer_config.format);
GetAlignedWidthAndHeight(buffer_config.width, buffer_config.height, &aligned_w, &aligned_h);
return (aligned_w * aligned_h * GetBpp(buf_format));
}
int SDMCompBufferAllocator::GetAllocatedBufferInfo(
const BufferConfig &buffer_config, AllocatedBufferInfo *allocated_buffer_info) {
uint32_t aligned_w = 0;
uint32_t aligned_h = 0;
BufferFormat buf_format = GetSDMCompFormat(buffer_config.format);
GetAlignedWidthAndHeight(buffer_config.width, buffer_config.height, &aligned_w, &aligned_h);
allocated_buffer_info->stride = aligned_w * GetBpp(buf_format);
allocated_buffer_info->aligned_width = aligned_w;
allocated_buffer_info->aligned_height = aligned_h;
allocated_buffer_info->size = (aligned_w * aligned_h * GetBpp(buf_format));
return 0;
}
int SDMCompBufferAllocator::GetBufferLayout(const AllocatedBufferInfo &buf_info, uint32_t stride[4],
uint32_t offset[4], uint32_t *num_planes) {
if (!num_planes) {
return -EINVAL;
}
BufferFormat buf_format = GetSDMCompFormat(buf_info.format);
*num_planes = 1;
stride[0] = static_cast<uint32_t>(buf_info.aligned_width * GetBpp(buf_format));
offset[0] = 0;
return 0;
}
void SDMCompBufferAllocator::GetAlignedWidthAndHeight(int width, int height,
uint32_t *aligned_width,
uint32_t *aligned_height) {
if (!aligned_width || !aligned_height) {
return;
}
*aligned_width = ALIGN(width, 32);
*aligned_height = ALIGN(height, 32);
}
int SDMCompBufferAllocator::SetBufferInfo(LayerBufferFormat format, int *target,
uint64_t *flags) {
return 0;
}
int SDMCompBufferAllocator::GetAlignedWidthAndHeight(int width, int height,
int format,
uint32_t alloc_type,
int *aligned_width,
int *aligned_height) {
return 0;
}
bool SDMCompBufferAllocator::GetSDMColorSpace(const int int_dataspace,
QtiDataspace *dataspace) {
return false;
}
LayerBufferFormat
SDMCompBufferAllocator::GetSDMFormat(const int32_t &source, const int32_t flags,
const int64_t compression_type) {
return kFormatInvalid;
}
DisplayError
SDMCompBufferAllocator::ColorMetadataToDataspace(Dataspace ds,
uint32_t *int_dataspace) {
return kErrorNone;
}
int32_t
SDMCompBufferAllocator::TranslateFromLegacyDataspace(const int32_t &legacy_ds) {
return 0;
}
} // namespace sdm

View File

@@ -0,0 +1,80 @@
/*
* Copyright (c) 2020, 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.
*/
/*
* Changes from Qualcomm Innovation Center, Inc. are provided under the following license:
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#ifndef __SDM_COMP_BUFFER_ALLOCATOR_H__
#define __SDM_COMP_BUFFER_ALLOCATOR_H__
#include <fcntl.h>
#include <sys/mman.h>
#include <core/sdm_types.h>
#include <core/buffer_allocator.h>
namespace sdm {
template <class Type>
inline Type ALIGN(Type x, Type align) {
return (x + align - 1) & ~(align - 1);
}
class SDMCompBufferAllocator : public BufferAllocator {
public:
virtual int AllocateBuffer(BufferInfo *buffer_info);
virtual int FreeBuffer(BufferInfo *buffer_info);
virtual uint32_t GetBufferSize(BufferInfo *buffer_info);
virtual int GetAllocatedBufferInfo(const BufferConfig &buffer_config,
AllocatedBufferInfo *allocated_buffer_info);
virtual int GetBufferLayout(const AllocatedBufferInfo &buf_info, uint32_t stride[4],
uint32_t offset[4], uint32_t *num_planes);
virtual int SetBufferInfo(LayerBufferFormat format, int *target,
uint64_t *flags);
virtual int GetAlignedWidthAndHeight(int width, int height, int format,
uint32_t alloc_type, int *aligned_width,
int *aligned_height);
virtual bool GetSDMColorSpace(const int int_dataspace,
QtiDataspace *dataspace);
virtual LayerBufferFormat GetSDMFormat(const int32_t &source,
const int32_t flags,
const int64_t compression_type);
virtual DisplayError ColorMetadataToDataspace(Dataspace ds,
uint32_t *int_dataspace);
virtual int32_t TranslateFromLegacyDataspace(const int32_t &legacy_ds);
private:
void GetAlignedWidthAndHeight(int width, int height, uint32_t *aligned_width,
uint32_t *aligned_height);
};
} // namespace sdm
#endif // __SDM_COMP_BUFFER_ALLOCATOR_H__

View File

@@ -0,0 +1,131 @@
/*
* Copyright (c) 2020, 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.
*/
/*
Changes from Qualcomm Innovation Center are provided under the following license:
Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted (subject to the limitations in the
disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 <string.h>
#include <sync/sync.h>
#include <utils/constants.h>
#include <utils/debug.h>
#include "sdm_comp_debugger.h"
#include "sdm_comp_buffer_sync_handler.h"
#define __CLASS__ "SDMCompBufferSyncHandler"
namespace sdm {
int SDMCompBufferSyncHandler::SyncWait(int fd) {
return SyncWait(fd, 1000);
}
int SDMCompBufferSyncHandler::SyncWait(int fd, int timeout) {
int error = 0;
if (fd >= 0) {
error = sync_wait(fd, timeout);
if (error < 0) {
DLOGW("sync_wait() error on fd = %d, timeout = %dms. (errno = %d \"%s\")", fd, timeout, errno,
strerror(errno));
return error;
}
}
return 0;
}
int SDMCompBufferSyncHandler::SyncMerge(int fd1, int fd2, int *merged_fd) {
// Merge the two fences. In the case where one of the fences is not a
// valid fence (e.g. NO_FENCE) merge the one valid fence with itself so
// that a new fence with the given name is created.
// TODO(user): "SyncMerge"string should be replaced with user-defined string to represent
// why it is merged.
if (fd1 >= 0 && fd2 >= 0) {
*merged_fd = sync_merge("SyncMerge", fd1, fd2);
} else if (fd1 >= 0) {
*merged_fd = sync_merge("SyncMerge", fd1, fd1);
} else if (fd2 >= 0) {
*merged_fd = sync_merge("SyncMerge", fd2, fd2);
} else {
*merged_fd = -1;
return 0;
}
if (*merged_fd == -1) {
DLOGE("Sync merge error! fd1 %d fd2 %d", fd1, fd2);
return -EINVAL;
}
return 0;
}
bool SDMCompBufferSyncHandler::IsSyncSignaled(int fd) {
if (sync_wait(fd, 0) < 0) {
return false;
} else {
return true;
}
}
} // namespace sdm

View File

@@ -0,0 +1,56 @@
/*
* Copyright (c) 2020, 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 __SDM_COMP_BUFFER_SYNC_HANDLER_H__
#define __SDM_COMP_BUFFER_SYNC_HANDLER_H__
#include <sys/mman.h>
#include <fcntl.h>
#include <core/sdm_types.h>
#include <core/buffer_sync_handler.h>
#include <utils/fence.h>
namespace sdm {
class SDMCompBufferSyncHandler : public BufferSyncHandler {
public:
SDMCompBufferSyncHandler() { Fence::Set(this); }
virtual int SyncWait(int fd);
virtual int SyncWait(int fd, int timeout);
virtual int SyncMerge(int fd1, int fd2, int *merged_fd);
virtual bool IsSyncSignaled(int fd);
virtual void GetSyncInfo(int fd, std::ostringstream *os) { };
};
} // namespace sdm
#endif // __SDM_COMP_BUFFER_SYNC_HANDLER_H__

View File

@@ -0,0 +1,315 @@
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
*
* Changes from Qualcomm Innovation Center are provided under the following license:
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 <stdio.h>
#include <stdarg.h>
#ifdef ANDROID
#include <log/log.h>
#endif
#include <utils/constants.h>
#include "sdm_comp_debugger.h"
#include <string>
#include <cstring>
using std::string;
namespace sdm {
SDMCompDebugHandler SDMCompDebugHandler::debug_handler_;
SDMCompDebugHandler::SDMCompDebugHandler() {
DebugHandler::Set(SDMCompDebugHandler::Get());
PropertyParserInterface::Create(&prop_parser_intf_);
}
void SDMCompDebugHandler::DebugAll(bool enable, int verbose_level) {
if (enable) {
debug_handler_.log_mask_ = 0x7FFFFFFF;
if (verbose_level) {
// Enable verbose scalar logs only when explicitly enabled
debug_handler_.log_mask_[kTagScalar] = 0;
}
debug_handler_.verbose_level_ = verbose_level;
} else {
debug_handler_.log_mask_ = 0x1; // kTagNone should always be printed.
debug_handler_.verbose_level_ = 0;
}
DebugHandler::SetLogMask(debug_handler_.log_mask_);
}
void SDMCompDebugHandler::DebugResources(bool enable, int verbose_level) {
if (enable) {
debug_handler_.log_mask_[kTagResources] = 1;
debug_handler_.verbose_level_ = verbose_level;
} else {
debug_handler_.log_mask_[kTagResources] = 0;
debug_handler_.verbose_level_ = 0;
}
DebugHandler::SetLogMask(debug_handler_.log_mask_);
}
void SDMCompDebugHandler::DebugStrategy(bool enable, int verbose_level) {
if (enable) {
debug_handler_.log_mask_[kTagStrategy] = 1;
debug_handler_.verbose_level_ = verbose_level;
} else {
debug_handler_.log_mask_[kTagStrategy] = 0;
debug_handler_.verbose_level_ = 0;
}
DebugHandler::SetLogMask(debug_handler_.log_mask_);
}
void SDMCompDebugHandler::DebugCompManager(bool enable, int verbose_level) {
if (enable) {
debug_handler_.log_mask_[kTagCompManager] = 1;
debug_handler_.verbose_level_ = verbose_level;
} else {
debug_handler_.log_mask_[kTagCompManager] = 0;
debug_handler_.verbose_level_ = 0;
}
DebugHandler::SetLogMask(debug_handler_.log_mask_);
}
void SDMCompDebugHandler::DebugDriverConfig(bool enable, int verbose_level) {
if (enable) {
debug_handler_.log_mask_[kTagDriverConfig] = 1;
debug_handler_.verbose_level_ = verbose_level;
} else {
debug_handler_.log_mask_[kTagDriverConfig] = 0;
debug_handler_.verbose_level_ = 0;
}
DebugHandler::SetLogMask(debug_handler_.log_mask_);
}
void SDMCompDebugHandler::DebugRotator(bool enable, int verbose_level) {
if (enable) {
debug_handler_.log_mask_[kTagRotator] = 1;
debug_handler_.verbose_level_ = verbose_level;
} else {
debug_handler_.log_mask_[kTagRotator] = 0;
debug_handler_.verbose_level_ = 0;
}
DebugHandler::SetLogMask(debug_handler_.log_mask_);
}
void SDMCompDebugHandler::DebugScalar(bool enable, int verbose_level) {
if (enable) {
debug_handler_.log_mask_[kTagScalar] = 1;
debug_handler_.verbose_level_ = verbose_level;
} else {
debug_handler_.log_mask_[kTagScalar] = 0;
debug_handler_.verbose_level_ = 0;
}
DebugHandler::SetLogMask(debug_handler_.log_mask_);
}
void SDMCompDebugHandler::DebugQdcm(bool enable, int verbose_level) {
if (enable) {
debug_handler_.log_mask_[kTagQDCM] = 1;
debug_handler_.verbose_level_ = verbose_level;
} else {
debug_handler_.log_mask_[kTagQDCM] = 0;
debug_handler_.verbose_level_ = 0;
}
DebugHandler::SetLogMask(debug_handler_.log_mask_);
}
void SDMCompDebugHandler::DebugClient(bool enable, int verbose_level) {
if (enable) {
debug_handler_.log_mask_[kTagClient] = 1;
debug_handler_.verbose_level_ = verbose_level;
} else {
debug_handler_.log_mask_[kTagClient] = 0;
debug_handler_.verbose_level_ = 0;
}
DebugHandler::SetLogMask(debug_handler_.log_mask_);
}
void SDMCompDebugHandler::DebugDisplay(bool enable, int verbose_level) {
if (enable) {
debug_handler_.log_mask_[kTagDisplay] = 1;
debug_handler_.verbose_level_ = verbose_level;
} else {
debug_handler_.log_mask_[kTagDisplay] = 0;
debug_handler_.verbose_level_ = 0;
}
DebugHandler::SetLogMask(debug_handler_.log_mask_);
}
void SDMCompDebugHandler::DebugQos(bool enable, int verbose_level) {
if (enable) {
debug_handler_.log_mask_[kTagQOSClient] = 1;
debug_handler_.log_mask_[kTagQOSImpl] = 1;
debug_handler_.verbose_level_ = verbose_level;
} else {
debug_handler_.log_mask_[kTagQOSClient] = 0;
debug_handler_.log_mask_[kTagQOSImpl] = 0;
debug_handler_.verbose_level_ = 0;
}
DebugHandler::SetLogMask(debug_handler_.log_mask_);
}
void SDMCompDebugHandler::Error(const char *format, ...) {
va_list list;
va_start(list, format);
#ifdef ANDROID
__android_log_vprint(ANDROID_LOG_ERROR, LOG_TAG, format, list);
#else
char buffer[1024];
vsnprintf (buffer, 1024, format, list);
// TODO(user): print timestamp, process id and thread id
printf("E %s %s \n", LOG_TAG, buffer);
#endif
va_end(list);
}
void SDMCompDebugHandler::Warning(const char *format, ...) {
va_list list;
va_start(list, format);
#ifdef ANDROID
__android_log_vprint(ANDROID_LOG_WARN, LOG_TAG, format, list);
#else
char buffer[1024];
vsnprintf (buffer, 1024, format, list);
printf("W %s %s \n", LOG_TAG, buffer);
#endif
va_end(list);
}
void SDMCompDebugHandler::Info(const char *format, ...) {
va_list list;
va_start(list, format);
#ifdef ANDROID
__android_log_vprint(ANDROID_LOG_INFO, LOG_TAG, format, list);
#else
char buffer[1024];
vsnprintf (buffer, 1024, format, list);
printf("I %s %s \n", LOG_TAG, buffer);
#endif
va_end(list);
}
void SDMCompDebugHandler::Debug(const char *format, ...) {
va_list list;
va_start(list, format);
#ifdef ANDROID
__android_log_vprint(ANDROID_LOG_DEBUG, LOG_TAG, format, list);
#else
char buffer[1024];
vsnprintf (buffer, 1024, format, list);
printf("D %s %s \n", LOG_TAG, buffer);
#endif
va_end(list);
}
void SDMCompDebugHandler::Verbose(const char *format, ...) {
if (debug_handler_.verbose_level_) {
va_list list;
va_start(list, format);
#ifdef ANDROID
__android_log_vprint(ANDROID_LOG_VERBOSE, LOG_TAG, format, list);
#else
char buffer[1024];
vsnprintf (buffer, 1024, format, list);
printf("V %s %s \n", LOG_TAG, buffer);
#endif
va_end(list);
}
}
void SDMCompDebugHandler::BeginTrace(const char *class_name, const char *function_name,
const char *custom_string) {
}
void SDMCompDebugHandler::EndTrace() {
}
int SDMCompDebugHandler::GetIdleTimeoutMs() {
return IDLE_TIMEOUT_DEFAULT_MS;
}
int SDMCompDebugHandler::GetProperty(const char *property_name, int *value) {
if (!property_name || !value)
return kErrorNotSupported;
if (prop_parser_intf_) {
return prop_parser_intf_->GetProperty(property_name, value);
}
auto it = properties_map_.find(property_name);
if (it != properties_map_.end())
*value = std::stoi(it->second);
else
return kErrorUndefined;
return kErrorNone;
}
int SDMCompDebugHandler::GetProperty(const char *property_name, char *value) {
if (!property_name || !value)
return kErrorNotSupported;
if (prop_parser_intf_) {
return prop_parser_intf_->GetProperty(property_name, value);
}
auto it = properties_map_.find(property_name);
if (it != properties_map_.end())
std::snprintf(value, it->second.size(), "%s", it->second.c_str());
else
return kErrorUndefined;
return kErrorNone;
}
int SDMCompDebugHandler::SetProperty(const char *property_name, const char *value) {
if (!property_name || !value) {
Error("SetProperty: failed to set property_name :%s :: %s\n", property_name, value);
return kErrorNotSupported;
}
properties_map_.emplace(std::string(property_name), std::string(value));
return kErrorNone;
}
} // namespace sdm

View File

@@ -0,0 +1,90 @@
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
*
* Changes from Qualcomm Innovation Center are provided under the following license:
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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 __SDM_COMP_DEBUGGER_H__
#define __SDM_COMP_DEBUGGER_H__
#include <core/sdm_types.h>
#include <debug_handler.h>
#include "property_parser_interface.h"
#include <bitset>
#include <map>
namespace sdm {
using display::DebugHandler;
class SDMCompDebugHandler : public DebugHandler {
public:
SDMCompDebugHandler();
static inline DebugHandler* Get() { return &debug_handler_; }
static void DebugAll(bool enable, int verbose_level);
static void DebugResources(bool enable, int verbose_level);
static void DebugStrategy(bool enable, int verbose_level);
static void DebugCompManager(bool enable, int verbose_level);
static void DebugDriverConfig(bool enable, int verbose_level);
static void DebugRotator(bool enable, int verbose_level);
static void DebugScalar(bool enable, int verbose_level);
static void DebugQdcm(bool enable, int verbose_level);
static void DebugClient(bool enable, int verbose_level);
static void DebugQos(bool enable, int verbose_level);
static void DebugDisplay(bool enable, int verbose_level);
static void DebugAllocator(bool enable, int verbose_level);
static int GetIdleTimeoutMs();
virtual void Error(const char *format, ...);
virtual void Warning(const char *format, ...);
virtual void Info(const char *format, ...);
virtual void Debug(const char *format, ...);
virtual void Verbose(const char *format, ...);
virtual void BeginTrace(const char *class_name, const char *function_name,
const char *custom_string);
virtual void EndTrace();
virtual int GetProperty(const char *property_name, int *value);
virtual int GetProperty(const char *property_name, char *value);
int SetProperty(const char *property_name, const char *value);
private:
static SDMCompDebugHandler debug_handler_;
std::bitset<32> log_mask_;
int32_t verbose_level_;
std::map<std::string, std::string> properties_map_;
PropertyParserInterface *prop_parser_intf_ = nullptr;
};
} // namespace sdm
#endif // __SDM_COMP_DEBUGGER_H__

View File

@@ -0,0 +1,499 @@
/*
* Copyright (c) 2020-2021, 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.
*/
/*
* Changes from Qualcomm Innovation Center are provided under the following license:
* Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#include <utils/constants.h>
#include <utils/debug.h>
#include <errno.h>
#include <unistd.h>
#include "sdm_comp_display_builtin.h"
#include "sdm_comp_debugger.h"
#include "formats.h"
#include "utils/fence.h"
#include "utils/rect.h"
#define __CLASS__ "SDMCompDisplayBuiltIn"
namespace sdm {
SDMCompDisplayBuiltIn::SDMCompDisplayBuiltIn(CoreInterface *core_intf,
CallbackInterface *callback, SDMCompDisplayType disp_type, int32_t disp_id)
: core_intf_(core_intf), callback_(callback), display_type_(disp_type),
display_id_(disp_id) {
}
int SDMCompDisplayBuiltIn::Init() {
int status = 0;
DisplayError error = core_intf_->CreateDisplay(display_id_, this, &display_intf_);
if (error != kErrorNone) {
if (kErrorDeviceRemoved == error) {
DLOGW("Display creation cancelled. Display %d-%d removed.", display_id_, display_type_);
return -ENODEV;
} else {
DLOGE("Display create failed. Error = %d display_id = %d event_handler = %p disp_intf = %p",
error, display_id_, this, &display_intf_);
return -EINVAL;
}
}
error = display_intf_->SetDisplayState(kStateOn, false /* tear_down */, NULL /* release_fence */);
if (error != kErrorNone) {
status = -EINVAL;
goto cleanup;
}
display_intf_->GetActiveConfig(&active_config_);
display_intf_->GetConfig(active_config_, &variable_info_);
display_intf_->SetCompositionState(kCompositionGPU, false);
CreateLayerSet();
error = display_intf_->GetStcColorModes(&stc_mode_list_);
if (error != kErrorNone) {
DLOGW("Failed to get Stc color modes, error %d", error);
stc_mode_list_.list.clear();
} else {
DLOGI("Stc mode count %d", stc_mode_list_.list.size());
}
PopulateColorModes();
return status;
cleanup:
DestroyLayerSet();
core_intf_->DestroyDisplay(display_intf_);
return status;
}
int SDMCompDisplayBuiltIn::Deinit() {
DisplayConfigFixedInfo fixed_info = {};
display_intf_->GetConfig(&fixed_info);
DisplayError error = kErrorNone;
if (!fixed_info.is_cmdmode) {
error = display_intf_->Flush(&layer_stack_);
if (error != kErrorNone && error != kErrorPermission) {
DLOGE("Flush failed. Error = %d", error);
return -EINVAL;
}
}
DestroyLayerSet();
error = core_intf_->DestroyDisplay(display_intf_);
if (error != kErrorNone) {
DLOGE("Display destroy failed. Error = %d", error);
return -EINVAL;
}
first_commit_ = true;
return 0;
}
int SDMCompDisplayBuiltIn::GetNumVariableInfoConfigs(uint32_t *count) {
if (!count) {
return -EINVAL;
}
DisplayError error = display_intf_->GetNumVariableInfoConfigs(count);
if (error != kErrorNone) {
return -EINVAL;
}
return 0;
}
int SDMCompDisplayBuiltIn::GetDisplayConfig(int config_idx,
DisplayConfigVariableInfo *variable_info) {
if (!variable_info) {
return -EINVAL;
}
DisplayError error = display_intf_->GetConfig(config_idx, variable_info);
if (error != kErrorNone) {
return -EINVAL;
}
return 0;
}
int SDMCompDisplayBuiltIn::SetDisplayConfig(int config_idx) {
DisplayError error = display_intf_->SetActiveConfig(config_idx);
if (error != kErrorNone) {
return -EINVAL;
}
active_config_ = config_idx;
error = display_intf_->GetConfig(config_idx, &variable_info_);
if (error != kErrorNone) {
return -EINVAL;
}
return 0;
}
void SDMCompDisplayBuiltIn::SetFrameBufferConfig() {
DisplayConfigVariableInfo fb_config;
display_intf_->GetFrameBufferConfig(&fb_config);
fb_config.x_pixels = mixer_config_.width;
fb_config.y_pixels = mixer_config_.height;
display_intf_->SetFrameBufferConfig(fb_config);
}
void SDMCompDisplayBuiltIn::SetMixerConfig(uint32_t width, uint32_t height) {
mixer_config_.width = width;
mixer_config_.height = height;
SetFrameBufferConfig();
}
int SDMCompDisplayBuiltIn::GetDisplayAttributes(SDMCompDisplayAttributes *display_attributes) {
if (!display_attributes) {
return -EINVAL;
}
// 1. When DS is not enabled, Layers are to be rendered at display resolution, which is same as
// LM config.
// 2. When DS is enabled (for AI scaler), layers are to be rendered at resolution less than
// display resolution. In this scenario, LM is reconfigured to new resolution.
// So in both scenarios, mixer attributes can be considered as Display attributes.
display_attributes->x_res = mixer_config_.width;
display_attributes->y_res = mixer_config_.height;
display_attributes->x_dpi = variable_info_.x_dpi;
display_attributes->y_dpi = variable_info_.y_dpi;
display_attributes->vsync_period = variable_info_.vsync_period_ns;
display_attributes->is_yuv = variable_info_.is_yuv;
display_attributes->fps = variable_info_.fps;
display_attributes->smart_panel = variable_info_.smart_panel;
return 0;
}
int SDMCompDisplayBuiltIn::ShowBuffer(BufferHandle *buf_handle, int32_t *retire_fence) {
int status = PrepareLayerStack(buf_handle);
if (status != 0) {
DLOGE("PrepareLayerStack failed %d", status);
return status;
}
status = ApplyCurrentColorModeWithRenderIntent();
if (status != 0) {
DLOGW("Failed to ApplyCurrentColorModeWithRenderIntent. Error = %d", status);
}
if (!validated_) {
DisplayError error = display_intf_->Prepare(&layer_stack_);
if (error != kErrorNone) {
DLOGW("Prepare failed. Error = %d", error);
return -EINVAL;
}
// Cache layer, if demura is configured, demura layer will be created in Prepare() function
demura_layer_ = nullptr;
for (auto &layer : layer_stack_.layers) {
if (layer->flags.is_demura) {
DLOGI("Demura layer is present");
demura_layer_ = layer;
}
}
// RC resources available after first cycle so enable skip_validate from 2nd cycle
if (!first_commit_) {
validated_ = true;
}
} else {
if (demura_layer_ != nullptr) {
layer_stack_.layers.push_back(demura_layer_);
}
}
DisplayError error = display_intf_->Commit(&layer_stack_);
if (error != kErrorNone) {
DLOGW("Commit failed. Error = %d", error);
return -EINVAL;
}
Layer *layer = layer_stack_.layers.at(0);
*retire_fence = Fence::Dup(layer_stack_.retire_fence);
buf_handle->consumer_fence_fd = Fence::Dup(layer->input_buffer.release_fence);
first_commit_ = false;
return 0;
}
void SDMCompDisplayBuiltIn::PopulateColorModes() {
for (uint32_t i = 0; i < stc_mode_list_.list.size(); i++) {
snapdragoncolor::ColorMode stc_mode = stc_mode_list_.list[i];
ColorPrimaries gamut = static_cast<ColorPrimaries>(stc_mode.gamut);
GammaTransfer gamma = static_cast<GammaTransfer>(stc_mode.gamma);
RenderIntent intent = static_cast<RenderIntent>(stc_mode.intent);
color_mode_map_[gamut][gamma][intent] = stc_mode;
}
}
int SDMCompDisplayBuiltIn::SetColorModeWithRenderIntent(struct ColorMode mode) {
if (mode.gamut < ColorPrimaries_BT709_5 || mode.gamut >= ColorPrimaries_Max) {
DLOGE("Invalid color primaries %d", mode.gamut);
return -EINVAL;
}
if (mode.gamma < Transfer_sRGB || mode.gamma >= Transfer_Max) {
DLOGE("Invalid gamma transfer %d", mode.gamma);
return -EINVAL;
}
if (mode.intent >= kRenderIntentMaxRenderIntent ) {
DLOGE("Invalid intent %d", mode.intent);
return -EINVAL;
}
if (current_mode_.gamut == mode.gamut && current_mode_.gamma == mode.gamma &&
current_mode_.intent == mode.intent) {
return 0;
}
current_mode_ = mode;
apply_mode_ = true;
Refresh();
return 0;
}
int SDMCompDisplayBuiltIn::GetStcColorModeFromMap(const ColorMode &mode,
snapdragoncolor::ColorMode *out_mode) {
if (!out_mode) {
DLOGE("Invalid parameter, out_mode is NULL");
return -EINVAL;
}
if (color_mode_map_.find(mode.gamut) == color_mode_map_.end()) {
DLOGE("Color Primary %d is not supported", mode.gamut);
return -ENOTSUP;
}
if (color_mode_map_[mode.gamut].find(mode.gamma) == color_mode_map_[mode.gamut].end()) {
DLOGE("Gamma Transfer %d is not supported", mode.gamma);
return -ENOTSUP;
}
auto iter = color_mode_map_[mode.gamut][mode.gamma].find(mode.intent);
if (iter != color_mode_map_[mode.gamut][mode.gamma].end()) {
// Found the mode
*out_mode = iter->second;
return 0;
}
DLOGW("Can't find color mode gamut %d gamma %d intent %d", mode.gamut, mode.gamma, mode.intent);
return -ENOTSUP;
}
int SDMCompDisplayBuiltIn::ApplyCurrentColorModeWithRenderIntent() {
if (stc_mode_list_.list.size() < 1) {
return 0;
}
if (!apply_mode_) {
return 0;
}
snapdragoncolor::ColorMode mode;
int ret = GetStcColorModeFromMap(current_mode_, &mode);
if (ret) {
DLOGW("Cannot find mode for current_color_mode_ gamut %d gamma %d intent %d ",
current_mode_.gamut, current_mode_.gamma, current_mode_.intent);
return 0;
}
DLOGI("Applying Stc mode (gamut %d gamma %d intent %d hw_assets.size %d)",
mode.gamut, mode.gamma, mode.intent, mode.hw_assets.size());
DisplayError error = display_intf_->SetStcColorMode(mode);
if (error != kErrorNone) {
DLOGE("Failed to apply Stc color mode: gamut %d gamma %d intent %d err %d",
mode.gamut, mode.gamma, mode.intent, error);
return 0;
}
apply_mode_ = false;
validated_ = false;
DLOGV_IF(kTagQDCM, "Successfully applied mode gamut = %d, gamma = %d, intent = %d",
current_mode_.gamut, current_mode_.gamma, current_mode_.intent);
return 0;
}
int SDMCompDisplayBuiltIn::GetColorModes(uint32_t *out_num_modes, struct ColorMode *out_modes) {
if (!out_num_modes || !out_modes) {
DLOGE("Invalid parameters");
return -EINVAL;
}
auto it = stc_mode_list_.list.begin();
*out_num_modes = std::min(*out_num_modes, UINT32(stc_mode_list_.list.size()));
ColorMode mode = {};
for (uint32_t i = 0; i < *out_num_modes; it++, i++) {
mode.gamut = static_cast<ColorPrimaries>(it->gamut);
mode.gamma = static_cast<GammaTransfer>(it->gamma);
mode.intent = static_cast<RenderIntent>(it->intent);
out_modes[i] = mode;
}
return 0;
}
void SDMCompDisplayBuiltIn::CreateLayerSet() {
Layer *layer = new Layer();
layer->flags.updating = 1;
layer->src_rect = LayerRect(0, 0, variable_info_.x_pixels, variable_info_.y_pixels);
layer->dst_rect = layer->src_rect;
layer->input_buffer = {};
layer->input_buffer.width = variable_info_.x_pixels;
layer->input_buffer.height = variable_info_.y_pixels;
layer->input_buffer.unaligned_width = variable_info_.x_pixels;
layer->input_buffer.unaligned_height = variable_info_.y_pixels;
layer->input_buffer.format = kFormatInvalid;
layer->input_buffer.planes[0].fd = -1;
layer->input_buffer.handle_id = -1;
layer->frame_rate = variable_info_.fps;
layer->blending = kBlendingPremultiplied;
layer_set_.push_back(layer);
}
void SDMCompDisplayBuiltIn::DestroyLayerSet() {
// Remove any layer if any and clear layer stack
for (Layer *layer : layer_set_)
delete layer;
layer_set_.clear();
}
int SDMCompDisplayBuiltIn::PrepareLayerStack(BufferHandle *buf_handle) {
if (!buf_handle) {
DLOGE("buf_handle pointer is null");
return -EINVAL;
}
Layer *layer = layer_set_.at(0);
layer->input_buffer.planes[0].fd = buf_handle->fd;
layer->input_buffer.planes[0].stride = buf_handle->stride_in_bytes;
layer->input_buffer.handle_id = buf_handle->buffer_id;
layer->input_buffer.buffer_id = buf_handle->buffer_id;
if (cached_buf_handle_.width == buf_handle->width &&
cached_buf_handle_.height == buf_handle->height &&
cached_buf_handle_.aligned_width == buf_handle->aligned_width &&
cached_buf_handle_.aligned_height == buf_handle->aligned_height &&
cached_buf_handle_.format == buf_handle->format &&
cached_buf_handle_.src_crop == buf_handle->src_crop) {
layer_stack_.layers.clear();
for (auto &it : layer_set_)
layer_stack_.layers.push_back(it);
return 0;
}
BufferFormat buf_format = GetSDMCompFormat(layer->input_buffer.format);
LayerRect src_crop = LayerRect(buf_handle->src_crop.left, buf_handle->src_crop.top,
buf_handle->src_crop.right, buf_handle->src_crop.bottom);
layer->input_buffer.width = buf_handle->width;
layer->input_buffer.height = buf_handle->height;
layer->input_buffer.unaligned_width = buf_handle->width;
layer->input_buffer.unaligned_height = buf_handle->height;
layer->input_buffer.format = GetSDMFormat(buf_handle->format);
layer->frame_rate = variable_info_.fps;
layer->blending = kBlendingPremultiplied;
layer->src_rect = LayerRect(0, 0, buf_handle->width, buf_handle->height);
if (IsValid(src_crop)) {
layer->src_rect = Intersection(src_crop, layer->src_rect);
}
layer->dst_rect.right = (float)mixer_config_.width;
layer->dst_rect.bottom = (float)mixer_config_.height;
DLOGI("WxHxF %dx%dx%d Crop[LTRB] [%.0f %.0f %.0f %.0f]", layer->input_buffer.width,
layer->input_buffer.height, layer->input_buffer.format, layer->src_rect.left,
layer->src_rect.top, layer->src_rect.right, layer->src_rect.bottom);
layer_stack_.layers.clear();
validated_ = false;
for (auto &it : layer_set_)
layer_stack_.layers.push_back(it);
cached_buf_handle_.width = buf_handle->width;
cached_buf_handle_.height = buf_handle->height;
cached_buf_handle_.aligned_width = buf_handle->aligned_width;
cached_buf_handle_.aligned_height = buf_handle->aligned_height;
cached_buf_handle_.format = buf_handle->format;
cached_buf_handle_.src_crop = buf_handle->src_crop;
return 0;
}
DisplayError SDMCompDisplayBuiltIn::HandleEvent(DisplayEvent event) {
DLOGI("Received display event %d", event);
switch (event) {
case kDisplayPowerResetEvent:
case kPanelDeadEvent:
if (callback_) {
callback_->OnError();
}
break;
default:
break;
}
return kErrorNone;
}
int SDMCompDisplayBuiltIn::SetPanelBrightness(float brightness_level) {
if (brightness_level < min_panel_brightness_) {
DLOGE("brightness level is invalid!! brightness_level %f, min_panel_brightness %f",
brightness_level, min_panel_brightness_);
return -EINVAL;
}
// if min_panel_brightness is not set, then set panel_brightness value as min_panel_brightness
if (min_panel_brightness_ == 0.0f) {
min_panel_brightness_ = brightness_level;
}
DisplayError err = display_intf_->SetPanelBrightness(brightness_level);
if (err != kErrorNone) {
return -EINVAL;
}
return 0;
}
int SDMCompDisplayBuiltIn::SetMinPanelBrightness(float min_brightness) {
if (min_brightness < 0.0f || min_brightness > 1.0) {
DLOGE("Invalid min brightness settings %f", min_brightness);
return -EINVAL;
}
min_panel_brightness_ = min_brightness;
return 0;
}
} // namespace sdm

View File

@@ -0,0 +1,113 @@
/*
* Copyright (c) 2020-2021, 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.
*/
/*
* Changes from Qualcomm Innovation Center are provided under the following license:
* Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#ifndef __SDM_COMP_DISPLAY_BUILTIN_H__
#define __SDM_COMP_DISPLAY_BUILTIN_H__
#include <string>
#include <vector>
#include "utils/constants.h"
#include "core/display_interface.h"
#include "core/core_interface.h"
#include "core/sdm_types.h"
#include "sdm_comp_interface.h"
#include "private/color_params.h"
namespace sdm {
class SDMCompDisplayBuiltIn : public DisplayEventHandler {
public:
explicit SDMCompDisplayBuiltIn(CoreInterface *core_intf, CallbackInterface *callback,
SDMCompDisplayType disp_type, int32_t disp_id);
virtual ~SDMCompDisplayBuiltIn() { }
virtual DisplayError VSync(const DisplayEventVSync &vsync) { return kErrorNone; }
virtual DisplayError Refresh() { return kErrorNone; }
virtual DisplayError CECMessage(char *message) { return kErrorNone; }
virtual DisplayError HistogramEvent(int source_fd, uint32_t blob_id) { return kErrorNone; }
virtual DisplayError HandleEvent(DisplayEvent event);
virtual void MMRMEvent(bool restricted) { }
int Init();
int Deinit();
int GetDisplayAttributes(SDMCompDisplayAttributes *display_attributes);
int ShowBuffer(BufferHandle *buf_handle, int32_t *out_release_fence);
int SetColorModeWithRenderIntent(struct ColorMode mode);
int GetColorModes(uint32_t *out_num_modes, struct ColorMode *out_modes);
SDMCompDisplayType GetDisplayType() { return display_type_; }
int SetPanelBrightness(float brightness_level);
int SetMinPanelBrightness(float min_brightness);
int GetNumVariableInfoConfigs(uint32_t *count);
int GetDisplayConfig(int config_idx, DisplayConfigVariableInfo *variable_info);
int SetDisplayConfig(int config_idx);
void SetFrameBufferConfig();
void SetMixerConfig(uint32_t width, uint32_t height);
private:
void CreateLayerSet();
void DestroyLayerSet();
int PrepareLayerStack(BufferHandle *buf_handle);
void PopulateColorModes();
int GetStcColorModeFromMap(const ColorMode &mode, snapdragoncolor::ColorMode *out_mode);
int ApplyCurrentColorModeWithRenderIntent();
CoreInterface *core_intf_ = NULL;
DisplayInterface *display_intf_ = NULL;
DisplayConfigVariableInfo variable_info_ = {};
SDMCompMixerConfig mixer_config_ = {};
CallbackInterface *callback_ = NULL;
SDMCompDisplayType display_type_;
int display_id_ = -1;
LayerStack layer_stack_ = {};
uint32_t active_config_ = 0xFFFFFFFF;
bool apply_mode_ = false;
ColorMode current_mode_ = {};
snapdragoncolor::ColorModeList stc_mode_list_ = {};
typedef std::map<RenderIntent, snapdragoncolor::ColorMode> RenderIntentMap;
typedef std::map<GammaTransfer, RenderIntentMap> TransferMap;
std::map<ColorPrimaries, TransferMap> color_mode_map_ = {};
float min_panel_brightness_ = 0.0f;
bool validated_ = false;
bool first_commit_ = true;
std::vector<Layer *> layer_set_ = {};
BufferHandle cached_buf_handle_;
Layer *demura_layer_ = nullptr;
};
} // namespace sdm
#endif // __SDM_COMP_DISPLAY_BUILTIN_H__

View File

@@ -0,0 +1,511 @@
/*
* Copyright (c) 2020-2021, 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.
*/
/*
Changes from Qualcomm Innovation Center are provided under the following license:
Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted (subject to the limitations in the
disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 <string.h>
#include <thread>
#include "sdm_comp_impl.h"
#include "core/sdm_types.h"
#include "debug_handler.h"
#include "core/ipc_interface.h"
#include "vm_interface.h"
#include "private/generic_payload.h"
#include "sdm_comp_debugger.h"
#define __CLASS__ "SDMCompImpl"
namespace sdm {
SDMCompImpl *SDMCompImpl::sdm_comp_impl_ = nullptr;
SDMCompDisplayBuiltIn *SDMCompImpl::display_builtin_[kSDMCompDisplayTypeMax] = { nullptr };
uint32_t SDMCompImpl::ref_count_ = 0;
uint32_t SDMCompImpl::disp_ref_count_[kSDMCompDisplayTypeMax] = { 0 };
recursive_mutex recursive_mutex_;
SDMCompImpl *SDMCompImpl::GetInstance() {
if (!sdm_comp_impl_) {
sdm_comp_impl_= new SDMCompImpl();
}
return sdm_comp_impl_;
}
int SDMCompImpl::Init() {
lock_guard<recursive_mutex> obj(recursive_mutex_);
if (ref_count_) {
ref_count_++;
return 0;
}
int ret = SDMCompServiceIntf::Create(this, &sdm_comp_service_intf_);
if (ret != 0) {
DLOGW("SDMCompServiceIntf create failed!! %d\n", ret);
return ret;
}
ipc_intf_ = std::make_shared<SDMCompIPCImpl>();
DisplayError error = CoreInterface::CreateCore(&buffer_allocator_, &buffer_sync_handler_, NULL,
ipc_intf_, &core_intf_);
if (error != kErrorNone) {
DLOGE("Failed to create CoreInterface");
SDMCompServiceIntf::Destroy(sdm_comp_service_intf_);
return -EINVAL;
}
ref_count_++;
SDMCompDebugHandler *sdm_comp_dbg_handler =
static_cast<SDMCompDebugHandler *>(SDMCompDebugHandler::Get());
sdm_comp_dbg_handler->GetProperty(ENABLE_ROUNDED_CORNER, &rc_enabled_);
DLOGI("RC status: %d", rc_enabled_);
return 0;
}
int SDMCompImpl::Deinit() {
lock_guard<recursive_mutex> obj(recursive_mutex_);
if (ref_count_) {
ref_count_--;
if (!ref_count_) {
if (sdm_comp_service_intf_) {
SDMCompServiceIntf::Destroy(sdm_comp_service_intf_);
}
DisplayError error = CoreInterface::DestroyCore();
if (error != kErrorNone) {
DLOGE("Display core de-initialization failed. Error = %d", error);
return -EINVAL;
}
if (ipc_intf_) {
ipc_intf_->Deinit();
}
delete sdm_comp_impl_;
sdm_comp_impl_ = nullptr;
}
}
return 0;
}
int SDMCompImpl::CreateDisplay(SDMCompDisplayType display_type, CallbackInterface *callback,
Handle *disp_hnd) {
lock_guard<recursive_mutex> obj(recursive_mutex_);
if (!disp_hnd || display_type >= kSDMCompDisplayTypeMax) {
return -EINVAL;
}
if (display_builtin_[display_type]) {
*disp_hnd = display_builtin_[display_type];
disp_ref_count_[display_type]++;
return 0;
}
int status = 0;
HWDisplaysInfo hw_displays_info = {};
DisplayError error = core_intf_->GetDisplaysStatus(&hw_displays_info);
if (error != kErrorNone) {
DLOGE("Failed to get connected display list. Error = %d", error);
return -EINVAL;
}
for (auto &iter : hw_displays_info) {
auto &info = iter.second;
if (info.display_type != kBuiltIn) {
continue;
}
if ((display_type == kSDMCompDisplayTypePrimary && !info.is_primary) ||
(display_type != kSDMCompDisplayTypePrimary && info.is_primary)) {
continue;
}
if (!info.is_connected) {
continue;
}
DLOGI("Create builtin display, id = %d, type = %d", info.display_id, display_type);
SDMCompDisplayBuiltIn *display_builtin = new SDMCompDisplayBuiltIn(core_intf_, callback,
display_type, info.display_id);
status = display_builtin->Init();
if (status) {
delete display_builtin;
display_builtin = nullptr;
return status;
}
*disp_hnd = display_builtin;
display_builtin_[display_type] = display_builtin;
disp_ref_count_[display_type]++;
HandlePendingEvents();
break;
}
return status;
}
int SDMCompImpl::DestroyDisplay(Handle disp_hnd) {
lock_guard<recursive_mutex> obj(recursive_mutex_);
if (!disp_hnd) {
DLOGE("Display handle is NULL");
return -EINVAL;
}
SDMCompDisplayBuiltIn *sdm_comp_display = reinterpret_cast<SDMCompDisplayBuiltIn *>(disp_hnd);
SDMCompDisplayType disp_type = sdm_comp_display->GetDisplayType();
if (disp_ref_count_[disp_type]) {
disp_ref_count_[disp_type]--;
if (!disp_ref_count_[disp_type]) {
int status = sdm_comp_display->Deinit();
if (status != 0) {
return status;
}
DLOGI("Destroying builtin display %d", disp_type);
delete display_builtin_[disp_type];
display_builtin_[disp_type] = nullptr;
}
}
first_commit_ = true;
return 0;
}
int SDMCompImpl::GetDisplayAttributes(Handle disp_hnd,
SDMCompDisplayAttributes *display_attributes) {
lock_guard<recursive_mutex> obj(recursive_mutex_);
if (!disp_hnd || !display_attributes) {
DLOGE("Invalid input param disp_hnd %d, display_attributes %d", disp_hnd, display_attributes);
return -EINVAL;
}
SDMCompDisplayBuiltIn *sdm_comp_display = reinterpret_cast<SDMCompDisplayBuiltIn *>(disp_hnd);
return sdm_comp_display->GetDisplayAttributes(display_attributes);
}
int SDMCompImpl::ShowBuffer(Handle disp_hnd, BufferHandle *buf_handle, int32_t *retire_fence) {
lock_guard<recursive_mutex> obj(recursive_mutex_);
if (!disp_hnd || !buf_handle || !retire_fence) {
DLOGE("Invalid input param disp_hnd %d, buf_handle %d, retire_fence %d", disp_hnd, buf_handle,
retire_fence);
return -EINVAL;
}
SDMCompDisplayBuiltIn *sdm_comp_display = reinterpret_cast<SDMCompDisplayBuiltIn *>(disp_hnd);
// RC resources available after first cycle so enable RC need two commits.
if(rc_enabled_ && first_commit_) {
sdm_comp_display->ShowBuffer(buf_handle, retire_fence);
int ret = buffer_sync_handler_.SyncWait(*retire_fence);
if (ret) {
DLOGW("syncwait failed err:%d", ret);
}
close(*retire_fence);
close(buf_handle->consumer_fence_fd);
first_commit_ = false;
}
return sdm_comp_display->ShowBuffer(buf_handle, retire_fence);
}
int SDMCompImpl::SetColorModeWithRenderIntent(Handle disp_hnd, struct ColorMode mode) {
lock_guard<recursive_mutex> obj(recursive_mutex_);
if (!disp_hnd) {
DLOGE("Invalid input param disp_hnd %d", disp_hnd);
return -EINVAL;
}
SDMCompDisplayBuiltIn *sdm_comp_display = reinterpret_cast<SDMCompDisplayBuiltIn *>(disp_hnd);
return sdm_comp_display->SetColorModeWithRenderIntent(mode);
}
int SDMCompImpl::GetColorModes(Handle disp_hnd, uint32_t *out_num_modes,
struct ColorMode *out_modes) {
lock_guard<recursive_mutex> obj(recursive_mutex_);
if (!disp_hnd || !out_num_modes || !out_modes) {
DLOGE("Invalid input param disp_hnd %d, out_num_modes %d, out_modes %d", disp_hnd, out_num_modes,
out_modes);
return -EINVAL;
}
SDMCompDisplayBuiltIn *sdm_comp_display = reinterpret_cast<SDMCompDisplayBuiltIn *>(disp_hnd);
return sdm_comp_display->GetColorModes(out_num_modes, out_modes);
}
int SDMCompImpl::SetPanelBrightness(Handle disp_hnd, float brightness_level) {
if (!disp_hnd) {
DLOGE("Invalid input param disp_hnd %d", disp_hnd);
return -EINVAL;
}
SDMCompDisplayBuiltIn *sdm_comp_display = reinterpret_cast<SDMCompDisplayBuiltIn *>(disp_hnd);
return sdm_comp_display->SetPanelBrightness(brightness_level);
}
int SDMCompImpl::SetMinPanelBrightness(Handle disp_hnd, float min_brightness_level) {
if (!disp_hnd) {
DLOGE("Invalid input param disp_hnd %d", disp_hnd);
return -EINVAL;
}
SDMCompDisplayBuiltIn *sdm_comp_display = reinterpret_cast<SDMCompDisplayBuiltIn *>(disp_hnd);
int err = sdm_comp_display->SetMinPanelBrightness(min_brightness_level);
if (err == 0) {
SDMCompDisplayType disp_type = sdm_comp_display->GetDisplayType();
if (panel_brightness_[disp_type] < min_brightness_level) {
return SetPanelBrightness(disp_hnd, min_brightness_level);
}
}
return err;
}
int SDMCompImpl::OnEvent(SDMCompServiceEvents event, ...) {
int err = 0;
va_list arguments;
va_start(arguments, event);
switch (event) {
case kEventSetPanelBrightness: {
lock_guard<recursive_mutex> obj(recursive_mutex_);
SDMCompDisplayType disp_type = (SDMCompDisplayType)(va_arg(arguments, int));
float panel_brightness = FLOAT(va_arg(arguments, double));
if (display_builtin_[disp_type]) {
int err = display_builtin_[disp_type]->SetPanelBrightness(panel_brightness);
DLOGI("Setting panel brightness value %f on display type %d is %s", panel_brightness,
disp_type, err ? "failed" : "successful");
} else {
pending_events_.emplace(std::make_pair(kEventSetPanelBrightness, disp_type));
panel_brightness_[disp_type] = panel_brightness;
DLOGI("Cache panel brightness value %f on display type %d", panel_brightness, disp_type);
}
} break;
case kEventSetDisplayConfig: {
lock_guard<recursive_mutex> obj(recursive_mutex_);
SDMCompDisplayType disp_type = (SDMCompDisplayType)(va_arg(arguments, int));
SDMCompServiceDispConfigs *disp_configs =
reinterpret_cast<SDMCompServiceDispConfigs*>(va_arg(arguments, Handle));
if (display_builtin_[disp_type]) {
DLOGW("Setting display config is not supported in the middle of TUI session");
err = -ENOTSUP;
} else {
pending_events_.emplace(std::make_pair(kEventSetDisplayConfig, disp_type));
disp_configs_[disp_type] = *disp_configs;
DLOGI("Cache display h_total %d, vtotal %d, fps %d, %s panel for display type %d",
disp_configs->h_total, disp_configs->v_total, disp_configs->fps,
disp_configs->smart_panel ? "cmdmode" : "videomode", disp_type);
}
} break;
case kEventImportDemuraBuffers: {
lock_guard<recursive_mutex> obj(recursive_mutex_);
SDMCompServiceDemuraBufInfo *demura_buf_info =
reinterpret_cast<SDMCompServiceDemuraBufInfo*>(va_arg(arguments, Handle));
if (demura_buf_info && ipc_intf_) {
GenericPayload pl;
SDMCompServiceDemuraBufInfo* buffer = nullptr;
if ((err = pl.CreatePayload<SDMCompServiceDemuraBufInfo>(buffer))) {
DLOGE("Failed to create payload for BufferInfo, error = %d", err);
break;
}
buffer->hfc_buf_fd = demura_buf_info->hfc_buf_fd;
buffer->hfc_buf_size = demura_buf_info->hfc_buf_size;
buffer->panel_id = demura_buf_info->panel_id;
if ((err = ipc_intf_->SetParameter(kIpcParamSetDemuraBuffer, pl))) {
DLOGE("Failed to Cache the demura Buffers err %d", err);
break;
}
}
} break;
default:
err = -EINVAL;
break;
}
va_end(arguments);
return err;
}
void SDMCompImpl::HandlePendingEvents() {
for (auto pending_event : pending_events_) {
SDMCompDisplayType display_type = pending_event.second;
switch (pending_event.first) {
case kEventSetDisplayConfig: {
uint32_t num_configs = 0;
bool foundConfig = false;
int err = display_builtin_[display_type]->GetNumVariableInfoConfigs(&num_configs);
for (uint32_t config_idx = 0; config_idx < num_configs; config_idx++) {
DisplayConfigVariableInfo variable_info = {};
int err = display_builtin_[display_type]->GetDisplayConfig(config_idx, &variable_info);
if (err == 0) {
if (variable_info.h_total != disp_configs_[display_type].h_total ||
variable_info.v_total != disp_configs_[display_type].v_total ||
variable_info.fps != disp_configs_[display_type].fps ||
variable_info.smart_panel != disp_configs_[display_type].smart_panel) {
continue;
}
err = display_builtin_[display_type]->SetDisplayConfig(config_idx);
if (err != 0) {
continue;
}
foundConfig = true;
DLOGI("Setting display config idx %d, WxH %dx%d, fps %d, %s panel for display type %d",
config_idx, variable_info.x_pixels, variable_info.y_pixels, variable_info.fps,
disp_configs_[display_type].smart_panel ? "cmdmode" : "videomode", display_type);
display_builtin_[display_type]->SetMixerConfig(disp_configs_[display_type].mixer_width,
disp_configs_[display_type].mixer_height);
break;
}
}
// TODO(user): Need to fix why config not coming properly
if (!foundConfig) {
DLOGW("Failed to find the current config, set the default config as 0");
err = display_builtin_[display_type]->SetDisplayConfig(0);
if (err != 0) {
DLOGW("Failed to set config to secondary vm");
}
}
} break;
case kEventSetPanelBrightness: {
int err = display_builtin_[display_type]->SetPanelBrightness(panel_brightness_[display_type]);
DLOGI("SetPanelBrightness value %f on display type %d is %s", panel_brightness_[display_type],
display_type, err ? "failed" : "successful");
} break;
default:
break;
}
}
pending_events_.clear();
}
int SDMCompIPCImpl::SetParameter(IPCParams param, const GenericPayload &in) {
int ret = 0;
switch(param) {
case kIpcParamSetDemuraBuffer: {
SDMCompServiceDemuraBufInfo *buf_info = nullptr;
uint32_t sz = 0;
if ((ret = in.GetPayload(buf_info, &sz))) {
DLOGE("Failed to get input payload error = %d", ret);
return ret;
}
if (buf_info->hfc_buf_fd > 0) {
hfc_buf_info_.hfc_buf_fd = buf_info->hfc_buf_fd;
hfc_buf_info_.hfc_buf_size = buf_info->hfc_buf_size;
hfc_buf_info_.panel_id = buf_info->panel_id;
} else {
DLOGW("Failed to import HFC buffer");
}
} break;
default:
break;
}
return 0;
}
int SDMCompIPCImpl::GetParameter(IPCParams param, GenericPayload *out) {
(void)param;
(void)out;
DLOGE("GetParameter on param %d is not supported", param);
return -ENOTSUP;
}
int SDMCompIPCImpl::ProcessOps(IPCOps op, const GenericPayload &in, GenericPayload *out) {
lock_guard<recursive_mutex> obj(recursive_mutex_);
if (!out) {
return -EINVAL;
}
int ret = 0;
switch(op) {
case kIpcOpsImportBuffers: {
IPCImportBufInParams *buf_in_params = nullptr;
IPCImportBufOutParams *buf_out_params = nullptr;
uint32_t sz = 0;
if ((ret = in.GetPayload(buf_in_params, &sz))) {
DLOGE("Failed to get input payload error = %d", ret);
return ret;
}
if ((ret = out->GetPayload(buf_out_params, &sz))) {
DLOGE("Failed to get output payload error = %d", ret);
return ret;
}
if (buf_in_params->req_buf_type == kIpcBufferTypeDemuraHFC) {
IPCBufferInfo buf;
buf.fd = hfc_buf_info_.hfc_buf_fd;
buf.size = hfc_buf_info_.hfc_buf_size;
buf.panel_id = hfc_buf_info_.panel_id;
buf.mem_handle = -1;
buf_out_params->buffers.push_back(buf);
DLOGI("ProcessOps: hfc fd:%d and size :%u", hfc_buf_info_.hfc_buf_fd,
hfc_buf_info_.hfc_buf_size);
} else {
DLOGE("Invalid buffer type : %d", buf_in_params->req_buf_type);
}
} break;
default:
break;
}
return 0;
}
int SDMCompIPCImpl::Deinit() {
hfc_buf_info_ = {};
return 0;
}
} // namespace sdm

View File

@@ -0,0 +1,139 @@
/*
* Copyright (c) 2020-2021, 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.
*/
/*
Changes from Qualcomm Innovation Center are provided under the following license:
Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted (subject to the limitations in the
disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 __SDM_COMP_IMPL_H__
#define __SDM_COMP_IMPL_H__
#include <core/core_interface.h>
#include <errno.h>
#include <mutex>
#include <condition_variable>
#include "sdm_comp_buffer_sync_handler.h"
#include "sdm_comp_buffer_allocator.h"
#include "sdm_comp_interface.h"
#include "core/display_interface.h"
#include "sdm_comp_service_intf.h"
#include "sdm_comp_display_builtin.h"
namespace sdm {
using std::recursive_mutex;
using std::lock_guard;
class SDMCompIPCImpl : public IPCIntf {
public:
int Init() { return 0; }
int Deinit();
int SetParameter(IPCParams param, const GenericPayload &in);
int GetParameter(IPCParams param, GenericPayload *out);
int ProcessOps(IPCOps op, const GenericPayload &in, GenericPayload *out);
private:
SDMCompServiceDemuraBufInfo hfc_buf_info_ {};
};
class SDMCompImpl : public SDMCompInterface, SDMCompServiceCbIntf {
public:
static SDMCompImpl *GetInstance();
virtual ~SDMCompImpl() { }
int Init();
int Deinit();
int SetParameter(IPCParams param, const GenericPayload &in);
int GetParameter(IPCParams param, GenericPayload *out);
int ProcessOps(IPCOps op, const GenericPayload &in, GenericPayload *out);
protected:
virtual int CreateDisplay(SDMCompDisplayType display_type, CallbackInterface *callback,
Handle *disp_hnd);
virtual int DestroyDisplay(Handle disp_hnd);
virtual int GetDisplayAttributes(Handle disp_hnd, SDMCompDisplayAttributes *display_attributes);
virtual int ShowBuffer(Handle disp_hnd, BufferHandle *buf_handle, int32_t *retire_fence);
virtual int SetColorModeWithRenderIntent(Handle disp_hnd, struct ColorMode mode);
virtual int GetColorModes(Handle disp_hnd, uint32_t *out_num_modes,
struct ColorMode *out_modes);
virtual int SetPanelBrightness(Handle disp_hnd, float brightness_level);
virtual int SetMinPanelBrightness(Handle disp_hnd, float min_brightness_level);
virtual int OnEvent(SDMCompServiceEvents event, ...);
void HandlePendingEvents();
static SDMCompImpl *sdm_comp_impl_;
static SDMCompDisplayBuiltIn *display_builtin_[kSDMCompDisplayTypeMax];
static uint32_t ref_count_;
static uint32_t disp_ref_count_[kSDMCompDisplayTypeMax];
CoreInterface *core_intf_ = nullptr;
SDMCompBufferAllocator buffer_allocator_;
SDMCompBufferSyncHandler buffer_sync_handler_;
SDMCompServiceIntf *sdm_comp_service_intf_ = nullptr;
float panel_brightness_[kSDMCompDisplayTypeMax] = {0.0f};
SDMCompServiceDispConfigs disp_configs_[kSDMCompDisplayTypeMax] = {};
std::map<SDMCompServiceEvents, SDMCompDisplayType> pending_events_ = {};
std::shared_ptr<SDMCompIPCImpl> ipc_intf_;
bool first_commit_ = true;
int rc_enabled_ = 0;
};
} // namespace sdm
#endif // __SDM_COMP_IMPL_H__

View File

@@ -0,0 +1,75 @@
/*
* Copyright (c) 2020, 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 <utils/debug.h>
#include <utils/utils.h>
#include "sdm_comp_interface.h"
#include "sdm_comp_impl.h"
#define __CLASS__ "SDMCompInterface"
namespace sdm {
int SDMCompInterface::Create(SDMCompInterface **intf) {
if (!intf) {
DLOGE("intf pointer is NULL");
return -EINVAL;
}
SDMCompImpl *sdm_comp_impl = SDMCompImpl::GetInstance();
if (!sdm_comp_impl) {
return -EINVAL;
}
int error = sdm_comp_impl->Init();
if (error != 0) {
DLOGE("Init failed with %d", error);
return error;
}
*intf = sdm_comp_impl;
return error;
}
int SDMCompInterface::Destroy(SDMCompInterface *intf) {
if (!intf) {
DLOGE("intf pointer is NULL");
return -EINVAL;
}
SDMCompImpl *sdm_comp_impl = static_cast<SDMCompImpl *>(intf);
int error = sdm_comp_impl->Deinit();
if (error != 0) {
DLOGE("Deinit failed with %d", error);
return error;
}
return 0;
}
} // namespace sdm

View File

@@ -0,0 +1,656 @@
/*
* Copyright (c) 2020-2021, 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.
*/
/*
Changes from Qualcomm Innovation Center are provided under the following license:
Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted (subject to the limitations in the
disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 <unistd.h>
#include <string.h>
#include <sys/poll.h>
#include <sys/mman.h>
#include <systemdq/sd-bus.h>
#include <mutex>
#include <algorithm>
#include <cstring>
#include <string>
#include "sdm_comp_service.h"
#include "sdm_comp_debugger.h"
#include "display_properties.h"
#define __CLASS__ "SDMCompService"
#define DISPLAY_SERVICE_FILE_WITH_PARAM "display@.service"
#define DISPLAY_SERVICE_FILE_NO_PARAM "display.service"
#define SYSTEMD_ESCAPE_BIN "/bin/systemd-escape"
namespace sdm {
std::mutex SDMCompService::qrtr_lock_;
std::vector <SDMCompServiceCbIntf *> SDMCompService::callbacks_ = {};
int SDMCompService::qrtr_fd_ = -1;
DynLib SDMCompService::qrtr_lib_ = {};
MemBuf *SDMCompService::mem_buf_ = nullptr;
DynLib SDMCompService::extension_lib_ = {};
CreateSDMCompExtnIntf SDMCompService::create_sdm_comp_extn_intf_ = nullptr;
DestroySDMCompExtnIntf SDMCompService::destroy_sdm_comp_extn_intf_ = nullptr;
SDMCompServiceExtnIntf *SDMCompService::sdm_comp_service_extn_intf_ = nullptr;
int SDMCompService::exit_thread_fd_ = -1;
std::thread SDMCompService::event_thread_ = {};
QrtrOpen SDMCompService::qrtr_open_ = nullptr;
QrtrClose SDMCompService::qrtr_close_ = nullptr;
QrtrSendTo SDMCompService::qrtr_send_to_ = nullptr;
QrtrPublish SDMCompService::qrtr_publish_ = nullptr;
QrtrBye SDMCompService::qrtr_bye_ = nullptr;
QrtrDecode SDMCompService::qrtr_decode_ = nullptr;
std::mutex SDMCompService::pending_cmd_lock_;
std::multimap<int, struct qrtr_packet> SDMCompService::pending_commands_ = {};
static bool IsModuleLoaded() {
FILE *fp = popen("cat /proc/modules | grep msm_drm", "r");
if (fp == NULL) {
return false;
}
char buf[16];
if (fread (buf, 1, sizeof (buf), fp) > 0) {
pclose(fp);
return true;
}
pclose(fp);
return false;
}
static int LoadModule(const std::string &service_file_path, const std::string &argument) {
if (IsModuleLoaded()) {
return 0;
}
sd_bus_error error = SD_BUS_ERROR_NULL;
sd_bus_message *msg = NULL;
sd_bus *bus = NULL;
char systemd_escape_cmd[256] = {};
char modified_arg[256] = {};
std::string mod_service_file_path(service_file_path);
if (!argument.empty()) {
FILE *cmd_file;
snprintf(systemd_escape_cmd, sizeof(systemd_escape_cmd), "%s '%s' 2>&1",
SYSTEMD_ESCAPE_BIN, argument.c_str());
DLOGI("systemd_escape_cmd %s", systemd_escape_cmd);
cmd_file = popen(systemd_escape_cmd, "r");
if (!cmd_file) {
DLOGI("cmd file is NULL");
return -EINVAL;
}
if (fgets(modified_arg, sizeof(modified_arg), cmd_file) == NULL) {
DLOGE("fgets returned null");
return -EINVAL;
}
DLOGI("modified_arg %s", modified_arg);
pclose(cmd_file);
std::size_t pos = mod_service_file_path.find_first_of('@');
if (pos == std::string::npos) {
DLOGE("Invalid service file path!!");
return -EINVAL;
}
mod_service_file_path.insert(pos + 1, modified_arg);
pos = mod_service_file_path.find_first_of('\n');
if (pos != std::string::npos) {
mod_service_file_path.erase(pos, 1);
}
}
DLOGI("service file path %s", mod_service_file_path.c_str());
int err = sd_bus_open_system(&bus);
if (err < 0) {
DLOGE("Failed to connect to system bus err %d %s", err, strerror(errno));
return err;
}
err = sd_bus_call_method(bus,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
"StartUnit",
&error,
&msg,
"ss",
mod_service_file_path.c_str(),
"replace");
if (err < 0) {
DLOGE("sd_bus_call_method failed with err %d %s", err, strerror(errno));
}
sd_bus_error_free(&error);
sd_bus_message_unref(msg);
sd_bus_unref(bus);
DLOGI("Loading kernel module is %s", (err < 0) ? "failed" : "successful");
return ((err < 0) ? err : 0);
}
int SDMCompService::RegisterCallback(SDMCompServiceCbIntf *callback) {
std::lock_guard<std::mutex> lock(qrtr_lock_);
if (qrtr_fd_ > 0) {
callbacks_.push_back(callback);
if (callback) {
std::thread(HandlePendingCommands).detach();
}
return 0;
}
int err = 0;
// Try to load qrtr library & get handle to its interface.
if (qrtr_lib_.Open("libqrtr.so.1.0.0")) {
if (!qrtr_lib_.Sym("qrtr_open", reinterpret_cast<void **>(&qrtr_open_)) ||
!qrtr_lib_.Sym("qrtr_close", reinterpret_cast<void **>(&qrtr_close_)) ||
!qrtr_lib_.Sym("qrtr_sendto", reinterpret_cast<void **>(&qrtr_send_to_)) ||
!qrtr_lib_.Sym("qrtr_publish", reinterpret_cast<void **>(&qrtr_publish_)) ||
!qrtr_lib_.Sym("qrtr_bye", reinterpret_cast<void **>(&qrtr_bye_)) ||
!qrtr_lib_.Sym("qrtr_decode", reinterpret_cast<void **>(&qrtr_decode_))) {
DLOGE("Unable to load symbols, error = %s", qrtr_lib_.Error());
return-ENOENT;
}
} else {
DLOGE("Unable to load libqrtr.so, error = %s", qrtr_lib_.Error());
return-ENOENT;
}
qrtr_fd_ = qrtr_open_(0);
if (qrtr_fd_ < 0) {
DLOGE("Failed to create qrtr socket");
err = -EINVAL;
goto cleanup;
}
err = qrtr_publish_(qrtr_fd_, SDM_COMP_SERVICE_ID, SDM_COMP_SERVICE_VERSION,
SDM_COMP_SERVICE_INSTANCE);
if (err < 0) {
DLOGE("failed to publish rmtfs service %d", err);
goto cleanup;
}
err = MemBuf::GetInstance(&mem_buf_);
if (err != 0) {
DLOGE("MemBuf::GetInstance failed!! %d\n", err);
goto cleanup;
}
// Try to load extension library & get handle to its interface.
if (extension_lib_.Open(EXTN_LIB_NAME)) {
if (!extension_lib_.Sym(CREATE_SDMCOMP_SERVICE_EXTN,
reinterpret_cast<void **>(&create_sdm_comp_extn_intf_)) ||
!extension_lib_.Sym(DESTROY_SDMCOMP_SERVICE_EXTN,
reinterpret_cast<void **>(&destroy_sdm_comp_extn_intf_))) {
DLOGE("Unable to load symbols, error = %s", extension_lib_.Error());
err = -ENOENT;
goto cleanup;
}
err = create_sdm_comp_extn_intf_(qrtr_fd_, &sdm_comp_service_extn_intf_);
if (err != 0) {
DLOGE("Unable to create sdm comp service extenstion interface");
goto cleanup;
}
} else {
DLOGW("Unable to load = %s, error = %s", EXTN_LIB_NAME, extension_lib_.Error());
}
// Create an eventfd to be used to unblock the poll system call when
// a thread is exiting.
exit_thread_fd_ = Sys::eventfd_(0, 0);
event_thread_ = std::thread(&SDMCompService::QRTREventHandler);
event_thread_.detach();
callbacks_.push_back(callback);
if (callback) {
HandlePendingCommands();
}
return 0;
cleanup:
UnRegisterCallback(callback);
return err;
}
int SDMCompService::UnRegisterCallback(SDMCompServiceCbIntf *callback) {
std::lock_guard<std::mutex> lock(qrtr_lock_);
auto it = std::find(callbacks_.begin(), callbacks_.end(), callback);
if (it != callbacks_.end()) {
callbacks_.erase(it);
}
if (!callbacks_.empty()) {
return 0;
}
uint64_t exit_value = 1;
if (exit_thread_fd_ > 0) {
ssize_t write_size = Sys::write_(exit_thread_fd_, &exit_value, sizeof(uint64_t));
if (write_size != sizeof(uint64_t)) {
DLOGW("Error triggering exit fd (%d). write size = %d, error = %s", exit_thread_fd_,
write_size, strerror(errno));
}
if (event_thread_.joinable()) {
event_thread_.join();
}
Sys::close_(exit_thread_fd_);
}
if (destroy_sdm_comp_extn_intf_) {
destroy_sdm_comp_extn_intf_(sdm_comp_service_extn_intf_);
}
if (mem_buf_) {
MemBuf::PutInstance();
}
if (qrtr_fd_ > 0) {
qrtr_bye_(qrtr_fd_, SDM_COMP_SERVICE_ID, SDM_COMP_SERVICE_VERSION,
SDM_COMP_SERVICE_INSTANCE);
qrtr_close_(qrtr_fd_);
}
return 0;
}
void SDMCompService::SendResponse(int node, int port, const Response &rsp) {
int ret = qrtr_send_to_(qrtr_fd_, node, port, &rsp, sizeof(rsp));
if (ret < 0) {
DLOGE("Failed to send response for command %d ret %d", rsp.id, ret);
}
DLOGI("Sent response for the command id %d size %d", rsp.id, sizeof(rsp));
}
void SDMCompService::HandleImportDemuraBuffers(const struct qrtr_packet &qrtr_pkt, Response *rsp) {
Command *cmd = reinterpret_cast<Command *>(qrtr_pkt.data);
rsp->id = cmd->id;
DemuraMemInfo *demura_mem_info = &cmd->cmd_export_demura_buf.demura_mem_info;
SDMCompServiceDemuraBufInfo demura_buf_info = {};
int demura_enabled = 0;
SDMCompDebugHandler *sdm_comp_dbg_handler =
static_cast<SDMCompDebugHandler *>(SDMCompDebugHandler::Get());
sdm_comp_dbg_handler->GetProperty(ENABLE_DEMURA, &demura_enabled);
if (!demura_enabled) {
DLOGI("demura is not enabled on TVM");
return;
}
DLOGI("hfc mem handle :%d", demura_mem_info->hfc_mem_hdl);
if (demura_mem_info->hfc_mem_hdl != -1) {
VmParams vm_params;
std::bitset<kVmPermissionMax> buf_perm = { 0 };
buf_perm.set(kVmPermissionRead);
buf_perm.set(kVmPermissionWrite);
vm_params.emplace(kVmTypeTrusted, buf_perm);
vm_params.emplace(kVmTypePrimary, buf_perm);
int error = mem_buf_->Import(demura_mem_info->hfc_mem_hdl, vm_params,
&demura_buf_info.hfc_buf_fd);
if (error != 0) {
DLOGW("Import failed with %d", error);
rsp->status = error;
return;
}
demura_buf_info.hfc_buf_size = demura_mem_info->hfc_mem_size;
demura_buf_info.panel_id = demura_mem_info->panel_id;
DLOGI("hfc fd:%d and size :%u", demura_buf_info.hfc_buf_fd, demura_buf_info.hfc_buf_size);
}
for (auto callback : callbacks_) {
if (callback) {
int err = callback->OnEvent(kEventImportDemuraBuffers, &demura_buf_info);
DLOGI("ImportDemuraBuffers on panel_id %lu is %s", demura_mem_info->panel_id,
err ? "failed" : "successful");
rsp->status = err;
}
}
}
void SDMCompService::HandleSetBacklight(const struct qrtr_packet &qrtr_pkt, Response *rsp) {
Command *cmd = reinterpret_cast<Command *>(qrtr_pkt.data);
rsp->id = cmd->id;
CmdSetBacklight *cmd_backlight = reinterpret_cast<CmdSetBacklight*>(&cmd->cmd_set_backlight);
SDMCompDisplayType sdm_comp_disp_type = GetSDMCompDisplayType(cmd_backlight->disp_type);
if (sdm_comp_disp_type == kSDMCompDisplayTypeMax) {
DLOGE("Invalid display_type %d", sdm_comp_disp_type);
rsp->status = -EINVAL;
return;
}
for (auto callback : callbacks_) {
if (callback) {
int err = callback->OnEvent(kEventSetPanelBrightness, sdm_comp_disp_type,
cmd_backlight->brightness);
rsp->status = err;
}
}
}
void SDMCompService::HandleSetDisplayConfigs(const struct qrtr_packet &qrtr_pkt, Response *rsp) {
Command *cmd = reinterpret_cast<Command *>(qrtr_pkt.data);
rsp->id = cmd->id;
CmdSetDisplayConfigs *cmd_disp_configs =
reinterpret_cast<CmdSetDisplayConfigs*>(&cmd->cmd_set_disp_configs);
SDMCompDisplayType sdm_comp_disp_type = GetSDMCompDisplayType(cmd_disp_configs->disp_type);
if (sdm_comp_disp_type == kSDMCompDisplayTypeMax) {
DLOGE("Invalid display_type %d", sdm_comp_disp_type);
rsp->status = -EINVAL;
return;
}
for (auto callback : callbacks_) {
if (callback) {
SDMCompServiceDispConfigs disp_configs = {};
disp_configs.h_total = cmd_disp_configs->h_total;
disp_configs.v_total = cmd_disp_configs->v_total;
disp_configs.fps = cmd_disp_configs->fps;
disp_configs.smart_panel = cmd_disp_configs->smart_panel;
disp_configs.mixer_width = cmd_disp_configs->mixer_width;
disp_configs.mixer_height = cmd_disp_configs->mixer_height;
int err = callback->OnEvent(kEventSetDisplayConfig, sdm_comp_disp_type, &disp_configs);
rsp->status = err;
}
}
}
void SDMCompService::HandleSetProperties(const struct qrtr_packet &qrtr_pkt, Response *rsp) {
Command *cmd = reinterpret_cast<Command *>(qrtr_pkt.data);
rsp->id = cmd->id;
CmdSetProperties *cmd_set_props =
reinterpret_cast<CmdSetProperties *>(&cmd->cmd_set_properties);
for (int i = 0; i < cmd_set_props->props.count; i++) {
SDMCompDebugHandler *sdm_comp_dbg_handler =
static_cast<SDMCompDebugHandler *>(SDMCompDebugHandler::Get());
sdm_comp_dbg_handler->SetProperty(cmd_set_props->props.property_list[i].prop_name,
cmd_set_props->props.property_list[i].value);
DLOGI("prop idx : %d, name: %s, value :%s", i, cmd_set_props->props.property_list[i].prop_name,
cmd_set_props->props.property_list[i].value);
}
}
void SDMCompService::HandleSetPanelBootParams(const struct qrtr_packet &qrtr_pkt, Response *rsp) {
Command *cmd = reinterpret_cast<Command *>(qrtr_pkt.data);
rsp->id = cmd->id;
CmdSetPanelBootParam *cmd_set_panel_boot_param =
reinterpret_cast<CmdSetPanelBootParam *>(&cmd->cmd_set_panel_boot_param);
DLOGI("panel_boot_param_string %s", cmd_set_panel_boot_param->panel_boot_string);
int ret = 0;
std::string panel_boot_str(cmd_set_panel_boot_param->panel_boot_string);
if (!panel_boot_str.empty())
ret = LoadModule(DISPLAY_SERVICE_FILE_WITH_PARAM, panel_boot_str);
else
ret = LoadModule(DISPLAY_SERVICE_FILE_NO_PARAM, panel_boot_str);
if (ret != 0) {
DLOGE("Failed loading kernel module %d", ret);
rsp->status = -EINVAL;
return;
}
}
void SDMCompService::CommandHandler(const struct qrtr_packet &qrtr_pkt) {
Response rsp = {};
rsp.status = -EINVAL;
if (qrtr_pkt.data_len < sizeof(Command)) {
DLOGW("Invalid packet!! length %zu command buffer size %d", qrtr_pkt.data_len, sizeof(Command));
SendResponse(qrtr_pkt.node, qrtr_pkt.port, rsp);
return;
}
Command *cmd = reinterpret_cast<Command *>(qrtr_pkt.data);
if (!cmd) {
DLOGE("cmd is null!!\n");
SendResponse(qrtr_pkt.node, qrtr_pkt.port, rsp);
return;
}
rsp.id = cmd->id;
if (cmd->id < kCmdMax) {
if (cmd->version > VM_INTF_VERSION) {
DLOGE("Invalid vm interface client version %x, supported version %x", cmd->version,
VM_INTF_VERSION);
SendResponse(qrtr_pkt.node, qrtr_pkt.port, rsp);
return;
}
// Command kCmdSetPanelBootParams is handled in sdm comp service. So valid client
// is not needed to handle it.
if ((cmd->id != kCmdSetPanelBootParams) && (cmd->id != kCmdSetProperties) &&
!IsRegisteredClientValid()) {
std::lock_guard<std::mutex> lock(pending_cmd_lock_);
struct qrtr_packet qrtr_pkt_temp = qrtr_pkt;
qrtr_pkt_temp.data = (void *)new uint8_t[sizeof(Command)];
qrtr_pkt_temp.data_len = sizeof(Command);
memcpy(qrtr_pkt_temp.data, qrtr_pkt.data, qrtr_pkt_temp.data_len);
pending_commands_.emplace(std::make_pair(cmd->id, qrtr_pkt_temp));
DLOGI("Registered client invalid handle the command %d later", cmd->id);
rsp.status = 0;
SendResponse(qrtr_pkt.node, qrtr_pkt.port, rsp);
return;
}
}
DLOGI("Received command %d from client fd %d node %d port %d", cmd->id, qrtr_fd_, qrtr_pkt.node,
qrtr_pkt.port);
switch (cmd->id) {
case kCmdExportDemuraBuffers:
HandleImportDemuraBuffers(qrtr_pkt, &rsp);
break;
case kCmdSetBacklight: {
HandleSetBacklight(qrtr_pkt, &rsp);
} break;
case kCmdSetDisplayConfig: {
HandleSetDisplayConfigs(qrtr_pkt, &rsp);
} break;
case kCmdSetProperties: {
HandleSetProperties(qrtr_pkt, &rsp);
} break;
case kCmdSetPanelBootParams: {
HandleSetPanelBootParams(qrtr_pkt, &rsp);
} break;
default:
if (sdm_comp_service_extn_intf_) {
sdm_comp_service_extn_intf_->CommandHandler(qrtr_pkt);
}
break;
}
if (cmd->id < kCmdMax) {
SendResponse(qrtr_pkt.node, qrtr_pkt.port, rsp);
}
}
void SDMCompService::QRTREventHandler() {
struct sockaddr_qrtr soc_qrtr = {};
struct qrtr_packet qrtr_pkt = {};
socklen_t soc_len;
char buf[4096] = {};
struct pollfd poll_fd[2] = {-1};
qrtr_lock_.lock();
// Add qrtr socket fd
poll_fd[0].fd = qrtr_fd_;
poll_fd[0].revents = 0;
poll_fd[0].events = POLLIN | POLLERR;
qrtr_lock_.unlock();
// Add event fd to exit the thread
poll_fd[1].fd = exit_thread_fd_;
poll_fd[1].revents = 0;
poll_fd[1].events = POLLIN;
// Clear any existing data
Sys::pread_(exit_thread_fd_, buf, 4096, 0);
DLOGI("Start listening to the client request %d", SDM_COMP_SERVICE_ID);
while(!callbacks_.empty()) {
int ret = poll(poll_fd, sizeof(poll_fd) / sizeof(struct pollfd), -1);
if (ret < 0) {
continue;
}
if (!(poll_fd[0].revents & POLLIN || poll_fd[0].revents & POLLERR)) {
continue;
}
soc_len = sizeof(soc_qrtr);
ret = recvfrom(qrtr_fd_, buf, sizeof(buf), 0, (sockaddr *)&soc_qrtr,
&soc_len);
if (ret < 0) {
if (errno == EAGAIN) {
continue;
}
return;
}
{
std::lock_guard<std::mutex> lock(qrtr_lock_);
ret = qrtr_decode_(&qrtr_pkt, buf, ret, &soc_qrtr);
if (ret < 0) {
DLOGE("failed to decode incoming message");
continue;
}
switch (qrtr_pkt.type) {
case QRTR_TYPE_DEL_CLIENT:
DLOGI("Client with port %d node %d is disconnected", qrtr_pkt.port, qrtr_pkt.node);
break;
case QRTR_TYPE_BYE:
DLOGI("System server goes down");
break;
case QRTR_TYPE_DATA:
CommandHandler(qrtr_pkt);
break;
}
}
}
DLOGI("Exiting qrtr event thread");
}
SDMCompDisplayType SDMCompService::GetSDMCompDisplayType(DisplayType disp_type) {
switch(disp_type) {
case kDisplayTypePrimary:
return kSDMCompDisplayTypePrimary;
case kDisplayTypeSecondary1:
return kSDMCompDisplayTypeSecondary1;
default:
return kSDMCompDisplayTypeMax;
}
}
void SDMCompService::HandlePendingCommands() {
std::lock_guard<std::mutex> lock(pending_cmd_lock_);
Response rsp = {};
for (auto cmd : pending_commands_) {
int cmd_id = cmd.first;
const struct qrtr_packet &qrtr_pkt = cmd.second;
switch (cmd_id) {
case kCmdExportDemuraBuffers:
HandleImportDemuraBuffers(qrtr_pkt, &rsp);
break;
case kCmdSetBacklight: {
HandleSetBacklight(qrtr_pkt, &rsp);
} break;
case kCmdSetDisplayConfig: {
HandleSetDisplayConfigs(qrtr_pkt, &rsp);
} break;
case kCmdSetProperties: {
HandleSetProperties(qrtr_pkt, &rsp);
} break;
case kCmdSetPanelBootParams: {
HandleSetPanelBootParams(qrtr_pkt, &rsp);
} break;
default:
break;
}
if (qrtr_pkt.data) {
delete [] qrtr_pkt.data;
}
}
pending_commands_.clear();
}
bool SDMCompService::IsRegisteredClientValid() {
for (auto callback : callbacks_) {
if (callback) {
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,138 @@
/*
* Copyright (c) 2020-2021, 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.
*/
/*
Changes from Qualcomm Innovation Center are provided under the following license:
Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted (subject to the limitations in the
disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 __SDM_COMP_SERVICE_H__
#define __SDM_COMP_SERVICE_H__
#include <stdint.h>
#include "vm_interface.h"
#include "libqrtr.h"
#include "membuf_wrapper.h"
#include "sdm_comp_service_intf.h"
#include "utils/sys.h"
#include "sdm_comp_service_extn_intf.h"
#include "sdm_comp_interface.h"
#include <mutex>
#include <vector>
#include <thread>
#include <map>
using std::mutex;
namespace sdm {
typedef int (*QrtrOpen)(int rport);
typedef void (*QrtrClose)(int sock);
typedef int (*QrtrSendTo)(int sock, uint32_t node, uint32_t port, const void *data,
unsigned int sz);
typedef int (*QrtrPublish)(int sock, uint32_t service, uint16_t version, uint16_t instance);
typedef int (*QrtrBye)(int sock, uint32_t service, uint16_t version, uint16_t instance);
typedef int (*QrtrDecode)(struct qrtr_packet *dest, void *buf, size_t len,
const struct sockaddr_qrtr *sq);
class SDMCompService {
public:
static int RegisterCallback(SDMCompServiceCbIntf *callback);
static int UnRegisterCallback(SDMCompServiceCbIntf *callback);
private:
static void QRTREventHandler();
static void CommandHandler(const struct qrtr_packet &qrtr_pkt);
static void SendResponse(int node, int port, const Response &rsp);
static void HandleImportDemuraBuffers(const struct qrtr_packet &qrtr_pkt, Response *rsp);
static void HandleSetBacklight(const struct qrtr_packet &qrtr_pkt, Response *rsp);
static void HandleSetDisplayConfigs(const struct qrtr_packet &qrtr_pkt, Response *rsp);
static void HandleSetProperties(const struct qrtr_packet &qrtr_pkt, Response *rsp);
static void HandleSetPanelBootParams(const struct qrtr_packet &qrtr_pkt, Response *rsp);
static SDMCompDisplayType GetSDMCompDisplayType(DisplayType disp_type);
static void HandlePendingCommands();
static bool IsRegisteredClientValid();
static std::mutex qrtr_lock_;
static QrtrOpen qrtr_open_;
static QrtrClose qrtr_close_;
static QrtrSendTo qrtr_send_to_;
static QrtrPublish qrtr_publish_;
static QrtrBye qrtr_bye_;
static QrtrDecode qrtr_decode_;
static std::vector <SDMCompServiceCbIntf *> callbacks_;
static int qrtr_fd_;
static DynLib qrtr_lib_;
static MemBuf *mem_buf_;
static DynLib extension_lib_;
static CreateSDMCompExtnIntf create_sdm_comp_extn_intf_;
static DestroySDMCompExtnIntf destroy_sdm_comp_extn_intf_;
static SDMCompServiceExtnIntf *sdm_comp_service_extn_intf_;
static int exit_thread_fd_;
static std::thread event_thread_;
static std::mutex pending_cmd_lock_;
static std::multimap<int, struct qrtr_packet> pending_commands_;
};
} // namespace sdm
#endif // __SDM_COMP_SERVICE_H__

View File

@@ -0,0 +1,60 @@
/*
Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted (subject to the limitations in the
disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 "sdm_comp_service_client.h"
#include "sdm_comp_service.h"
#include "debug_handler.h"
#define __CLASS__ "SDMCompServiceClient"
namespace sdm {
int SDMCompServiceClient::Init(SDMCompServiceCbIntf *callback) {
int err = SDMCompService::RegisterCallback(callback);
if (err != 0) {
DLOGE("Init failed!! err %d", err);
return err;
}
callback_ = callback;
return 0;
}
int SDMCompServiceClient::Deinit() {
return SDMCompService::UnRegisterCallback(callback_);
}
}

View File

@@ -0,0 +1,59 @@
/*
Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted (subject to the limitations in the
disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 __SDM_COMP_SERVICE_CLIENT_H__
#define __SDM_COMP_SERVICE_CLIENT_H__
#include <stdint.h>
#include "sdm_comp_service_intf.h"
#include "utils/sys.h"
#include "sdm_comp_interface.h"
namespace sdm {
class SDMCompServiceClient : public SDMCompServiceIntf {
public:
int Init(SDMCompServiceCbIntf *callback);
int Deinit();
~SDMCompServiceClient() { }
private:
SDMCompServiceCbIntf *callback_ = nullptr;
};
} // namespace sdm
#endif // __SDM_COMP_SERVICE_CLIENT_H__

View File

@@ -0,0 +1,108 @@
/*
* Copyright (c) 2020, 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.
*/
/*
Changes from Qualcomm Innovation Center are provided under the following license:
Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted (subject to the limitations in the
disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 <utils/debug.h>
#include <utils/utils.h>
#include "sdm_comp_service_intf.h"
#include "sdm_comp_service_client.h"
#define __CLASS__ "SDMCompServiceIntf"
namespace sdm {
int SDMCompServiceIntf::Create(SDMCompServiceCbIntf *callback, SDMCompServiceIntf **intf) {
if (!intf) {
DLOGE("intf pointer is NULL");
return -EINVAL;
}
SDMCompServiceClient *sdm_comp_service_client = new SDMCompServiceClient();
int error = sdm_comp_service_client->Init(callback);
if (error != 0) {
DLOGE("SDMCompServiceClient Init failed!! %d\n", error);
delete sdm_comp_service_client;
return error;
}
*intf = sdm_comp_service_client;
return 0;
}
int SDMCompServiceIntf::Destroy(SDMCompServiceIntf *intf) {
if (!intf) {
DLOGE("intf pointer is NULL");
return -EINVAL;
}
SDMCompServiceClient *sdm_comp_service_client = static_cast<SDMCompServiceClient *>(intf);
int error = sdm_comp_service_client->Deinit();
if (error != 0) {
DLOGE("Deinit failed with %d", error);
return error;
}
delete intf;
return 0;
}
} // namespace sdm