From 3dfe2108cfab31ba3ee5527e217d0d8e99a51162 Mon Sep 17 00:00:00 2001 From: git perforce import user Date: Tue, 25 Oct 2016 12:29:14 -0600 Subject: Initial commit: PhysX 3.4.0 Update @ 21294896 APEX 1.4.0 Update @ 21275617 [CL 21300167] --- APEX_1.4/shared/external/src/UserErrorCallback.cpp | 367 +++++++++++++++++++++ 1 file changed, 367 insertions(+) create mode 100644 APEX_1.4/shared/external/src/UserErrorCallback.cpp (limited to 'APEX_1.4/shared/external/src/UserErrorCallback.cpp') diff --git a/APEX_1.4/shared/external/src/UserErrorCallback.cpp b/APEX_1.4/shared/external/src/UserErrorCallback.cpp new file mode 100644 index 00000000..9cccd073 --- /dev/null +++ b/APEX_1.4/shared/external/src/UserErrorCallback.cpp @@ -0,0 +1,367 @@ +/* + * Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. + * + * NVIDIA CORPORATION and its licensors retain all intellectual property + * and proprietary rights in and to this software, related documentation + * and any modifications thereto. Any use, reproduction, disclosure or + * distribution of this software and related documentation without an express + * license agreement from NVIDIA CORPORATION is strictly prohibited. + */ + + +#include "ApexDefs.h" +#include "UserErrorCallback.h" +#include "PxAssert.h" +#include + +#if PX_WINDOWS_FAMILY +#define NOMINMAX +#include +#include +#include +#endif + +#if PX_X360 +#include +#include +#endif + +UserErrorCallback* UserErrorCallback::s_instance /* = NULL */; + +UserErrorCallback::UserErrorCallback(const char* filename, const char* mode, bool header, bool reportErrors) + : mNumErrors(0) + , mOutFile(NULL) + , mOutFileName(filename == NULL ? "" : filename) + , mOutFileMode(mode) + , mOutFileHeader(header) + , mReportErrors(reportErrors) +{ + mFirstErrorBuffer[0] = '\0'; + mFirstErrorBufferUpdated = false; + if (!s_instance) + { + s_instance = this; + } + else if (s_instance->mOutFileName.empty()) + { + // replace stub error handler + delete s_instance; + s_instance = this; + } + + // initialize the filtered messages. + //mFilteredMessages.insert(""); + addFilteredMessage("CUDA not available", true); + addFilteredMessage("CUDA is not available", true); + + // filter particle debug visualization warnings from PhysX when APEX is using GPU particles in device exclusive mode + // the message was changed in 3.3, so adding both + addFilteredMessage("Operation not allowed in device exclusive mode", true); + addFilteredMessage("Receiving particles through host interface not supported device exclusive mode", true); + + + // Filter out a harmless particle warning from PhysX 3.2.4 + addFilteredMessage("Adding particles before the first simulation step is not supported.", true); +} + +const char* sanitizeFileName(const char* fullPath) +{ + return std::max(::strrchr(fullPath, '\\'), ::strrchr(fullPath, '/')) + 1; +} + +bool UserErrorCallback::messageFiltered(const char * code, const char * msg) +{ + if (0 == strcmp(code, "info")) + { + return true; + } + + std::map::iterator found = mFilteredMessages.find(msg); + if (found != mFilteredMessages.end()) + { + if (found->second != NULL) + { + // set the trigger + *(found->second) = true; + } + return true; + } + + for (size_t i = 0; i < mFilteredParts.size(); i++) + { + const char* fmsg = mFilteredParts[i].first.c_str(); + if (strstr(msg, fmsg) != NULL) + { + if (mFilteredParts[i].second != NULL) + { + // set the trigger + *(mFilteredParts[i].second) = true; + } + return true; + } + } + + return false; +} + +#if PX_WINDOWS_FAMILY + +void logf(FILE* file, const char* format, ...) +{ + // size = 2047 from SampleApexApplication::printMessageUser() + // '\n' appended by UserErrorCallback::printError() + // '\0' appended by vsnprintf() + enum { BUFFER_SIZE = 2049 }; + char buffer[BUFFER_SIZE]; + + va_list args; + va_start(args, format); + vsnprintf(buffer, sizeof(buffer), format, args); + va_end(args); + + // Output to file + fputs(buffer, file); + + // Output to debug stream + ::OutputDebugString(buffer); +} + +#else + +#define logf(file, format, ...) fprintf(file, format, __VA_ARGS__) + +#endif /* PX_WINDOWS_FAMILY */ + +void UserErrorCallback::printError(const char* message, const char* errorCode, const char* file, int line) +{ + if (mOutFile == NULL) + { + openFile(); + } + + // do not count eDEBUG_INFO "info" messages as errors. + // errors trigger benchmarks to be exited. + if (!messageFiltered(errorCode, message)) + { + mNumErrors++; + } + + // if this is the first error while running a benchmark + if (mNumErrors == 1 && !mFirstErrorBufferUpdated) + { + if (errorCode) + { + strcpy(mFirstErrorBuffer, errorCode); + strcat(mFirstErrorBuffer, ": "); + } + if (file) + { + char lineNumBuf[20]; + strcat(mFirstErrorBuffer, sanitizeFileName(file)); + strcat(mFirstErrorBuffer, ":"); + sprintf(lineNumBuf, "%d: ", line); + strcat(mFirstErrorBuffer, lineNumBuf); + } + if (message) + { + strcat(mFirstErrorBuffer, message); + strcat(mFirstErrorBuffer, "\n"); + } + mFirstErrorBufferUpdated = true; + } + + if (mOutFile == NULL) + { + return; + } + + if (errorCode != NULL) + { + logf(mOutFile, "\n%s: ", errorCode); + } + + if (file != NULL) + { + logf(mOutFile, "%s:%d:\n", sanitizeFileName(file), line); + } + + if (message != NULL) + { + logf(mOutFile, "%s\n", message); + } + + fflush(mOutFile); +} + +int UserErrorCallback::getNumErrors(void) +{ + return((int)mNumErrors); +} + +void UserErrorCallback::clearErrorCounter(void) +{ + mNumErrors = 0; + mFirstErrorBuffer[0] = '\0'; +} + +const char* UserErrorCallback::getFirstEror(void) +{ + return(mFirstErrorBuffer); +} + +void UserErrorCallback::addFilteredMessage(const char* msg, bool fullMatch, bool* trigger) +{ + if (fullMatch) + { + mFilteredMessages.insert(std::pair(msg, trigger)); + } + else + { + mFilteredParts.push_back(std::pair(msg, trigger)); + } +} + + + +void UserErrorCallback::reportErrors(bool enabled) +{ + PX_UNUSED(enabled); + mReportErrors = false; +} + + + +void UserErrorCallback::reportError(physx::PxErrorCode::Enum e, const char* message, const char* file, int line) +{ + const char* errorCode = NULL; + + switch (e) + { + case physx::PxErrorCode::eINVALID_PARAMETER: + errorCode = "invalid parameter"; + break; + case physx::PxErrorCode::eINVALID_OPERATION: + errorCode = "invalid operation"; + break; + case physx::PxErrorCode::eOUT_OF_MEMORY: + errorCode = "out of memory"; + break; + case physx::PxErrorCode::eDEBUG_INFO: + errorCode = "info"; + break; + case physx::PxErrorCode::eDEBUG_WARNING: + errorCode = "warning"; + break; + default: + errorCode = "unknown error"; + break; + } + + PX_ASSERT(errorCode != NULL); + if (errorCode != NULL) + { + printError(message, errorCode, file, line); + } +} + +void UserErrorCallback::printError(physx::PxErrorCode::Enum code, const char* file, int line, const char* fmt, ...) +{ + char buff[2048]; + va_list arg; + va_start(arg, fmt); + physx::shdfnd::vsnprintf(buff, sizeof(buff), fmt, arg); + va_end(arg); + reportError(code, buff, file, line); +} + + +void UserErrorCallback::openFile() +{ + if (mOutFile != NULL) + { + return; + } + + if (mOutFileName.empty()) + { + return; + } + + PX_ASSERT(mNumErrors == 0); + + if (mOutFileMode == NULL) + { + mOutFileMode = "w"; + } + + mOutFile = fopen(mOutFileName.c_str(), mOutFileMode); + + // if that failed, try the temp location on windows +#if PX_WINDOWS_FAMILY + if (!mOutFile) + { + DWORD pathLen = ::GetTempPathA(0, NULL); + if (pathLen) + { + char *pathStr = (char*)malloc(pathLen); + GetTempPathA(pathLen, pathStr); + std::string tmpPath(pathStr); + tmpPath.append(mOutFileName); + mOutFileName = tmpPath; + free(pathStr); + + ::fopen_s(&mOutFile, mOutFileName.c_str(), mOutFileMode); + } + } +#endif + + if (mOutFile && mOutFileHeader) + { + fprintf(mOutFile, + "\n\n" + "-------------------------------------\n" + "-- new error stream\n"); +#if PX_WINDOWS_FAMILY + char timeBuf[30]; + time_t rawTime; + time(&rawTime); + ctime_s(timeBuf, sizeof(timeBuf), &rawTime); + fprintf(mOutFile, + "--\n" + "-- %s", timeBuf); +#endif + fprintf(mOutFile, + "-------------------------------------\n\n"); + + fflush(mOutFile); + } +} + +UserErrorCallback::~UserErrorCallback() +{ +#if PX_WINDOWS_FAMILY + if (mNumErrors > 0 && mReportErrors) + { + std::string errorString; + char buf[64]; + physx::shdfnd::snprintf(buf, sizeof(buf), "The error callback captured %d errors", mNumErrors); + + errorString.append(buf); + if (mOutFile != stdout && mOutFile != 0) + { + errorString.append(" in "); + errorString.append(mOutFileName); + } + + ::MessageBoxA(NULL, errorString.c_str(), "UserErrorCallback", MB_OK); + } +#else + PX_ASSERT(mNumErrors == 0); +#endif + + if (mOutFile != stdout && mOutFile != 0) + { + fclose(mOutFile); + mOutFile = 0; + } +} -- cgit v1.2.3