blob: cadbe54cac402743dd70e236716bcea0749964e7 [file] [log] [blame]
/*
* Copyright (c) 2019, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
//!
//! \file mos_utilities_next.cpp
//! \brief Common OS service across different platform
//! \details Common OS service across different platform
//!
#include "mos_utilities.h"
#include "mos_util_debug_next.h"
#include "media_user_settings_mgr.h"
#include <sstream>
#include <fcntl.h> //open
#include <malloc.h> // For memalign
#include <string.h> // memset
#include <stdlib.h> // atoi atol
#include <math.h>
#include "mos_os.h"
#if MOS_MESSAGES_ENABLED
#include <time.h> //for simulate random memory allcation failure
#endif
int32_t MosUtilities::m_mosMemAllocCounterNoUserFeature = 0;
int32_t MosUtilities::m_mosMemAllocCounterNoUserFeatureGfx = 0;
uint8_t MosUtilities::m_mosUltFlag = 0;
int32_t MosUtilities::m_mosMemAllocCounter = 0;
int32_t MosUtilities::m_mosMemAllocFakeCounter = 0;
int32_t MosUtilities::m_mosMemAllocCounterGfx = 0;
bool MosUtilities::m_enableAddressDump = false;
MOS_FUNC_EXPORT void MosUtilities::MosSetUltFlag(uint8_t ultFlag)
{
MosUtilities::m_mosUltFlag = ultFlag;
}
MOS_FUNC_EXPORT int32_t MosUtilities::MosGetMemNinjaCounter()
{
return m_mosMemAllocCounterNoUserFeature;
}
MOS_FUNC_EXPORT int32_t MosUtilities::MosGetMemNinjaCounterGfx()
{
return m_mosMemAllocCounterNoUserFeatureGfx;
}
#define __MAX_MULTI_STRING_COUNT 128
char MosUtilities::m_xmlFilePath[MOS_USER_CONTROL_MAX_DATA_SIZE] = {};
#if (_DEBUG || _RELEASE_INTERNAL)
uint32_t MosUtilities::m_mosAllocMemoryFailSimulateMode = 0;
uint32_t MosUtilities::m_mosAllocMemoryFailSimulateFreq = 0;
uint32_t MosUtilities::m_mosAllocMemoryFailSimulateHint = 0;
uint32_t MosUtilities::m_mosAllocMemoryFailSimulateAllocCounter = 0;
#define MEMORY_ALLOC_FAIL_SIMULATE_MODE_DEFAULT (0)
#define MEMORY_ALLOC_FAIL_SIMULATE_MODE_RANDOM (1)
#define MEMORY_ALLOC_FAIL_SIMULATE_MODE_TRAVERSE (2)
#define MIN_MEMORY_ALLOC_FAIL_FREQ (1) //max memory allcation fail rate 100%
#define MAX_MEMORY_ALLOC_FAIL_FREQ (10000) //min memory allcation fail rate 1/10000
#define MosAllocMemoryFailSimulationEnabled \
(m_mosAllocMemoryFailSimulateMode == MEMORY_ALLOC_FAIL_SIMULATE_MODE_RANDOM || \
m_mosAllocMemoryFailSimulateMode == MEMORY_ALLOC_FAIL_SIMULATE_MODE_TRAVERSE)
void MosUtilities::MosInitAllocMemoryFailSimulateFlag(MOS_CONTEXT_HANDLE mosCtx)
{
MOS_USER_FEATURE_VALUE_DATA userFeatureValueData;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
//default off for simulate random fail
m_mosAllocMemoryFailSimulateMode = MEMORY_ALLOC_FAIL_SIMULATE_MODE_DEFAULT;
m_mosAllocMemoryFailSimulateFreq = 0;
m_mosAllocMemoryFailSimulateHint = 0;
m_mosAllocMemoryFailSimulateAllocCounter = 0;
// Read Config : memory allocation failure simulate mode
MosZeroMemory(&userFeatureValueData, sizeof(userFeatureValueData));
MosUserFeatureReadValueID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_ALLOC_MEMORY_FAIL_SIMULATE_MODE_ID,
&userFeatureValueData,
mosCtx);
if ((userFeatureValueData.u32Data == MEMORY_ALLOC_FAIL_SIMULATE_MODE_DEFAULT) ||
(userFeatureValueData.u32Data == MEMORY_ALLOC_FAIL_SIMULATE_MODE_RANDOM) ||
(userFeatureValueData.u32Data == MEMORY_ALLOC_FAIL_SIMULATE_MODE_TRAVERSE))
{
m_mosAllocMemoryFailSimulateMode = userFeatureValueData.u32Data;
MOS_OS_NORMALMESSAGE("Init MosSimulateAllocMemoryFailSimulateMode as %d \n ", m_mosAllocMemoryFailSimulateMode);
}
else
{
m_mosAllocMemoryFailSimulateMode = MEMORY_ALLOC_FAIL_SIMULATE_MODE_DEFAULT;
MOS_OS_NORMALMESSAGE("Invalid Alloc Memory Fail Simulate Mode from config: %d \n ", userFeatureValueData.u32Data);
}
// Read Config : memory allocation failure simulate frequence
MosZeroMemory(&userFeatureValueData, sizeof(userFeatureValueData));
MosUserFeatureReadValueID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_ALLOC_MEMORY_FAIL_SIMULATE_FREQ_ID,
&userFeatureValueData,
mosCtx);
if ((userFeatureValueData.u32Data >= MIN_MEMORY_ALLOC_FAIL_FREQ) &&
(userFeatureValueData.u32Data <= MAX_MEMORY_ALLOC_FAIL_FREQ))
{
m_mosAllocMemoryFailSimulateFreq = userFeatureValueData.u32Data;
MOS_OS_NORMALMESSAGE("Init m_MosSimulateRandomAllocMemoryFailFreq as %d \n ", m_mosAllocMemoryFailSimulateFreq);
if (m_mosAllocMemoryFailSimulateMode == MEMORY_ALLOC_FAIL_SIMULATE_MODE_RANDOM)
{
srand((unsigned int)time(nullptr));
}
}
else
{
m_mosAllocMemoryFailSimulateFreq = 0;
MOS_OS_NORMALMESSAGE("Invalid Alloc Memory Fail Simulate Freq from config: %d \n ", userFeatureValueData.u32Data);
}
// Read Config : memory allocation failure simulate counter
MosZeroMemory(&userFeatureValueData, sizeof(userFeatureValueData));
MosUserFeatureReadValueID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_ALLOC_MEMORY_FAIL_SIMULATE_HINT_ID,
&userFeatureValueData,
mosCtx);
if (userFeatureValueData.u32Data <= m_mosAllocMemoryFailSimulateFreq)
{
m_mosAllocMemoryFailSimulateHint = userFeatureValueData.u32Data;
MOS_OS_NORMALMESSAGE("Init m_MosAllocMemoryFailSimulateHint as %d \n ", m_mosAllocMemoryFailSimulateHint);
}
else
{
m_mosAllocMemoryFailSimulateHint = m_mosAllocMemoryFailSimulateFreq;
MOS_OS_NORMALMESSAGE("Set m_mosAllocMemoryFailSimulateHint as %d since INVALID CONFIG %d \n ", m_mosAllocMemoryFailSimulateHint, userFeatureValueData.u32Data);
}
}
bool MosUtilities::MosSimulateAllocMemoryFail(
size_t size,
size_t alignment,
const char *functionName,
const char *filename,
int32_t line)
{
bool bSimulateAllocFail = false;
if (!MosAllocMemoryFailSimulationEnabled)
{
return false;
}
if (m_mosAllocMemoryFailSimulateMode == MEMORY_ALLOC_FAIL_SIMULATE_MODE_RANDOM)
{
int32_t Rn = rand();
m_mosAllocMemoryFailSimulateAllocCounter++;
if (Rn % m_mosAllocMemoryFailSimulateFreq == 1)
{
bSimulateAllocFail = true;
MOS_DEBUGMESSAGE(MOS_MESSAGE_LVL_CRITICAL, MOS_COMPONENT_OS, MOS_SUBCOMP_SELF, \
"Simulated Allocate Memory Fail (Rn=%d, SimulateAllocCounter=%d) for: functionName: %s, filename: %s, line: %d, size: %d, alignment: %d \n", \
Rn, m_mosAllocMemoryFailSimulateAllocCounter, functionName, filename, line, size, alignment);
}
else
{
bSimulateAllocFail = false;
}
}
else if (m_mosAllocMemoryFailSimulateMode == MEMORY_ALLOC_FAIL_SIMULATE_MODE_TRAVERSE)
{
if (m_mosAllocMemoryFailSimulateAllocCounter++ == m_mosAllocMemoryFailSimulateHint)
{
MOS_DEBUGMESSAGE(MOS_MESSAGE_LVL_CRITICAL, MOS_COMPONENT_OS, MOS_SUBCOMP_SELF, \
"Simulated Allocate Memory Fail (hint=%d) for: functionName: %s, filename: %s, line: %d, size: %d \n", \
m_mosAllocMemoryFailSimulateHint, functionName, filename, line, size, alignment);
bSimulateAllocFail = true;
}
else
{
bSimulateAllocFail = false;
}
}
else
{
MOS_OS_NORMALMESSAGE("Invalid m_MosAllocMemoryFailSimulateMode: %d \n ", m_mosAllocMemoryFailSimulateMode);
bSimulateAllocFail = false;
}
return bSimulateAllocFail;
}
#endif // #if (_DEBUG || _RELEASE_INTERNAL)
MOS_STATUS MosUtilities::MosUtilitiesInit(MOS_CONTEXT_HANDLE mosCtx)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MOS_OS_FUNCTION_ENTER;
eStatus = MosOsUtilitiesInit(mosCtx);
#if (_DEBUG || _RELEASE_INTERNAL)
//Initialize MOS simulate random alloc memorflag
MosInitAllocMemoryFailSimulateFlag(mosCtx);
MOS_USER_FEATURE_VALUE_DATA userFeatureValueData;
MosZeroMemory(&userFeatureValueData, sizeof(userFeatureValueData));
MosUserFeatureReadValueID(
nullptr,
__MEDIA_USER_FEATURE_VALUE_RESOURCE_ADDR_DUMP_ENABLE_ID,
&userFeatureValueData,
mosCtx);
MosUtilities::m_enableAddressDump = userFeatureValueData.i32Data ? true : false;
#endif
return eStatus;
}
MOS_STATUS MosUtilities::MosUtilitiesClose(MOS_CONTEXT_HANDLE mosCtx)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MOS_OS_FUNCTION_ENTER;
MediaUserSettingsMgr::MediaUserSettingClose();
// MOS_OS_Utilitlies_Close must be called right before end of function
// Because Memninja will calc mem leak here.
// Any memory allocation release after MosOsUtilitiesClose() will be treated as mem leak.
eStatus = MosOsUtilitiesClose(mosCtx);
#if (_DEBUG || _RELEASE_INTERNAL)
//Reset Simulate Alloc Memory Fail flags
MosInitAllocMemoryFailSimulateFlag(mosCtx);
#endif
return eStatus;
}
void MosUtilities::MosFreeUserFeatureValueString(PMOS_USER_FEATURE_VALUE_STRING pUserString)
{
if (pUserString != nullptr)
{
if (pUserString->uSize > 0)
{
if (pUserString->pStringData)
{
MOS_FreeMemAndSetNull(pUserString->pStringData);
m_mosMemAllocFakeCounter--;
}
pUserString->uSize = 0;
}
}
}
#if MOS_MESSAGES_ENABLED
void *MosUtilities::MosAlignedAllocMemoryUtils(
size_t size,
size_t alignment,
const char *functionName,
const char *filename,
int32_t line)
#else
void *MosUtilities::MosAlignedAllocMemory(
size_t size,
size_t alignment)
#endif // MOS_MESSAGES_ENABLED
{
void *ptr;
#if (_DEBUG || _RELEASE_INTERNAL)
if (MosSimulateAllocMemoryFail(size, alignment, functionName, filename, line))
{
return nullptr;
}
#endif
ptr = _aligned_malloc(size, alignment);
MOS_OS_ASSERT(ptr != nullptr);
if(ptr != nullptr)
{
MosAtomicIncrement(&m_mosMemAllocCounter);
MOS_MEMNINJA_ALLOC_MESSAGE(ptr, size, functionName, filename, line);
}
return ptr;
}
#if MOS_MESSAGES_ENABLED
void MosUtilities::MosAlignedFreeMemoryUtils(
void *ptr,
const char *functionName,
const char *filename,
int32_t line)
#else
void MosUtilities::MosAlignedFreeMemory(void *ptr)
#endif // MOS_MESSAGES_ENABLED
{
MOS_OS_ASSERT(ptr != nullptr);
if(ptr != nullptr)
{
MosAtomicDecrement(&m_mosMemAllocCounter);
MOS_MEMNINJA_FREE_MESSAGE(ptr, functionName, filename, line);
_aligned_free(ptr);
}
}
#if MOS_MESSAGES_ENABLED
void *MosUtilities::MosAllocMemoryUtils(
size_t size,
const char *functionName,
const char *filename,
int32_t line)
#else
void *MosUtilities::MosAllocMemory(size_t size)
#endif // MOS_MESSAGES_ENABLED
{
void *ptr;
#if (_DEBUG || _RELEASE_INTERNAL)
if (MosSimulateAllocMemoryFail(size, NO_ALLOC_ALIGNMENT, functionName, filename, line))
{
return nullptr;
}
#endif
ptr = malloc(size);
MOS_OS_ASSERT(ptr != nullptr);
if(ptr != nullptr)
{
MosAtomicIncrement(&m_mosMemAllocCounter);
MOS_MEMNINJA_ALLOC_MESSAGE(ptr, size, functionName, filename, line);
}
return ptr;
}
#if MOS_MESSAGES_ENABLED
void *MosUtilities::MosAllocAndZeroMemoryUtils(
size_t size,
const char *functionName,
const char *filename,
int32_t line)
#else
void *MosUtilities::MosAllocAndZeroMemory(size_t size)
#endif // MOS_MESSAGES_ENABLED
{
void *ptr;
#if (_DEBUG || _RELEASE_INTERNAL)
if (MosSimulateAllocMemoryFail(size, NO_ALLOC_ALIGNMENT, functionName, filename, line))
{
return nullptr;
}
#endif
ptr = malloc(size);
MOS_OS_ASSERT(ptr != nullptr);
if(ptr != nullptr)
{
MosZeroMemory(ptr, size);
MosAtomicIncrement(&m_mosMemAllocCounter);
MOS_MEMNINJA_ALLOC_MESSAGE(ptr, size, functionName, filename, line);
}
return ptr;
}
#if MOS_MESSAGES_ENABLED
void *MosUtilities::MosReallocMemoryUtils(
void *ptr,
size_t newSize,
const char *functionName,
const char *filename,
int32_t line)
#else
void *MosUtilities::MosReallocMemory(
void *ptr,
size_t newSize)
#endif // MOS_MESSAGES_ENABLED
{
void *oldPtr = nullptr;
void *newPtr = nullptr;
#if (_DEBUG || _RELEASE_INTERNAL)
if (MosSimulateAllocMemoryFail(newSize, NO_ALLOC_ALIGNMENT, functionName, filename, line))
{
return nullptr;
}
#endif
oldPtr = ptr;
newPtr = realloc(ptr, newSize);
MOS_OS_ASSERT(newPtr != nullptr);
if (newPtr != oldPtr)
{
if (oldPtr != nullptr)
{
MosAtomicDecrement(&m_mosMemAllocCounter);
MOS_MEMNINJA_FREE_MESSAGE(oldPtr, functionName, filename, line);
}
if (newPtr != nullptr)
{
MosAtomicIncrement(&m_mosMemAllocCounter);
MOS_MEMNINJA_ALLOC_MESSAGE(newPtr, newSize, functionName, filename, line);
}
}
return newPtr;
}
//!
//! \brief Wrapper for free(). Performs error checking.
//! \details Wrapper for free(). Performs error checking.
//! It decreases memory allocation counter variable
//! m_mosMemAllocCounter for checking memory leaks.
//! \param void *ptr
//! [in] Pointer to the memory to be freed
//! \return void
//!
#if MOS_MESSAGES_ENABLED
void MosUtilities::MosFreeMemoryUtils(
void *ptr,
const char *functionName,
const char *filename,
int32_t line)
#else
void MosUtilities::MosFreeMemory(void *ptr)
#endif // MOS_MESSAGES_ENABLED
{
if(ptr != nullptr)
{
MosAtomicDecrement(&m_mosMemAllocCounter);
MOS_MEMNINJA_FREE_MESSAGE(ptr, functionName, filename, line);
free(ptr);
}
}
void MosUtilities::MosZeroMemory(void *pDestination, size_t stLength)
{
MOS_OS_ASSERT(pDestination != nullptr);
if(pDestination != nullptr)
{
memset(pDestination, 0, stLength);
}
}
void MosUtilities::MosFillMemory(void *pDestination, size_t stLength, uint8_t bFill)
{
MOS_OS_ASSERT(pDestination != nullptr);
if(pDestination != nullptr)
{
memset(pDestination, bFill, stLength);
}
}
MOS_STATUS MosUtilities::MosReadFileToPtr(
const char *pFilename,
uint32_t *lpNumberOfBytesRead,
void **ppReadBuffer)
{
HANDLE hFile;
void *lpBuffer;
uint32_t fileSize;
uint32_t bytesRead;
MOS_STATUS eStatus;
*ppReadBuffer = nullptr;
*lpNumberOfBytesRead = 0;
eStatus = MosCreateFile(&hFile, (char *)pFilename, O_RDONLY);
if (eStatus != MOS_STATUS_SUCCESS)
{
MOS_OS_ASSERTMESSAGE("Failed to open file '%s'.", pFilename);
return eStatus;
}
eStatus = MosGetFileSize(hFile, &fileSize, nullptr);
if (eStatus != MOS_STATUS_SUCCESS)
{
MOS_OS_ASSERTMESSAGE("Failed to get size of file '%s'.", pFilename);
MosCloseHandle(hFile);
return eStatus;
}
lpBuffer = MOS_AllocAndZeroMemory(fileSize);
if (lpBuffer == nullptr)
{
MOS_OS_ASSERTMESSAGE("Failed to allocate memory.");
MosCloseHandle(hFile);
return MOS_STATUS_NO_SPACE;
}
if((eStatus = MosReadFile(hFile, lpBuffer, fileSize, &bytesRead, nullptr)) != MOS_STATUS_SUCCESS)
{
MOS_OS_ASSERTMESSAGE("Failed to read from file '%s'.", pFilename);
MosCloseHandle(hFile);
MOS_FreeMemory(lpBuffer);
lpBuffer = nullptr;
return eStatus;
}
MosCloseHandle(hFile);
*lpNumberOfBytesRead = bytesRead;
*ppReadBuffer = lpBuffer;
return eStatus;
}
MOS_STATUS MosUtilities::MosWriteFileFromPtr(
const char *pFilename,
void *lpBuffer,
uint32_t writeSize)
{
HANDLE hFile;
uint32_t bytesWritten;
MOS_STATUS eStatus;
MOS_OS_CHK_NULL(pFilename);
MOS_OS_CHK_NULL(lpBuffer);
if (writeSize == 0)
{
MOS_OS_ASSERTMESSAGE("Attempting to write 0 bytes to a file");
eStatus = MOS_STATUS_INVALID_PARAMETER;
goto finish;
}
bytesWritten = 0;
eStatus = MosCreateFile(&hFile, (char *)pFilename, O_WRONLY|O_CREAT);
if (eStatus != MOS_STATUS_SUCCESS)
{
MOS_OS_ASSERTMESSAGE("Failed to open file '%s'.", pFilename);
goto finish;
}
if((eStatus = MosWriteFile(hFile, lpBuffer, writeSize, &bytesWritten, nullptr)) != MOS_STATUS_SUCCESS)
{
MOS_OS_ASSERTMESSAGE("Failed to write to file '%s'.", pFilename);
MosCloseHandle(hFile);
goto finish;
}
MosCloseHandle(hFile);
finish:
return eStatus;
}
MOS_STATUS MosUtilities::MosAppendFileFromPtr(
const char *pFilename,
void *pData,
uint32_t dwSize)
{
MOS_STATUS eStatus;
HANDLE hFile;
uint32_t dwWritten;
//------------------------------
MOS_OS_ASSERT(pFilename);
MOS_OS_ASSERT(pData);
//------------------------------
dwWritten = 0;
eStatus = MosCreateFile(&hFile, (char *)pFilename, O_WRONLY | O_CREAT | O_APPEND);
if (eStatus != MOS_STATUS_SUCCESS)
{
MOS_OS_ASSERTMESSAGE("Failed to open file '%s'.", pFilename);
return eStatus;
}
eStatus = MosSetFilePointer(hFile, 0, nullptr, SEEK_END);
if (eStatus != MOS_STATUS_SUCCESS)
{
MOS_OS_ASSERTMESSAGE("Failed to set file pointer'%s'.", pFilename);
MosCloseHandle(hFile);
return eStatus;
}
// Write the file
if((eStatus = MosWriteFile(hFile, pData, dwSize, &dwWritten, nullptr)) != MOS_STATUS_SUCCESS)
{
MOS_OS_ASSERTMESSAGE("Failed to write to file '%s'.", pFilename);
MosCloseHandle(hFile);
return eStatus;
}
MosCloseHandle(hFile);
return eStatus;
}
/*****************************************************************************
|
| USER FEATURE Functions
|
*****************************************************************************/
MOS_STATUS MosUtilities::MosWriteOneUserFeatureKeyToXML(PMOS_USER_FEATURE_VALUE pUserFeature)
{
char sOutBuf[MOS_USER_CONTROL_MAX_DATA_SIZE];
char ValueType[MAX_USER_FEATURE_FIELD_LENGTH];
char KeyPath[MOS_USER_CONTROL_MAX_DATA_SIZE];
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MOS_OS_CHK_NULL_RETURN(pUserFeature);
switch (pUserFeature->Type)
{
case MOS_USER_FEATURE_TYPE_USER:
MosSecureStringPrint(
KeyPath,
sizeof(KeyPath),
sizeof(KeyPath),
"UFINT\\%s",
pUserFeature->pcPath);
break;
case MOS_USER_FEATURE_TYPE_SYSTEM:
MosSecureStringPrint(
KeyPath,
sizeof(KeyPath),
sizeof(KeyPath),
"UFEXT\\%s",
pUserFeature->pcPath);
break;
default:
MosSecureStringPrint(
KeyPath,
sizeof(KeyPath),
sizeof(KeyPath),
"%s",pUserFeature->pcPath);
break;
}
switch (pUserFeature->ValueType)
{
case MOS_USER_FEATURE_VALUE_TYPE_BOOL:
MosSecureStringPrint(
ValueType,
sizeof(ValueType),
sizeof(ValueType),
"bool");
break;
case MOS_USER_FEATURE_VALUE_TYPE_FLOAT:
case MOS_USER_FEATURE_VALUE_TYPE_UINT32:
case MOS_USER_FEATURE_VALUE_TYPE_INT32:
MosSecureStringPrint(
ValueType,
sizeof(ValueType),
sizeof(ValueType),
"dword");
break;
case MOS_USER_FEATURE_VALUE_TYPE_UINT64:
case MOS_USER_FEATURE_VALUE_TYPE_INT64:
MosSecureStringPrint(
ValueType,
sizeof(ValueType),
sizeof(ValueType),
"qword");
break;
case MOS_USER_FEATURE_VALUE_TYPE_MULTI_STRING:
case MOS_USER_FEATURE_VALUE_TYPE_STRING:
MosSecureStringPrint(
ValueType,
sizeof(ValueType),
sizeof(ValueType),
"string");
break;
default:
MosSecureStringPrint(
ValueType,
sizeof(ValueType),
sizeof(ValueType),
"unknown");
break;
}
MosZeroMemory(sOutBuf, sizeof(sOutBuf));
MosSecureStringPrint(
sOutBuf,
sizeof(sOutBuf),
sizeof(sOutBuf),
" <Key name=\"%s\" type=\"%s\" location=\"%s\" defaultval=\"%s\" description=\"%s\" />\n",
pUserFeature->pValueName,
ValueType,
KeyPath,
pUserFeature->DefaultValue,
pUserFeature->pcDescription);
MosAppendFileFromPtr(
m_xmlFilePath,
sOutBuf,
(uint32_t)strlen(sOutBuf));
return eStatus;
}
MOS_STATUS MosUtilities::MosWriteOneUserFeatureGroupToXML(MOS_USER_FEATURE_VALUE UserFeatureFilter)
{
char sOutBuf[MAX_USER_FEATURE_FIELD_LENGTH];
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
// Group Header Start
MosZeroMemory(sOutBuf, sizeof(sOutBuf));
MosSecureStringPrint(
sOutBuf,
sizeof(sOutBuf),
sizeof(sOutBuf),
" <Group name=\"%s\">\n",
UserFeatureFilter.pcGroup);
eStatus = MosAppendFileFromPtr(
m_xmlFilePath,
sOutBuf,
(uint32_t)strlen(sOutBuf));
// Group User Feature Keys
eStatus = MosGetItemFromMosUserFeatureDescField(
m_mosUserFeatureDescFields,
__MOS_USER_FEATURE_KEY_MAX_ID,
__MOS_USER_FEATURE_KEY_MAX_ID,
&MosWriteOneUserFeatureKeyToXML,
&UserFeatureFilter);
// Group Header End
MosZeroMemory(sOutBuf, sizeof(sOutBuf));
MosSecureStringPrint(
sOutBuf,
sizeof(sOutBuf),
sizeof(sOutBuf),
" </Group>\n",
UserFeatureFilter.pcGroup);
eStatus = MosAppendFileFromPtr(
m_xmlFilePath,
sOutBuf,
(uint32_t)strlen(sOutBuf));
return eStatus;
}
MOS_STATUS MosUtilities::MosGenerateUserFeatureKeyXML(MOS_CONTEXT_HANDLE mosCtx)
{
char sOutBuf[MAX_USER_FEATURE_FIELD_LENGTH];
uint32_t uiIndex=0;
MOS_USER_FEATURE_VALUE UserFeatureFilter = __NULL_USER_FEATURE_VALUE__;
MOS_USER_FEATURE_VALUE_DATA UserFeatureData;
const char * const FilterGroups[] = { "Codec", "Decode", "Encode", "CP", "General", "MOS",
"Report", "VP", "Media", "Secure HEVC Encode", "MDF"};
uint32_t FilterGroupsCount = sizeof(FilterGroups) / sizeof(FilterGroups[0]);
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
// Check if XML dump is enabled by User Feature Key
MosZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
eStatus = MosUserFeatureReadValueID(
nullptr,
__MOS_USER_FEATURE_KEY_XML_AUTOGEN_ID,
&UserFeatureData,
mosCtx);
if (UserFeatureData.u32Data == 0)
{
eStatus = MOS_STATUS_INVALID_PARAMETER;
return eStatus;
}
MosZeroMemory(&UserFeatureData, sizeof(UserFeatureData));
UserFeatureData.StringData.pStringData = m_xmlFilePath;
eStatus = MosUserFeatureReadValueID(
nullptr,
__MOS_USER_FEATURE_KEY_XML_FILEPATH_ID,
&UserFeatureData,
mosCtx);
// User Feature Key Header Start
MosZeroMemory(sOutBuf, sizeof(sOutBuf));
MosSecureStringPrint(
sOutBuf,
sizeof(sOutBuf),
sizeof(sOutBuf),
"<UserFeatureKeys>\n");
eStatus = MosWriteFileFromPtr(
UserFeatureData.StringData.pStringData,
sOutBuf,
(uint32_t)strlen(sOutBuf));
// User Feature Key Groups
for (uiIndex = 0; uiIndex < FilterGroupsCount; uiIndex++)
{
UserFeatureFilter.pcGroup = FilterGroups[uiIndex];
eStatus = MosWriteOneUserFeatureGroupToXML(UserFeatureFilter);
}
// User Feature Key Header End
MosZeroMemory(sOutBuf, sizeof(sOutBuf));
MosSecureStringPrint(
sOutBuf,
sizeof(sOutBuf),
sizeof(sOutBuf),
"</UserFeatureKeys>\n");
eStatus = MosAppendFileFromPtr(
UserFeatureData.StringData.pStringData,
sOutBuf,
(uint32_t)strlen(sOutBuf));
return eStatus;
}
MOS_STATUS MosUtilities::MosUserFeatureSetMultiStringValue(
PMOS_USER_FEATURE_VALUE_DATA pFeatureData,
uint32_t dwSize)
{
PMOS_USER_FEATURE_VALUE_STRING pStrings;
uint32_t uiNumStrings;
uint32_t ui;
char *pData;
char *pCurData;
uint32_t dwLen;
uint32_t dwPos;
MOS_OS_CHK_NULL_RETURN(pFeatureData);
MOS_OS_ASSERT(dwSize);
pStrings = pFeatureData->MultiStringData.pStrings;
pData = pFeatureData->MultiStringData.pMultStringData;
dwPos = 0;
uiNumStrings = 0;
MOS_OS_ASSERT(pStrings);
MOS_OS_ASSERT(pData);
// Find number of strings in the multi string array
do
{
pCurData = pData + dwPos;
dwLen = (uint32_t)strlen(pCurData);
if (dwLen == 0)
{
MOS_OS_NORMALMESSAGE("Invalid user feature key entry.");
return MOS_STATUS_INVALID_PARAMETER;
}
uiNumStrings++;
dwPos += dwLen + 1;
if (dwPos >= (dwSize - 1))
{
// last entry
break;
}
} while (true);
// Check the size of MultiStringData
if (pFeatureData->MultiStringData.uCount < uiNumStrings)
{
MOS_OS_NORMALMESSAGE("pFeatureValue->MultiStringData.uCount is smaller than the actual necessary number.");
return MOS_STATUS_UNKNOWN;
}
// Populate Array
dwPos = 0;
for (ui = 0; ui < uiNumStrings; ui++)
{
pCurData = pData + dwPos;
dwLen = (uint32_t)strlen(pCurData);
MOS_OS_ASSERT(dwLen > 0);
pStrings[ui].pStringData = pCurData;
pStrings[ui].uSize = dwLen;
dwPos += dwLen + 1;
}
pFeatureData->MultiStringData.uCount = uiNumStrings;
pFeatureData->MultiStringData.uSize = dwPos;
return MOS_STATUS_SUCCESS;
}
MOS_STATUS MosUtilities::MosCopyUserFeatureValueData(
PMOS_USER_FEATURE_VALUE_DATA pSrcData,
PMOS_USER_FEATURE_VALUE_DATA pDstData,
MOS_USER_FEATURE_VALUE_TYPE ValueType)
{
uint32_t ui;
PMOS_USER_FEATURE_VALUE_STRING pSrcString = nullptr;
PMOS_USER_FEATURE_VALUE_STRING pDstString = nullptr;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
//------------------------------
MOS_OS_ASSERT(pSrcData);
MOS_OS_ASSERT(pDstData);
MOS_OS_ASSERT(ValueType != MOS_USER_FEATURE_VALUE_TYPE_INVALID);
//------------------------------
switch(ValueType)
{
case MOS_USER_FEATURE_VALUE_TYPE_BOOL:
pDstData->bData = pSrcData->bData;
break;
case MOS_USER_FEATURE_VALUE_TYPE_INT32:
pDstData->i32Data = pSrcData->i32Data;
break;
case MOS_USER_FEATURE_VALUE_TYPE_INT64:
pDstData->i64Data = pSrcData->i64Data;
break;
case MOS_USER_FEATURE_VALUE_TYPE_UINT32:
pDstData->u32Data = pSrcData->u32Data;
break;
case MOS_USER_FEATURE_VALUE_TYPE_UINT64:
pDstData->u64Data = pSrcData->u64Data;
break;
case MOS_USER_FEATURE_VALUE_TYPE_FLOAT:
pDstData->fData = pSrcData->fData;
break;
case MOS_USER_FEATURE_VALUE_TYPE_STRING:
if ((pSrcData->StringData.pStringData != nullptr) && (strlen(pSrcData->StringData.pStringData) != 0))
{
pDstData->StringData.uMaxSize = pSrcData->StringData.uMaxSize;
pDstData->StringData.uSize = pSrcData->StringData.uSize;
if (pDstData->StringData.pStringData == nullptr)
{
MOS_OS_ASSERTMESSAGE("Failed to allocate memory.");
return MOS_STATUS_NULL_POINTER;
}
eStatus = MosSecureMemcpy(
pDstData->StringData.pStringData,
pDstData->StringData.uSize,
pSrcData->StringData.pStringData,
pSrcData->StringData.uSize);
}
break;
case MOS_USER_FEATURE_VALUE_TYPE_MULTI_STRING:
if ((pSrcData->MultiStringData.pMultStringData != nullptr) && (strlen(pSrcData->MultiStringData.pMultStringData) != 0))
{
pDstData->MultiStringData.uCount = pSrcData->MultiStringData.uCount;
pDstData->MultiStringData.uMaxSize = pSrcData->MultiStringData.uMaxSize;
pDstData->MultiStringData.uSize = pSrcData->MultiStringData.uSize;
if (pDstData->MultiStringData.pMultStringData != nullptr)
{
eStatus = MosSecureMemcpy(
pDstData->MultiStringData.pMultStringData,
pDstData->MultiStringData.uSize,
pSrcData->MultiStringData.pMultStringData,
pSrcData->MultiStringData.uSize);
for (ui = 0; ui < pSrcData->MultiStringData.uCount; ui++)
{
pSrcString = &pSrcData->MultiStringData.pStrings[ui];
pDstString = &pDstData->MultiStringData.pStrings[ui];
MOS_OS_CHK_NULL(pSrcString);
MOS_OS_CHK_NULL(pDstString);
pDstString->uMaxSize = pSrcString->uMaxSize;
pDstString->uSize = pSrcString->uSize;
if (pDstString->pStringData != nullptr)
{
eStatus = MosSecureMemcpy(
pDstString->pStringData,
pDstString->uSize+1,
pSrcString->pStringData,
pSrcString->uSize+1);
}// if
}// for
}
}// if
break;
default:
break;
}
finish:
return eStatus;
}
MOS_STATUS MosUtilities::MosAssignUserFeatureValueData(
PMOS_USER_FEATURE_VALUE_DATA pDstData,
const char *pData,
MOS_USER_FEATURE_VALUE_TYPE ValueType
)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
uint32_t dwUFSize = 0;
//------------------------------
MOS_OS_ASSERT(pData);
MOS_OS_ASSERT(pDstData);
MOS_OS_ASSERT(ValueType != MOS_USER_FEATURE_VALUE_TYPE_INVALID);
//------------------------------
switch(ValueType)
{
case MOS_USER_FEATURE_VALUE_TYPE_BOOL:
pDstData->bData = atoi(pData);
break;
case MOS_USER_FEATURE_VALUE_TYPE_INT32:
pDstData->i32Data = atoi(pData);
break;
case MOS_USER_FEATURE_VALUE_TYPE_INT64:
pDstData->i64Data = atol(pData);
break;
case MOS_USER_FEATURE_VALUE_TYPE_UINT32:
pDstData->u32Data = atoi(pData);
break;
case MOS_USER_FEATURE_VALUE_TYPE_UINT64:
pDstData->u64Data = atol(pData);
break;
case MOS_USER_FEATURE_VALUE_TYPE_FLOAT:
pDstData->fData = (float)atol(pData);
break;
case MOS_USER_FEATURE_VALUE_TYPE_STRING:
pDstData->StringData.uMaxSize = MOS_USER_CONTROL_MAX_DATA_SIZE;
if ((pData != nullptr) && (strlen(pData) != 0))
{
pDstData->StringData.uSize = (uint32_t)strlen(pData) + 1;
if (pDstData->StringData.uSize > pDstData->StringData.uMaxSize)
{
pDstData->StringData.uSize = pDstData->StringData.uMaxSize;
}
pDstData->StringData.pStringData = (char *)MOS_AllocAndZeroMemory(strlen(pData) + 1);
if (pDstData->StringData.pStringData == nullptr)
{
MOS_OS_ASSERTMESSAGE("Failed to allocate memory.");
return MOS_STATUS_NULL_POINTER;
}
m_mosMemAllocFakeCounter++;
eStatus = MosSecureStrcpy(
pDstData->StringData.pStringData,
pDstData->StringData.uSize,
(char *)pData);
}
break;
case MOS_USER_FEATURE_VALUE_TYPE_MULTI_STRING:
pDstData->MultiStringData.uCount = MOS_USER_MAX_STRING_COUNT;
pDstData->MultiStringData.uMaxSize = MOS_USER_CONTROL_MAX_DATA_SIZE;
pDstData->MultiStringData.pStrings = (PMOS_USER_FEATURE_VALUE_STRING)MOS_AllocAndZeroMemory(sizeof(MOS_USER_FEATURE_VALUE_STRING) * __MAX_MULTI_STRING_COUNT);
if (pDstData->MultiStringData.pStrings == nullptr)
{
MOS_OS_ASSERTMESSAGE("Failed to allocate memory.");
pDstData->MultiStringData.pMultStringData = nullptr;
pDstData->MultiStringData.uSize = 0;
pDstData->MultiStringData.uCount = 0;
return MOS_STATUS_NULL_POINTER;
}
if ((pData != nullptr) && (strlen(pData) != 0))
{
MOS_SafeFreeMemory(pDstData->MultiStringData.pMultStringData);
pDstData->MultiStringData.pMultStringData = (char *)MOS_AllocAndZeroMemory(strlen(pData) + 1);
if (pDstData->MultiStringData.pMultStringData == nullptr)
{
MOS_OS_ASSERTMESSAGE("Failed to allocate memory.");
return MOS_STATUS_NULL_POINTER;
}
eStatus = MosSecureMemcpy(
pDstData->MultiStringData.pMultStringData,
strlen(pData),
(char *)pData,
strlen(pData));
if ((eStatus = MosUserFeatureSetMultiStringValue(
pDstData,
dwUFSize)) != MOS_STATUS_SUCCESS)
{
MOS_OS_ASSERTMESSAGE("Failed to set multi string value.");
return eStatus;
}
}
break;
default:
break;
}
return eStatus;
}
MOS_STATUS MosUtilities::MosUserFeatureSetDefaultValues(
PMOS_USER_FEATURE_VALUE_WRITE_DATA pWriteValues,
uint32_t uiNumOfValues)
{
uint32_t ui;
PMOS_USER_FEATURE_VALUE pUserFeature = nullptr;
uint32_t ValueID = __MOS_USER_FEATURE_KEY_INVALID_ID;
MOS_STATUS eStatus = MOS_STATUS_UNKNOWN;
//--------------------------------------------------
MOS_OS_CHK_NULL_RETURN(pWriteValues);
//--------------------------------------------------
for (ui = 0; ui < uiNumOfValues; ui++)
{
ValueID = pWriteValues[ui].ValueID;
pUserFeature = MosUtilUserInterface::GetValue(ValueID);
MOS_OS_CHK_NULL_RETURN(pUserFeature);
// Copy the write data into corresponding user feature value
MosCopyUserFeatureValueData(
&pWriteValues[ui].Value,
&pUserFeature->Value,
pUserFeature->ValueType);
}
eStatus = MOS_STATUS_SUCCESS;
return eStatus;
}
MOS_STATUS MosUtilities::MosDeclareUserFeatureKey(PMOS_USER_FEATURE_VALUE pUserFeatureKey)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
//------------------------------
MOS_OS_CHK_NULL_RETURN(pUserFeatureKey);
//------------------------------
eStatus = MosAssignUserFeatureValueData(
&pUserFeatureKey->Value,
pUserFeatureKey->DefaultValue,
pUserFeatureKey->ValueType);
if (eStatus == MOS_STATUS_SUCCESS)
{
MosUtilUserInterface::AddEntry(pUserFeatureKey->ValueID, pUserFeatureKey);
}
return eStatus;
}
MOS_STATUS MosUtilities::MosDestroyUserFeatureData(PMOS_USER_FEATURE_VALUE_DATA pData,MOS_USER_FEATURE_VALUE_TYPE ValueType)
{
uint32_t ui;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
//------------------------------
if (pData == nullptr)
{
return eStatus;
}
//------------------------------
switch (ValueType)
{
case MOS_USER_FEATURE_VALUE_TYPE_STRING:
MosFreeUserFeatureValueString(&pData->StringData);
break;
case MOS_USER_FEATURE_VALUE_TYPE_MULTI_STRING:
for (ui = 0; ui < pData->MultiStringData.uCount; ui++)
{
MosFreeUserFeatureValueString(&pData->MultiStringData.pStrings[ui]);
}
MOS_SafeFreeMemory(pData->MultiStringData.pStrings);
pData->MultiStringData.pStrings = nullptr;
pData->MultiStringData.pMultStringData = nullptr;
pData->MultiStringData.uSize = 0;
pData->MultiStringData.uCount = 0;
break;
default:
break;
}
return eStatus;
}
MOS_STATUS MosUtilities::MosDestroyUserFeatureKey(PMOS_USER_FEATURE_VALUE pUserFeatureKey)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
//------------------------------
MOS_OS_CHK_NULL_RETURN(pUserFeatureKey);
//------------------------------
MosUtilUserInterface::DelEntry(pUserFeatureKey->ValueID);
eStatus = MosDestroyUserFeatureData(
&pUserFeatureKey->Value,
pUserFeatureKey->ValueType);
return eStatus;
}
MOS_STATUS MosUtilities::MosIsCorrectDefaultValueType(
const char *pData,
MOS_USER_FEATURE_VALUE_TYPE ValueType)
{
uint32_t dwLen;
uint32_t ui;
int32_t IntVal;
MOS_STATUS eStatus = MOS_STATUS_INVALID_PARAMETER;
dwLen = (uint32_t)strlen(pData);
//------------------------------
MOS_OS_ASSERT(pData);
MOS_OS_ASSERT(ValueType != MOS_USER_FEATURE_VALUE_TYPE_INVALID);
//------------------------------
switch (ValueType)
{
case MOS_USER_FEATURE_VALUE_TYPE_BOOL:
if ((!strcmp(pData, "0")) || (!strcmp(pData, "1")))
{
eStatus = MOS_STATUS_SUCCESS;
}
break;
case MOS_USER_FEATURE_VALUE_TYPE_INT32:
case MOS_USER_FEATURE_VALUE_TYPE_INT64:
case MOS_USER_FEATURE_VALUE_TYPE_UINT32:
case MOS_USER_FEATURE_VALUE_TYPE_UINT64:
case MOS_USER_FEATURE_VALUE_TYPE_FLOAT:
eStatus = MOS_STATUS_SUCCESS;
for (ui = 0; ui<dwLen; ui++)
{
IntVal = pData[ui] - '0';
if ((0 > IntVal) || (9 < IntVal))
{
if ((((ui == 0)&&(pData[ui] - '-') != 0)) && ((pData[ui] - '.') != 0))
{
eStatus = MOS_STATUS_INVALID_PARAMETER;
break;
}
}
}
break;
case MOS_USER_FEATURE_VALUE_TYPE_STRING:
eStatus = MOS_STATUS_SUCCESS;
break;
case MOS_USER_FEATURE_VALUE_TYPE_MULTI_STRING:
eStatus = MOS_STATUS_SUCCESS;
break;
default:
break;
}
return eStatus;
}
MOS_STATUS MosUtilities::MosIsCorrectUserFeatureDescField(PMOS_USER_FEATURE_VALUE pUserFeatureKey, uint32_t maxKeyID)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MOS_OS_CHK_NULL_RETURN(pUserFeatureKey);
if ((pUserFeatureKey->ValueID <= __MOS_USER_FEATURE_KEY_INVALID_ID) ||
(pUserFeatureKey->ValueID >= maxKeyID))
{
eStatus = MOS_STATUS_INVALID_PARAMETER;
return eStatus;
}
MOS_OS_CHK_NULL_RETURN(pUserFeatureKey->pValueName);
MOS_OS_CHK_NULL_RETURN(pUserFeatureKey->pcPath);
MOS_OS_CHK_NULL_RETURN(pUserFeatureKey->pcWritePath);
MOS_OS_CHK_NULL_RETURN(pUserFeatureKey->pcGroup);
if ((pUserFeatureKey->pcDescription != nullptr) &&
(strlen(pUserFeatureKey->pcDescription) > MAX_USER_FEATURE_FIELD_LENGTH))
{
eStatus = MOS_STATUS_INVALID_PARAMETER;
return eStatus;
}
eStatus = MosIsCorrectDefaultValueType(
pUserFeatureKey->DefaultValue,
pUserFeatureKey->ValueType);
return eStatus;
}
MOS_STATUS MosUtilities::MosGetItemFromMosUserFeatureDescField(
MOS_USER_FEATURE_VALUE *descTable,
uint32_t numOfItems,
uint32_t maxId,
MOS_STATUS (*CallbackFunc)(PMOS_USER_FEATURE_VALUE),
PMOS_USER_FEATURE_VALUE pUserFeatureKeyFilter)
{
uint32_t uiIndex = 0;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
//------------------------------
MOS_OS_CHK_NULL_RETURN(CallbackFunc);
MOS_OS_CHK_NULL_RETURN(pUserFeatureKeyFilter);
MOS_OS_CHK_NULL_RETURN(descTable);
//------------------------------
for (uiIndex = __MOS_USER_FEATURE_KEY_INVALID_ID; uiIndex < numOfItems; uiIndex++)
{
if (MosIsCorrectUserFeatureDescField(&descTable[uiIndex], maxId) != MOS_STATUS_SUCCESS)
{
continue;
}
if ((pUserFeatureKeyFilter->ValueID != __MOS_USER_FEATURE_KEY_INVALID_ID) && (pUserFeatureKeyFilter->ValueID != descTable[uiIndex].ValueID))
{
continue;
}
if ((pUserFeatureKeyFilter->pValueName != nullptr) && (strcmp(pUserFeatureKeyFilter->pValueName, descTable[uiIndex].pValueName) != 0))
{
continue;
}
if ((pUserFeatureKeyFilter->pcPath != nullptr) && (strcmp(pUserFeatureKeyFilter->pcPath, descTable[uiIndex].pcPath) != 0))
{
continue;
}
if ((pUserFeatureKeyFilter->pcWritePath != nullptr) && (strcmp(pUserFeatureKeyFilter->pcWritePath, descTable[uiIndex].pcWritePath) != 0))
{
continue;
}
if ((pUserFeatureKeyFilter->pcGroup != nullptr) && (strcmp(pUserFeatureKeyFilter->pcGroup, descTable[uiIndex].pcGroup) != 0))
{
continue;
}
if ((pUserFeatureKeyFilter->Type != MOS_USER_FEATURE_TYPE_INVALID) && (pUserFeatureKeyFilter->Type != descTable[uiIndex].Type))
{
continue;
}
if ((pUserFeatureKeyFilter->ValueType != MOS_USER_FEATURE_VALUE_TYPE_INVALID) && (pUserFeatureKeyFilter->ValueType != descTable[uiIndex].ValueType))
{
continue;
}
eStatus = (*CallbackFunc)(&descTable[uiIndex]);
}
return eStatus;
}
MOS_STATUS MosUtilities::MosDeclareUserFeatureKeysFromDescFields(
MOS_USER_FEATURE_VALUE *descTable,
uint32_t numOfItems,
uint32_t maxId)
{
MOS_USER_FEATURE_VALUE UserFeatureKeyFilter = __NULL_USER_FEATURE_VALUE__;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
eStatus = MosGetItemFromMosUserFeatureDescField(
descTable,
numOfItems,
maxId,
&MosDeclareUserFeatureKey,
&UserFeatureKeyFilter);
return eStatus;
}
MOS_STATUS MosUtilities::MosDeclareUserFeatureKeysForAllDescFields()
{
MOS_OS_CHK_STATUS_RETURN(MosDeclareUserFeatureKeysFromDescFields(
m_mosUserFeatureDescFields,
__MOS_USER_FEATURE_KEY_MAX_ID,
__MOS_USER_FEATURE_KEY_MAX_ID));
return MOS_STATUS_SUCCESS;
}
MOS_STATUS MosUtilities::MosDestroyUserFeatureKeysFromDescFields(
MOS_USER_FEATURE_VALUE *descTable,
uint32_t numOfItems,
uint32_t maxId)
{
MOS_USER_FEATURE_VALUE UserFeatureKeyFilter = __NULL_USER_FEATURE_VALUE__;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
eStatus = MosGetItemFromMosUserFeatureDescField(
descTable,
numOfItems,
maxId,
&MosDestroyUserFeatureKey,
&UserFeatureKeyFilter);
return eStatus;
}
MOS_STATUS MosUtilities::MosDestroyUserFeatureKeysForAllDescFields()
{
MOS_USER_FEATURE_VALUE UserFeatureKeyFilter = __NULL_USER_FEATURE_VALUE__;
MOS_OS_CHK_STATUS_RETURN(MosDestroyUserFeatureKeysFromDescFields(
m_mosUserFeatureDescFields,
__MOS_USER_FEATURE_KEY_MAX_ID,
__MOS_USER_FEATURE_KEY_MAX_ID));
return MOS_STATUS_SUCCESS;
}
MOS_STATUS MosUtilities::MosUserFeatureReadValueInit(uint32_t uiNumValues)
{
// Check if memory is allocated
if (uiNumValues == 0)
{
MOS_OS_ASSERTMESSAGE("pUserFeature->uiNumValues is 0.");
return MOS_STATUS_UNKNOWN;
}
return MOS_STATUS_SUCCESS;
}
void MosUtilities::MosUserFeatureCallback(
PTP_CALLBACK_INSTANCE Instance,
void *pvParameter,
PTP_WAIT Wait,
TP_WAIT_RESULT WaitResult)
{
PMOS_USER_FEATURE_NOTIFY_DATA pNotifyData;
MOS_UNUSED(Instance);
MOS_UNUSED(Wait);
MOS_UNUSED(WaitResult);
MOS_OS_ASSERT(pvParameter);
pNotifyData = (PMOS_USER_FEATURE_NOTIFY_DATA)pvParameter;
pNotifyData->bTriggered = true;
}
MOS_STATUS MosUtilities::MosUserFeatureOpen(
MOS_USER_FEATURE_TYPE KeyType,
const char *pSubKey,
uint32_t dwAccess,
void **pUFKey,
MOS_USER_FEATURE_KEY_PATH_INFO *ufInfo)
{
MOS_STATUS eStatus;
void *RootKey = 0;
MOS_OS_ASSERT(pSubKey);
MOS_OS_ASSERT(pUFKey);
if (KeyType == MOS_USER_FEATURE_TYPE_USER)
{
RootKey = (void *)UFKEY_INTERNAL;
}
else if (KeyType == MOS_USER_FEATURE_TYPE_SYSTEM)
{
RootKey = (void *)UFKEY_EXTERNAL;
}
else
{
MOS_OS_ASSERTMESSAGE("Invalid Key Type %d.", KeyType);
return MOS_STATUS_UNKNOWN;
}
if((eStatus = MosUserFeatureOpenKey(
RootKey,
pSubKey,
0,
dwAccess,
pUFKey,
ufInfo)) != MOS_STATUS_SUCCESS)
{
MOS_OS_NORMALMESSAGE("Unable to open user feature key %s.", pSubKey);
}
return eStatus;
}
MOS_STATUS MosUtilities::MosUserFeatureReadValueBinary(
void *UFKey,
PMOS_USER_FEATURE_VALUE pFeatureValue)
{
MOS_STATUS eStatus;
void *pvData;
uint32_t dwUFSize;
MOS_OS_ASSERT(UFKey);
MOS_OS_ASSERT(pFeatureValue);
MOS_OS_ASSERT(pFeatureValue->pValueName);
MOS_OS_ASSERT(pFeatureValue->ValueType == MOS_USER_FEATURE_VALUE_TYPE_BINARY);
pvData = pFeatureValue->Value.BinaryData.pBinaryData;
if (!pvData)
{
MOS_OS_ASSERTMESSAGE("pFeatureValue->BinaryData.pBinaryData is NULL.");
return MOS_STATUS_NULL_POINTER;
}
dwUFSize = pFeatureValue->Value.BinaryData.uMaxSize;
if (dwUFSize == 0)
{
MOS_OS_ASSERTMESSAGE("pFeatureValue->BinaryData.uMaxSize is 0.");
return MOS_STATUS_UNKNOWN;
}
eStatus = MosUserFeatureGetValue(
UFKey,
nullptr,
pFeatureValue->pValueName,
RRF_RT_UF_BINARY,
nullptr,
pvData,
&dwUFSize);
if (eStatus != MOS_STATUS_SUCCESS)
{
if (dwUFSize > pFeatureValue->Value.BinaryData.uMaxSize) // Buffer size is not enough
{
MOS_OS_NORMALMESSAGE("Size %d exceeds max %d.", dwUFSize, pFeatureValue->Value.BinaryData.uMaxSize);
return MOS_STATUS_UNKNOWN;
}
else // This error case can be hit if the user feature key does not exist.
{
MOS_OS_NORMALMESSAGE("Failed to read binary user feature value '%s'.", pFeatureValue->pValueName);
return MOS_STATUS_USER_FEATURE_KEY_READ_FAILED;
}
}
pFeatureValue->Value.BinaryData.uSize = dwUFSize;
return MOS_STATUS_SUCCESS;
}
MOS_STATUS MosUtilities::MosUserFeatureReadValueString(
void *UFKey,
PMOS_USER_FEATURE_VALUE pFeatureValue)
{
MOS_STATUS eStatus;
uint32_t dwUFSize;
char pcTmpStr[MOS_USER_CONTROL_MAX_DATA_SIZE];
//--------------------------------------------------
MOS_OS_ASSERT(UFKey);
MOS_OS_ASSERT(pFeatureValue);
MOS_OS_ASSERT(pFeatureValue->pValueName);
MOS_OS_ASSERT(pFeatureValue->ValueType == MOS_USER_FEATURE_VALUE_TYPE_STRING);
//--------------------------------------------------
MosZeroMemory(pcTmpStr, MOS_USER_CONTROL_MAX_DATA_SIZE);
dwUFSize = pFeatureValue->Value.StringData.uMaxSize;
if (dwUFSize == 0)
{
MOS_OS_ASSERTMESSAGE("pFeatureValue->StringData.uMaxSize is 0.");
return MOS_STATUS_UNKNOWN;
}
eStatus = MosUserFeatureGetValue(
UFKey,
nullptr,
pFeatureValue->pValueName,
RRF_RT_UF_SZ,
nullptr,
pcTmpStr,
&dwUFSize);
if (eStatus != MOS_STATUS_SUCCESS)
{
if (dwUFSize > pFeatureValue->Value.StringData.uMaxSize) // Buffer size is not enough
{
MOS_OS_NORMALMESSAGE("Size %d exceeds max %d.", dwUFSize, pFeatureValue->Value.StringData.uMaxSize);
return MOS_STATUS_UNKNOWN;
}
else // This error case can be hit if the user feature key does not exist.
{
MOS_OS_NORMALMESSAGE("Failed to read single string user feature value '%s'.", pFeatureValue->pValueName);
return MOS_STATUS_USER_FEATURE_KEY_READ_FAILED;
}
}
if (strlen(pcTmpStr) > 0)
{
if (!pFeatureValue->Value.StringData.pStringData)
{
m_mosMemAllocFakeCounter++;
}
if (pFeatureValue->Value.StringData.uSize < strlen(pcTmpStr) + 1)
{
pFeatureValue->Value.StringData.pStringData =
(char *)MOS_ReallocMemory(pFeatureValue->Value.StringData.pStringData, strlen(pcTmpStr) + 1);
pFeatureValue->Value.StringData.uSize = strlen(pcTmpStr) + 1;
}
MOS_OS_CHK_NULL_RETURN(pFeatureValue->Value.StringData.pStringData);
MosZeroMemory(pFeatureValue->Value.StringData.pStringData, pFeatureValue->Value.StringData.uSize);
MosSecureMemcpy(pFeatureValue->Value.StringData.pStringData, pFeatureValue->Value.StringData.uSize, pcTmpStr, strlen(pcTmpStr));
}
return eStatus;
}
MOS_STATUS MosUtilities::MosUserFeatureReadValueMultiString(
void *UFKey,
PMOS_USER_FEATURE_VALUE pFeatureValue)
{
MOS_STATUS eStatus;
uint32_t dwUFSize;
char pcTmpStr[MOS_USER_CONTROL_MAX_DATA_SIZE];
MOS_OS_ASSERT(UFKey);
MOS_OS_ASSERT(pFeatureValue);
MOS_OS_ASSERT(pFeatureValue->pValueName);
MOS_OS_ASSERT(pFeatureValue->ValueType == MOS_USER_FEATURE_VALUE_TYPE_MULTI_STRING);
if (!pFeatureValue->Value.MultiStringData.pStrings)
{
MOS_OS_ASSERTMESSAGE("pFeatureValue->MultiStringData.pStrings is NULL.");
return MOS_STATUS_NULL_POINTER;
}
MosZeroMemory(pcTmpStr, MOS_USER_CONTROL_MAX_DATA_SIZE);
dwUFSize = pFeatureValue->Value.MultiStringData.uMaxSize;
if (dwUFSize == 0)
{
MOS_OS_ASSERTMESSAGE("pFeatureValue->MultiStringData.uMaxSize is 0.");
return MOS_STATUS_UNKNOWN;
}
eStatus = MosUserFeatureGetValue(
UFKey,
nullptr,
pFeatureValue->pValueName,
RRF_RT_UF_MULTI_SZ,
nullptr,
pcTmpStr,
&dwUFSize);
if (eStatus != MOS_STATUS_SUCCESS)
{
if (dwUFSize > pFeatureValue->Value.MultiStringData.uMaxSize) // Buffer size is not enough
{
MOS_OS_NORMALMESSAGE("Size %d exceeds max %d.", dwUFSize, pFeatureValue->Value.MultiStringData.uMaxSize);
return MOS_STATUS_UNKNOWN;
}
else // This error case can be hit if the user feature key does not exist.
{
MOS_OS_NORMALMESSAGE("Failed to read single string user feature value '%s'.", pFeatureValue->pValueName);
return MOS_STATUS_USER_FEATURE_KEY_READ_FAILED;
}
}
if (strlen(pcTmpStr) > 0)
{
MOS_SafeFreeMemory(pFeatureValue->Value.MultiStringData.pMultStringData);
pFeatureValue->Value.MultiStringData.pMultStringData = (char *)MOS_AllocAndZeroMemory(strlen(pcTmpStr) + 1);
m_mosMemAllocFakeCounter++;
if (pFeatureValue->Value.MultiStringData.pMultStringData == nullptr)
{
MOS_OS_ASSERTMESSAGE("Failed to allocate memory.");
return MOS_STATUS_NULL_POINTER;
}
MosSecureMemcpy(
pFeatureValue->Value.MultiStringData.pMultStringData,
strlen(pcTmpStr),
pcTmpStr,
strlen(pcTmpStr));
if((eStatus = MosUserFeatureSetMultiStringValue(
&pFeatureValue->Value,
dwUFSize)) != MOS_STATUS_SUCCESS)
{
MOS_OS_ASSERTMESSAGE("Failed to set multi string value.");
return eStatus;
}
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS MosUtilities::MosUserFeatureReadValuePrimitive(
void *UFKey,
PMOS_USER_FEATURE_VALUE pFeatureValue)
{
MOS_STATUS eStatus;
uint32_t dwUFType = 0;
uint32_t dwUFSize;
void *pvData = nullptr;
MOS_OS_ASSERT(UFKey);
MOS_OS_ASSERT(pFeatureValue);
MOS_OS_ASSERT(pFeatureValue->pValueName);
MOS_OS_ASSERT(pFeatureValue->ValueType != MOS_USER_FEATURE_VALUE_TYPE_INVALID);
switch(pFeatureValue->ValueType)
{
case MOS_USER_FEATURE_VALUE_TYPE_BOOL:
case MOS_USER_FEATURE_VALUE_TYPE_INT32:
case MOS_USER_FEATURE_VALUE_TYPE_UINT32:
case MOS_USER_FEATURE_VALUE_TYPE_FLOAT:
dwUFType = RRF_RT_UF_DWORD;
dwUFSize = sizeof(uint32_t);
pvData = &pFeatureValue->Value.fData;
break;
case MOS_USER_FEATURE_VALUE_TYPE_INT64:
case MOS_USER_FEATURE_VALUE_TYPE_UINT64:
dwUFType = RRF_RT_UF_QWORD;
dwUFSize = sizeof(uint64_t);
pvData = &pFeatureValue->Value.u64Data;
break;
default:
MOS_OS_ASSERTMESSAGE("Invalid primitive value type.");
return MOS_STATUS_UNKNOWN;
}
eStatus = MosUserFeatureGetValue(
UFKey,
nullptr,
pFeatureValue->pValueName,
dwUFType,
nullptr,
pvData,
&dwUFSize);
if (eStatus != MOS_STATUS_SUCCESS)
{
// This error case can be hit if the user feature key does not exist.
MOS_OS_NORMALMESSAGE("Failed to read primitive user feature value \"%s\".", pFeatureValue->pValueName);
return MOS_STATUS_USER_FEATURE_KEY_READ_FAILED;
}
return eStatus;
}
MOS_STATUS MosUtilities::MosUserFeatureWriteValueString(
void *UFKey,
PMOS_USER_FEATURE_VALUE pFeatureValue,
PMOS_USER_FEATURE_VALUE_DATA pDataValue)
{
MOS_STATUS eStatus;
MOS_OS_ASSERT(UFKey);
MOS_OS_ASSERT(pFeatureValue);
MOS_OS_ASSERT(pFeatureValue->pValueName);
MOS_OS_ASSERT(pFeatureValue->ValueType == MOS_USER_FEATURE_VALUE_TYPE_STRING);
MOS_OS_ASSERT(pDataValue);
if((eStatus = MosUserFeatureSetValueEx(
UFKey,
pFeatureValue->pValueName,
0,
UF_SZ,
(uint8_t*)pDataValue->StringData.pStringData,
pDataValue->StringData.uSize)) != MOS_STATUS_SUCCESS)
{
MOS_OS_ASSERTMESSAGE("Failed to write string user feature value.");
}
return eStatus;
}
MOS_STATUS MosUtilities::MosUserFeatureWriteValueMultiString(
void *UFKey,
PMOS_USER_FEATURE_VALUE pFeatureValue,
PMOS_USER_FEATURE_VALUE_DATA pDataValue)
{
PMOS_USER_FEATURE_VALUE_STRING pStringData;
uint8_t *pData;
uint8_t *pCurData;
uint32_t dwDataSize;
uint32_t dwAvailableSize;
uint32_t ui;
MOS_STATUS eStatus;
MOS_OS_ASSERT(UFKey);
MOS_OS_ASSERT(pFeatureValue);
MOS_OS_ASSERT(pFeatureValue->pValueName);
MOS_OS_ASSERT(pFeatureValue->ValueType == MOS_USER_FEATURE_VALUE_TYPE_MULTI_STRING);
MOS_OS_ASSERT(pDataValue);
MOS_OS_ASSERT(pDataValue->MultiStringData.uCount > 0);
pData = nullptr;
dwDataSize = 0;
for (ui = 0; ui < pDataValue->MultiStringData.uCount; ui++)
{
pStringData = &pDataValue->MultiStringData.pStrings[ui];
dwDataSize += pStringData->uSize;
dwDataSize += 1; // for \0
}
dwDataSize += 1; // for \0 at the very end (see MULTI_SZ spec)
// Allocate memory to store data
pData = (uint8_t*)MOS_AllocAndZeroMemory(dwDataSize);
if(pData == nullptr)
{
MOS_OS_ASSERTMESSAGE("Failed to allocate memory.");
return MOS_STATUS_NO_SPACE;
}
// Copy data from original string array
pCurData = pData;
dwAvailableSize = dwDataSize;
for (ui = 0; ui < pDataValue->MultiStringData.uCount; ui++)
{
pStringData = &pDataValue->MultiStringData.pStrings[ui];
eStatus = MosSecureMemcpy(pCurData, dwAvailableSize, pStringData->pStringData, pStringData->uSize);
if(eStatus != MOS_STATUS_SUCCESS)
{
MOS_OS_ASSERTMESSAGE("Failed to copy memory.");
goto finish;
}
pCurData += pStringData->uSize;
pCurData++; // \0 is already added since we zeroed the memory
// Very last \0 is already added since we zeroed the memory
dwAvailableSize -= pStringData->uSize + 1;
}
// Write the user feature MULTI_SZ entry
if((eStatus = MosUserFeatureSetValueEx(
UFKey,
pFeatureValue->pValueName,
0,
UF_MULTI_SZ,
pData,
dwDataSize)) != MOS_STATUS_SUCCESS)
{
MOS_OS_ASSERTMESSAGE("Failed to write multi string user feature value.");
}
finish:
MOS_FreeMemory(pData);
return eStatus;
}
MOS_STATUS MosUtilities::MosUserFeatureWriteValueBinary(
void *UFKey,
PMOS_USER_FEATURE_VALUE pFeatureValue,
PMOS_USER_FEATURE_VALUE_DATA pDataValue)
{
MOS_STATUS eStatus;
MOS_OS_ASSERT(UFKey);
MOS_OS_ASSERT(pFeatureValue);
MOS_OS_ASSERT(pFeatureValue->pValueName);
MOS_OS_ASSERT(pFeatureValue->ValueType == MOS_USER_FEATURE_VALUE_TYPE_BINARY);
MOS_OS_ASSERT(pDataValue);
if((eStatus = MosUserFeatureSetValueEx(
UFKey,
pFeatureValue->pValueName,
0,
UF_BINARY,
(uint8_t*)pDataValue->BinaryData.pBinaryData,
pDataValue->BinaryData.uSize)) != MOS_STATUS_SUCCESS)
{
MOS_OS_ASSERTMESSAGE("Failed to write binary user feature value.");
}
return eStatus;
}
MOS_STATUS MosUtilities::MosUserFeatureWriteValuePrimitive(
void *UFKey,
PMOS_USER_FEATURE_VALUE pFeatureValue,
PMOS_USER_FEATURE_VALUE_DATA pDataValue)
{
MOS_STATUS eStatus;
uint32_t dwUFType = UF_NONE;
uint32_t dwUFSize = 0;
void *pvData = nullptr;
MOS_OS_ASSERT(UFKey);
MOS_OS_ASSERT(pFeatureValue);
MOS_OS_ASSERT(pFeatureValue->pValueName);
MOS_OS_ASSERT(pFeatureValue->ValueType != MOS_USER_FEATURE_VALUE_TYPE_INVALID);
MOS_OS_ASSERT(pDataValue);
switch(pFeatureValue->ValueType)
{
case MOS_USER_FEATURE_VALUE_TYPE_BOOL:
case MOS_USER_FEATURE_VALUE_TYPE_INT32:
case MOS_USER_FEATURE_VALUE_TYPE_UINT32:
case MOS_USER_FEATURE_VALUE_TYPE_FLOAT:
dwUFType = UF_DWORD;
dwUFSize = sizeof(uint32_t);
pvData = &pDataValue->fData;
break;
case MOS_USER_FEATURE_VALUE_TYPE_INT64:
case MOS_USER_FEATURE_VALUE_TYPE_UINT64:
dwUFType = UF_QWORD;
dwUFSize = sizeof(uint64_t);
pvData = &pDataValue->u64Data;
break;
default:
MOS_OS_ASSERTMESSAGE("Invalid primitive value type.");
return MOS_STATUS_UNKNOWN;
}
if((eStatus = MosUserFeatureSetValueEx(
UFKey,
pFeatureValue->pValueName,
0,
dwUFType,
(uint8_t*)pvData,
dwUFSize)) != MOS_STATUS_SUCCESS)
{
MOS_OS_ASSERTMESSAGE("Failed to write primitive user feature value.");
}
return eStatus;
}
MOS_STATUS MosUtilities::MosUserFeatureReadValueFromMapID(
uint32_t ValueID,
PMOS_USER_FEATURE_VALUE_DATA pValueData,
MOS_USER_FEATURE_KEY_PATH_INFO *ufInfo)
{
void *ufKey = nullptr;
PMOS_USER_FEATURE_VALUE pUserFeature = nullptr;
int32_t iDataFlag = MOS_USER_FEATURE_VALUE_DATA_FLAG_NONE_CUSTOM_DEFAULT_VALUE_TYPE;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
//--------------------------------------------------
MOS_OS_ASSERT(pValueData);
MOS_OS_ASSERT(ValueID != __MOS_USER_FEATURE_KEY_INVALID_ID);
//--------------------------------------------------
iDataFlag = pValueData->i32DataFlag;
pUserFeature = MosUtilUserInterface::GetValue(ValueID);
if (nullptr == pUserFeature)
{
MOS_OS_NORMALMESSAGE("Cannot found the user feature key.");
return MOS_STATUS_NULL_POINTER;
}
// Open the user feature
// Assigned the pUserFeature to ufKey for future reading
ufKey = pUserFeature;
if((eStatus = MosUserFeatureOpen(
pUserFeature->Type,
pUserFeature->pcPath,
KEY_READ,
&ufKey,
ufInfo)) != MOS_STATUS_SUCCESS)
{
MOS_OS_NORMALMESSAGE("Failed to open user feature for reading eStatus:%d.", eStatus);
eStatus = MOS_STATUS_USER_FEATURE_KEY_OPEN_FAILED;
goto finish;
}
// Initialize Read Value
if((eStatus = MosUserFeatureReadValueInit(pUserFeature->uiNumOfValues)) != MOS_STATUS_SUCCESS)
{
MOS_OS_ASSERTMESSAGE("Failed to initialize user feature read value eStatus:%d.",eStatus);
eStatus = MOS_STATUS_UNKNOWN;
goto finish;
}
#if !(_DEBUG || _RELEASE_INTERNAL)
// For release build, don't read debug only keys, but return default directly
if (pUserFeature->EffctiveRange == MOS_USER_FEATURE_EFFECT_DEBUGONLY)
{
eStatus = MOS_STATUS_USER_FEATURE_KEY_READ_FAILED;
goto finish;
}
#endif
// Read the Values from user feature
switch(pUserFeature->ValueType)
{
case MOS_USER_FEATURE_VALUE_TYPE_BINARY:
eStatus = MosUserFeatureReadValueBinary(ufKey, pUserFeature);
break;
case MOS_USER_FEATURE_VALUE_TYPE_STRING:
eStatus = MosUserFeatureReadValueString(ufKey, pUserFeature);
break;
case MOS_USER_FEATURE_VALUE_TYPE_MULTI_STRING:
eStatus = MosUserFeatureReadValueMultiString(ufKey, pUserFeature);
break;
default:
eStatus = MosUserFeatureReadValuePrimitive(ufKey, pUserFeature);
break;
}
if(eStatus != MOS_STATUS_SUCCESS)
{
MOS_OS_NORMALMESSAGE("Failed to read value from user feature eStatus:%d.", eStatus);
eStatus = MOS_STATUS_USER_FEATURE_KEY_READ_FAILED;
}
finish:
if ((pUserFeature != nullptr) &&
((eStatus == MOS_STATUS_SUCCESS) ||
(iDataFlag != MOS_USER_FEATURE_VALUE_DATA_FLAG_CUSTOM_DEFAULT_VALUE_TYPE)))
{
// Use the User Feature Value or default value in corresponding user feature key Desc Fields
// when User Feature Key read successfully or no input custom default value
MosCopyUserFeatureValueData(
&pUserFeature->Value,
pValueData,
pUserFeature->ValueType);
}
MosUserFeatureCloseKey(ufKey); // Closes the key if not nullptr
return eStatus;
}
MOS_STATUS MosUtilities::MosUserFeatureReadValueID(
PMOS_USER_FEATURE_INTERFACE pOsUserFeatureInterface,
uint32_t ValueID,
PMOS_USER_FEATURE_VALUE_DATA pValueData,
MOS_CONTEXT_HANDLE mosCtx)
{
MOS_USER_FEATURE_KEY_PATH_INFO *ufInfo = Mos_GetDeviceUfPathInfo((PMOS_CONTEXT)mosCtx);
return MosUserFeatureReadValueFromMapID(
ValueID,
pValueData,
ufInfo);
}
MOS_STATUS MosUtilities::MosUserFeatureReadValueID(
PMOS_USER_FEATURE_INTERFACE pOsUserFeatureInterface,
uint32_t ValueID,
PMOS_USER_FEATURE_VALUE_DATA pValueData,
MOS_USER_FEATURE_KEY_PATH_INFO *ufInfo)
{
return MosUserFeatureReadValueFromMapID(
ValueID,
pValueData,
ufInfo);
}
const char* MosUtilities::MosUserFeatureLookupValueName(uint32_t ValueID)
{
MOS_OS_ASSERT(ValueID != __MOS_USER_FEATURE_KEY_INVALID_ID);
PMOS_USER_FEATURE_VALUE pUserFeature = MosUtilUserInterface::GetValue(ValueID);
if (pUserFeature)
{
return pUserFeature->pValueName;
}
else
{
return nullptr;
}
}
const char *MosUtilities::MosUserFeatureLookupReadPath(uint32_t ValueID)
{
MOS_OS_ASSERT(ValueID != __MOS_USER_FEATURE_KEY_INVALID_ID);
PMOS_USER_FEATURE_VALUE pUserFeature = MosUtilUserInterface::GetValue(ValueID);
if (pUserFeature)
{
return pUserFeature->pcPath;
}
else
{
return nullptr;
}
}
const char *MosUtilities::MosUserFeatureLookupWritePath(uint32_t ValueID)
{
MOS_OS_ASSERT(ValueID != __MOS_USER_FEATURE_KEY_INVALID_ID);
PMOS_USER_FEATURE_VALUE pUserFeature = MosUtilUserInterface::GetValue(ValueID);
if (pUserFeature)
{
return pUserFeature->pcWritePath;
}
else
{
return nullptr;
}
}
MOS_STATUS MosUtilities::MosUserFeatureWriteValuesTblID(
PMOS_USER_FEATURE_VALUE_WRITE_DATA pWriteValues,
uint32_t uiNumOfValues,
MOS_USER_FEATURE_KEY_PATH_INFO *ufInfo)
{
uint32_t ui;
PMOS_USER_FEATURE_VALUE pFeatureValue = nullptr;
void *UFKey = nullptr;
PMOS_USER_FEATURE_VALUE_WRITE_DATA pUserWriteData = nullptr;
PMOS_USER_FEATURE_VALUE pUserFeature = nullptr;
uint32_t ValueID = __MOS_USER_FEATURE_KEY_INVALID_ID;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
char WritePathWithPID[MAX_PATH];
int32_t pid;
uint64_t ulTraceData = 0;
bool isValid = false;
//--------------------------------------------------
MOS_OS_CHK_NULL_RETURN(pWriteValues);
//--------------------------------------------------
MosZeroMemory(WritePathWithPID, MAX_PATH);
pid = MosGetPid();
for (ui = 0; ui < uiNumOfValues; ui++)
{
ValueID = pWriteValues[ui].ValueID;
pUserFeature = MosUtilUserInterface::GetValue(ValueID);
MOS_OS_CHK_NULL_RETURN(pUserFeature);
// Open the user feature
// Assigned the pUserFeature to UFKey for future reading
UFKey = pUserFeature;
//append write path with pid
sprintf_s(WritePathWithPID, MAX_PATH, "%s\\%d", pUserFeature->pcWritePath, pid);
// Trace data in case opening user feature for write fails
switch (pUserFeature->ValueType)
{
case MOS_USER_FEATURE_VALUE_TYPE_BOOL:
case MOS_USER_FEATURE_VALUE_TYPE_INT32:
case MOS_USER_FEATURE_VALUE_TYPE_UINT32:
case MOS_USER_FEATURE_VALUE_TYPE_FLOAT:
ulTraceData = pWriteValues[ui].Value.u32Data;
isValid = true;
break;
case MOS_USER_FEATURE_VALUE_TYPE_INT64:
case MOS_USER_FEATURE_VALUE_TYPE_UINT64:
ulTraceData = pWriteValues[ui].Value.u64Data;
isValid = true;
break;
default:
MOS_OS_NORMALMESSAGE("Unknown value type %d", pUserFeature->ValueType);
}
if (isValid)
{
MosTraceDataDictionary(pUserFeature->pValueName, &ulTraceData, sizeof(ulTraceData));
}
//try to open Write path with pid first
if ((eStatus = MosUserFeatureOpen(
pUserFeature->Type,
WritePathWithPID,
KEY_WRITE,
&UFKey,
ufInfo)) != MOS_STATUS_SUCCESS)
{
MOS_OS_NORMALMESSAGE("Failed to open user feature for concurrency.");
if ((eStatus = MosUserFeatureOpen(
pUserFeature->Type,
pUserFeature->pcWritePath,
KEY_WRITE,
&UFKey,
ufInfo)) != MOS_STATUS_SUCCESS)
{
MOS_OS_NORMALMESSAGE("Failed to open user feature for writing.");
eStatus = MOS_STATUS_USER_FEATURE_KEY_OPEN_FAILED;
goto finish;
}
}
//------------------------------------
MOS_OS_ASSERT(pUserFeature->ValueType != MOS_USER_FEATURE_VALUE_TYPE_INVALID);
//------------------------------------
switch(pUserFeature->ValueType)
{
case MOS_USER_FEATURE_VALUE_TYPE_BINARY:
if ((eStatus = MosUserFeatureWriteValueBinary(UFKey, pUserFeature, &(pWriteValues[ui].Value))) != MOS_STATUS_SUCCESS)
{
MOS_OS_ASSERTMESSAGE("Failed to write binary value to user feature.");
eStatus = MOS_STATUS_USER_FEATURE_KEY_WRITE_FAILED;
goto finish;
}
break;
case MOS_USER_FEATURE_VALUE_TYPE_STRING:
if ((eStatus = MosUserFeatureWriteValueString(UFKey, pUserFeature, &(pWriteValues[ui].Value))) != MOS_STATUS_SUCCESS)
{
MOS_OS_ASSERTMESSAGE("Failed to write string value to user feature.");
eStatus = MOS_STATUS_USER_FEATURE_KEY_WRITE_FAILED;
goto finish;
}
break;
case MOS_USER_FEATURE_VALUE_TYPE_MULTI_STRING:
if ((eStatus = MosUserFeatureWriteValueMultiString(UFKey, pUserFeature, &(pWriteValues[ui].Value))) != MOS_STATUS_SUCCESS)
{
MOS_OS_ASSERTMESSAGE("Failed to write multi string value to user feature.");
eStatus = MOS_STATUS_USER_FEATURE_KEY_WRITE_FAILED;
goto finish;
}
break;
default:
if ((eStatus = MosUserFeatureWriteValuePrimitive(UFKey, pUserFeature, &(pWriteValues[ui].Value))) != MOS_STATUS_SUCCESS)
{
MOS_OS_ASSERTMESSAGE("Failed to write primitive data value to user feature.");
eStatus = MOS_STATUS_USER_FEATURE_KEY_WRITE_FAILED;
goto finish;
}
}
MosUserFeatureCloseKey(UFKey); // Closes the key if not nullptr
}
finish:
if (eStatus != MOS_STATUS_SUCCESS)
{
MosUserFeatureCloseKey(UFKey); // Closes the key if not nullptr
}
return eStatus;
}
MOS_STATUS MosUtilities::MosUserFeatureWriteValuesID(
PMOS_USER_FEATURE_INTERFACE pOsUserFeatureInterface,
PMOS_USER_FEATURE_VALUE_WRITE_DATA pWriteValues,
uint32_t uiNumOfValues,
MOS_CONTEXT_HANDLE mosCtx)
{
MOS_USER_FEATURE_KEY_PATH_INFO *ufInfo = Mos_GetDeviceUfPathInfo((PMOS_CONTEXT)mosCtx);
return MosUserFeatureWriteValuesTblID(
pWriteValues,
uiNumOfValues,
ufInfo);
}
MOS_STATUS MosUtilities::MosUserFeatureWriteValuesID(
PMOS_USER_FEATURE_INTERFACE pOsUserFeatureInterface,
PMOS_USER_FEATURE_VALUE_WRITE_DATA pWriteValues,
uint32_t uiNumOfValues,
MOS_USER_FEATURE_KEY_PATH_INFO * ufInfo)
{
return MosUserFeatureWriteValuesTblID(
pWriteValues,
uiNumOfValues,
ufInfo);
}
MOS_STATUS MosUtilities::MosUserFeatureEnableNotification(
PMOS_USER_FEATURE_INTERFACE pOsUserFeatureInterface,
PMOS_USER_FEATURE_NOTIFY_DATA pNotification,
MOS_CONTEXT_HANDLE mosCtx)
{
PMOS_USER_FEATURE_NOTIFY_DATA_COMMON pNotifyCommon;
int32_t bResult;
MOS_STATUS eStatus;
MOS_UNUSED(pOsUserFeatureInterface);
//---------------------------------------
MOS_OS_ASSERT(pNotification);
MOS_OS_ASSERT(pNotification->NotifyType != MOS_USER_FEATURE_NOTIFY_TYPE_INVALID);
MOS_OS_ASSERT(pNotification->pPath);
//---------------------------------------
MOS_USER_FEATURE_KEY_PATH_INFO *ufInfo = Mos_GetDeviceUfPathInfo((PMOS_CONTEXT)mosCtx);
// Reset the triggered flag
pNotification->bTriggered = false;
if (pNotification->pHandle == nullptr)
{
// Allocate private data as well
pNotification->pHandle = MOS_AllocAndZeroMemory(sizeof(MOS_USER_FEATURE_NOTIFY_DATA));
if(pNotification->pHandle == nullptr)
{
MOS_OS_ASSERTMESSAGE("Failed to allocate memory.");
return MOS_STATUS_NO_SPACE;
}
}
pNotifyCommon = (PMOS_USER_FEATURE_NOTIFY_DATA_COMMON)pNotification->pHandle;
// Open User Feature for Reading
if (pNotifyCommon->UFKey == 0)
{
if((eStatus = MosUserFeatureOpen(
pNotification->Type,
pNotification->pPath,
KEY_READ,
&pNotifyCommon->UFKey,
ufInfo)) != MOS_STATUS_SUCCESS)
{
MOS_OS_ASSERTMESSAGE("Failed to open user feature for reading.");
return MOS_STATUS_USER_FEATURE_KEY_OPEN_FAILED;
}
}
// Create Event for notification
if (pNotifyCommon->hEvent == nullptr)
{
pNotifyCommon->hEvent = MosCreateEventEx(
nullptr,
nullptr,
0);
if(pNotifyCommon->hEvent == nullptr)
{
MOS_OS_ASSERTMESSAGE("Failed to allocate memory.");
return MOS_STATUS_NO_SPACE;
}
}
// Unregister wait event if already registered
if (pNotifyCommon->hWaitEvent)
{
if ((bResult = MosUnregisterWaitEx(pNotifyCommon->hWaitEvent)) == false)
{
MOS_OS_ASSERTMESSAGE("Unable to unregiser wait event.");
return MOS_STATUS_EVENT_WAIT_UNREGISTER_FAILED;
}
pNotifyCommon->hWaitEvent = nullptr;
}
// Register a Callback
if((eStatus = MosUserFeatureNotifyChangeKeyValue(
pNotifyCommon->UFKey,
false,
pNotifyCommon->hEvent,
true)) != MOS_STATUS_SUCCESS)
{
MOS_OS_ASSERTMESSAGE("Unable to setup user feature key notification.");
return MOS_STATUS_UNKNOWN;
}
// Create a wait object
if ((bResult = MosUserFeatureWaitForSingleObject(
&pNotifyCommon->hWaitEvent,
pNotifyCommon->hEvent,
(void *)MosUserFeatureCallback,
pNotification)) == false)
{
MOS_OS_ASSERTMESSAGE("Failed to create a wait object.");
return MOS_STATUS_EVENT_WAIT_REGISTER_FAILED;
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS MosUtilities::MosUserFeatureDisableNotification(
PMOS_USER_FEATURE_INTERFACE pOsUserFeatureInterface,
PMOS_USER_FEATURE_NOTIFY_DATA pNotification)
{
PMOS_USER_FEATURE_NOTIFY_DATA_COMMON pNotifyDataCommon;
int32_t bResult;
MOS_STATUS eStatus;
MOS_UNUSED(pOsUserFeatureInterface);
//---------------------------------------
MOS_OS_ASSERT(pNotification);
//---------------------------------------
if (pNotification->pHandle)
{
pNotifyDataCommon = (PMOS_USER_FEATURE_NOTIFY_DATA_COMMON)
pNotification->pHandle;
if (pNotifyDataCommon->hWaitEvent)
{
if ((bResult = MosUnregisterWaitEx(pNotifyDataCommon->hWaitEvent)) == false)
{
MOS_OS_ASSERTMESSAGE("Unable to unregiser wait event.");
return MOS_STATUS_EVENT_WAIT_UNREGISTER_FAILED;
}
}
if (pNotifyDataCommon->UFKey)
{
if ((eStatus = MosUserFeatureCloseKey(pNotifyDataCommon->UFKey)) != MOS_STATUS_SUCCESS)
{
MOS_OS_ASSERTMESSAGE("User feature key close failed.");
return eStatus;
}
}
if (pNotifyDataCommon->hEvent)
{
MosCloseHandle(pNotifyDataCommon->hEvent);
}
// Free Notify Data Memory
MOS_FreeMemory(pNotifyDataCommon);
pNotification->pHandle = nullptr;
}
return MOS_STATUS_SUCCESS;
}
float MosUtilities::MosSinc(float x)
{
return (MOS_ABS(x) < 1e-9f) ? 1.0F : (float)(sin(x) / x);
}
float MosUtilities::MosLanczos(float x, uint32_t dwNumEntries, float fLanczosT)
{
uint32_t dwNumHalfEntries;
dwNumHalfEntries = dwNumEntries >> 1;
if (fLanczosT < dwNumHalfEntries)
{
fLanczosT = (float)dwNumHalfEntries;
}
if (MOS_ABS(x) >= dwNumHalfEntries)
{
return 0.0;
}
x *= MOS_PI;
return MosSinc(x) * MosSinc(x / fLanczosT);
}
float MosUtilities::MosLanczosG(float x, uint32_t dwNumEntries, float fLanczosT)
{
uint32_t dwNumHalfEntries;
dwNumHalfEntries = (dwNumEntries >> 1) + (dwNumEntries & 1);
if (fLanczosT < dwNumHalfEntries)
{
fLanczosT = (float)dwNumHalfEntries;
}
if (x > (dwNumEntries >> 1) || (- x) >= dwNumHalfEntries)
{
return 0.0;
}
x *= MOS_PI;
return MosSinc(x) * MosSinc(x / fLanczosT);
}
uint32_t MosUtilities::MosGCD(uint32_t a, uint32_t b)
{
if (b == 0)
{
return a;
}
else
{
return MosGCD(b, a % b);
}
}
#ifdef _MOS_UTILITY_EXT
#include "mos_utilities_ext_next.h"
#else
#define Mos_SwizzleOffset MosUtilities::MosSwizzleOffset
#endif
__inline int32_t MosUtilities::MosSwizzleOffset(
int32_t OffsetX,
int32_t OffsetY,
int32_t Pitch,
MOS_TILE_TYPE TileFormat,
int32_t CsxSwizzle,
int32_t ExtFlags)
{
// When dealing with a tiled surface, logical linear accesses to the
// surface (y * pitch + x) must be translated into appropriate tile-
// formated accesses--This is done by swizzling (rearranging/translating)
// the given access address--though it is important to note that the
// swizzling is actually done on the accessing OFFSET into a TILED
// REGION--not on the absolute address itself.
// (!) Y-MAJOR TILING, REINTERPRETATION: For our purposes here, Y-Major
// tiling will be thought of in a different way, we will deal with
// the 16-byte-wide columns individually--i.e., we will treat a single
// Y-Major tile as 8 separate, thinner tiles--Doing so allows us to
// deal with both X- and Y-Major tile formats in the same "X-Major"
// way--just with different dimensions: either 512B x 8 rows, or
// 16B x 32 rows, respectively.
// A linear offset into a surface is of the form
// y * pitch + x = y:x (Shorthand, meaning: y * (x's per y) + x)
//
// To treat a surface as being composed of tiles (though still being
// linear), just as a linear offset has a y:x composition--its y and x
// components can be thought of as having Row:Line and Column:X
// compositions, respectively, where Row specifies a row of tiles, Line
// specifies a row of pixels within a tile, Column specifies a column
// of tiles, and X in this context refers to a byte within a Line--i.e.,
// offset = y:x
// y = Row:Line
// x = Col:X
// offset = y:x = Row:Line:Col:X
// Given the Row:Line:Col:X composition of a linear offset, all that
// tile swizzling does is swap the Line and Col components--i.e.,
// Linear Offset: Row:Line:Col:X
// Swizzled Offset: Row:Col:Line:X
// And with our reinterpretation of the Y-Major tiling format, we can now
// describe both the X- and Y-Major tiling formats in two simple terms:
// (1) The bit-depth of their Lines component--LBits, and (2) the
// swizzled bit-position of the Lines component (after it swaps with the
// Col component)--LPos.
int32_t Row, Line, Col, x; // Linear Offset Components
int32_t LBits, LPos; // Size and swizzled position of the Line component.
int32_t SwizzledOffset;
if (TileFormat == MOS_TILE_LINEAR)
{
return(OffsetY * Pitch + OffsetX);
}
if (TileFormat == MOS_TILE_Y)
{
LBits = 5; // Log2(TileY.Height = 32)
LPos = 4; // Log2(TileY.PseudoWidth = 16)
}
else //if (TileFormat == MOS_TILE_X)
{
LBits = 3; // Log2(TileX.Height = 8)
LPos = 9; // Log2(TileX.Width = 512)
}
Row = OffsetY >> LBits; // OffsetY / LinesPerTile
Line = OffsetY & ((1 << LBits) - 1); // OffsetY % LinesPerTile
Col = OffsetX >> LPos; // OffsetX / BytesPerLine
x = OffsetX & ((1 << LPos) - 1); // OffsetX % BytesPerLine
SwizzledOffset =
(((((Row * (Pitch >> LPos)) + Col) << LBits) + Line) << LPos) + x;
// V V V
// / BytesPerLine * LinesPerTile * BytesPerLine
/// Channel Select XOR Swizzling ///////////////////////////////////////////
if (CsxSwizzle)
{
if (TileFormat == MOS_TILE_Y) // A6 = A6 ^ A9
{
SwizzledOffset ^= ((SwizzledOffset >> (9 - 6)) & 0x40);
}
else //if (TileFormat == VPHAL_TILE_X) // A6 = A6 ^ A9 ^ A10
{
SwizzledOffset ^= (((SwizzledOffset >> (9 - 6)) ^ (SwizzledOffset >> (10 - 6))) & 0x40);
}
}
return(SwizzledOffset);
}
void MosUtilities::MosSwizzleData(
uint8_t *pSrc,
uint8_t *pDst,
MOS_TILE_TYPE SrcTiling,
MOS_TILE_TYPE DstTiling,
int32_t iHeight,
int32_t iPitch,
int32_t extFlags)
{
#define IS_TILED(_a) ((_a) != MOS_TILE_LINEAR)
#define IS_TILED_TO_LINEAR(_a, _b) (IS_TILED(_a) && !IS_TILED(_b))
#define IS_LINEAR_TO_TILED(_a, _b) (!IS_TILED(_a) && IS_TILED(_b))
int32_t LinearOffset;
int32_t TileOffset;
int32_t x;
int32_t y;
// Translate from one format to another
for (y = 0, LinearOffset = 0, TileOffset = 0; y < iHeight; y++)
{
for (x = 0; x < iPitch; x++, LinearOffset++)
{
// x or y --> linear
if (IS_TILED_TO_LINEAR(SrcTiling, DstTiling))
{
TileOffset = Mos_SwizzleOffset(
x,
y,
iPitch,
SrcTiling,
false,
extFlags);
*(pDst + LinearOffset) = *(pSrc + TileOffset);
}
// linear --> x or y
else if (IS_LINEAR_TO_TILED(SrcTiling, DstTiling))
{
TileOffset = Mos_SwizzleOffset(
x,
y,
iPitch,
DstTiling,
false,
extFlags);
*(pDst + TileOffset) = *(pSrc + LinearOffset);
}
else
{
MOS_OS_ASSERT(0);
}
}
}
}