////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
// All rights reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file camxdefs.h
///
/// @brief CamX common definitions
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef CAMXDEFS_H
#define CAMXDEFS_H

#include "camxtypes.h"

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Constants
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const UINT64 NanoSecondsPerSecond = 1000000000ULL;

const UINT64 MicroSecondsPerSecond = 1000000ULL;

const UINT64 MilliSecondsPerSecond = 1000ULL;

const UINT64 NanoSecondsPerMicroSecond = 1000ULL;

const UINT64 MicroSecondsPerMilliSecond = 1000ULL;

const UINT64 NanoSecondsPerMilliSecond = 1000000ULL;

static const UINT32 MaxNumCameras           = 10;                   ///< Max number of cameras
static const UINT32 MaxNumPipelineNodes     = 16;                   ///< Max nodes per pipeline
static const UINT32 MaxPipelineOutputs      = 16;                   ///< Max buffer outputs per pipeline
static const UINT32 InvalidFrameNum         = 0xFFFFFFFF;           ///< Invalid FrameNum

/// @brief Define invalid requestId
static const UINT CamxInvalidRequestId = 0;

/// @brief Define invalid stream Id
static const UINT CamxInvalidStreamId = 0xBEEFCAFE;

/// @brief Define Invalid time for monitoring
static const UINT64 CamxInvalidExecutionTime = 0xFFFFFFFFFFFFFFFF;

/// @brief Define Default maximum execution time for a job
static const UINT64 MaxExecutionTimeMilliseconds   = 66;    ///< Maxtime of execution in 30FPS case and considering SBM delays
static const UINT64 MaxConfigureExecutionTimeMs    = 300;   ///< Max time of execution for feature2 or configureTIme jobs
static const UINT64 MaxExecutionTimeForCSLMs       = 90;    ///< Max Execution time for CSL thread
static const UINT64 MaxExecutionTimeForResultMs    = 200;   ///< Maximum execution time for camxsession result processing
static const UINT32 DefaultMaxDelayCount           = 1;     ///< Default Mas Delay count used in case it is not set explicitly
/// @brief Used to detect region/buffer overruns
static const UINT CamxCanary = 0x43216789;

/// @brief Maximum device index count
static const UINT CamxMaxDeviceIndex = 16;

///< Max buffer inputs per pipeline
static const UINT32 MaxPipelineInputs       = 56;

/// @brief 512 character string length
static const UINT32 MaxStringLength                     = 512;          ///< Maximum value string length

/// @brief 64 character string length
static const UINT32 MaxStringLength64 = 64;

/// @brief 128 character string length
static const UINT32 MaxStringLength128 = 128;

/// @brief 256 character string length
static const UINT32 MaxStringLength256 = 256;

/// @brief 256 character string length
static const UINT32 MaxStringLength4092 = 4092;

/// @brief Broadcast camera id;
static const UINT32 BroadcastCameraId = 255;

/// @brief Invalid camera id;
static const UINT32 InvalidCameraId = 0xFFFFFFFF;

/// @brief Invalid exposure time
static const UINT32 InvalidExposureTime = 0xFFFFFFFF;

/// @brief HAL buffer manager mode disabled
static const UINT32 HALBufferMgrModeDisabled            = 0;

/// @brief HAL buffer manager mode backward compatible
static const UINT32 HALbufferMgrModeBackwardCompatible  = 1;

/// @brief HAL buffer manager mode cached
static const UINT32 HALBufferMgrModeCached              = 2;

/// @brief Number of bits for base smart error code
static const UINT32 SmartErrorCodeBaseBits = 14;

/// @brief Node timeout bit position in smart error code
static const UINT32 NodeTimeOutBit = 1<<19;

/// @brief Fence unsignaled bit position in smart error code
static const UINT32 FenceUnsignaledBit = 1<<20;

/// @brief Fence unprocessed bit position in smart error code
static const UINT32 FenceUnprocessedBit = 1<<21;

/// @brief Dependencies not met bit position in smart error code
static const UINT32 DependenciesNotMetBit = 1<<22;

/// @brief ChiFence unsignaled bit position in smart error code
static const UINT32 ChiFenceUnsignaledBit = 1<<23;

/// @brief Dependencies not published fully bit position in smart error code
static const UINT32 DependenciesNotPublishedFullyBit = 1<<24;

/// @brief Non zero live pending requests bit position in smart error code
static const UINT32 NonZeroLivePendingRequestsBit = 1<<25;

/// @brief Request status bits starting from 28th bit
static const UINT32 RequestStatusBaseBits = 28;

/// @brief Request status bits mask
static const UINT32 RequestStatusBitsMask = 0x7;

/// @brief Mask for number of bits reserved for diff nodes in smart error code
static const UINT32 NodeIdMask = 0x1F;

/// @brief Total length of Stacktrace collected
static const UINT32 MaxStackTraceStringLength = 4096;

/// @brief Length of the logs dumped for each PC
static const UINT32  MaxStackTraceLnStringLength = 1024;

/// @brief Resolution standard for 4K
static const INT32 UHDResolutionWidth          = 3840;          ///< 4K UHD resolution width
static const INT32 UHDResolutionHeight         = 2160;          ///< 4K UHD resolution height
static const INT32 UHDResolution219Width       = 3840;          ///< 4K UHD resolution width for 21:9 mode
static const INT32 UHDResolution219Height      = 1644;          ///< 4K UHD resolution height for 21:9 mode

/// @brief Minimal ultra-high resolution for ultra-high resolution sensor definition
static const INT32 MinUHRSensorResolution      = 24000000;

const UINT ChiExternalNode              = 255;

constexpr INT32 InvalidPipelineCameraId = 0x7FFFFFFF;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Macros
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/// @brief Helper for CamX namespace
// NOWHINE CP011: We're defining the macro
#define CAMX_NAMESPACE_BEGIN namespace CamX {

/// @brief Helper for CamX namespace
#define CAMX_NAMESPACE_END }

/// @brief A hint to the compiler that inlining is desired.
#define CAMX_INLINE __inline

/// @brief Ensures a function is inlined where supported. Use with care.
#if defined(__GNUC__)
#define CAMX_INLINE_FORCE __attribute__((always_inline))
#else
#define CAMX_INLINE_FORCE
#endif // __GNUC__

/// @brief Data structures that are directly accessed by HW must be packed to have the expected layout expected. Use a
///        platform-independent macro for this purpose.
#if defined(__GNUC__)
#define CAMX_PACKED                  __attribute__((__packed__))
#define CAMX_BEGIN_PACKED
#define CAMX_PACKED_ALIGN_N(N)       __attribute__((packed, aligned(N)))
#define CAMX_BEGIN_PACKED_ALIGN_N(N)
#define CAMX_END_PACKED
#else
#define CAMX_PACKED
#define CAMX_BEGIN_PACKED   \
    __pragma(pack(push, 1))
#define CAMX_BEGIN_PACKED_ALIGN_N(N)    \
    __pragma(pack(push, N))
#define CAMX_END_PACKED     \
    __pragma(pack(pop))
#define CAMX_PACKED_ALIGN_N(N)
#endif // defined(__GNUC__)

#if defined(__GNUC__)
#define CAMX_VISIBILITY_PUBLIC __attribute__ ((visibility ("default")))
#define CAMX_VISIBILITY_LOCAL  __attribute__ ((visibility ("hidden")))
#else
#define CAMX_VISIBILITY_PUBLIC __declspec(dllexport)
#define CAMX_VISIBILITY_LOCAL
#endif // defined(__GNUC__)

#if defined(__clang__) && defined(__has_cpp_attribute)
#   if __has_cpp_attribute(clang::fallthrough)
#       define CAMX_FALLTHROUGH_INTENDED [[clang::fallthrough]]
#   endif // __has_cpp_attribute(clang::fallthrough)
#else
#   if defined(__GNUC__) && defined(__has_cpp_attribute)
#       if __has_cpp_attribute(gnu::fallthrough)
#           define CAMX_FALLTHROUGH_INTENDED [[gnu::fallthrough]]
#       endif // __has_cpp_attribute(gnu::fallthrough)
#   endif // defined(__GNUC__) && defined(__has_cpp_attribute)
#endif // defined(__clang__) && defined(__has_cpp_attribute)

#if !defined(CAMX_FALLTHROUGH_INTENDED)
#define CAMX_FALLTHROUGH_INTENDED
#endif // !defined(CAMX_FALLTHROUGH_INTENDED)

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// CAMX_ARRAY_SIZE
///
/// @brief  Calculates the number of elements in an array
///
/// @param  arr The array to count the elements of
///
/// @return The number of elements in the array
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define CAMX_ARRAY_SIZE(arr) (sizeof((arr)) / sizeof((arr)[0]))

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// CAMX_ARRAY_COLS
///
/// @brief  Calculates the number of columns in a 2D array
///
/// @param  arr The 2D array to count the number of columns of
///
/// @return The number of columns in the 2D array
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define CAMX_ARRAY_COLS(arr) (sizeof((arr)[0]) / sizeof((arr)[0][0]))

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// CAMX_ARRAY_ROWS
///
/// @brief  Calculates the number of rows in a 2D array
///
/// @param  arr The 2D array to count the number of rows of
///
/// @return The number of rows in the 2D array
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define CAMX_ARRAY_ROWS(arr) CAMX_ARRAY_SIZE(arr)

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// CAMX_STRINGIZE
///
/// @brief Stringize helper
///
/// @param arg Argument to stringize
///
/// @return Stringized arg
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define CAMX_STRINGIZE(arg) #arg

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// CAMX_STRINGIZE_MACRO
///
/// @brief Macro stringize helper
///
/// @param arg Argument to macro expand and stringize
///
/// @return Stringized expansion of arg
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define CAMX_STRINGIZE_MACRO(arg) CAMX_STRINGIZE(arg)

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// CAMX_UNREFERENCED_PARAM
///
/// @brief Unreferenced macro helper
///
/// @param param The unreferenced parameter.
///
/// @return void
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define CAMX_UNREFERENCED_PARAM(param) (void)param

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// CAMX_MAYBE_UNUSED_ARGUMENT
///
/// @brief Maybe unused macro helper for unused functions and variables. It is defined in C++17 only.
///
/// @return void
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#if defined(_LINUX)
#define CAMX_MAYBE_UNUSED_ARGUMENT [[maybe_unused]]
#else
#define CAMX_MAYBE_UNUSED_ARGUMENT
#endif // defined(_LINUX)

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// CAMX_ALIGN_TO
///
/// @brief Align the value to alignment
///
/// @param value        Value to be aligned to
/// @param alignment    alignment. Must be a multiple of two
///
/// @return Aligned value
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define CAMX_ALIGN_TO(value, alignment) (((value) + ((alignment) - 1)) & ~((alignment) - 1))

#endif // CAMXDEFS_H
