/* Copyright (c) 2017, 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 "FNVIDIAGfeSDK.h" #include "NVIDIAGfeSDKPrivatePCH.h" #include "Runtime/Core/Public/Misc/Paths.h" #include "Runtime/Core/Public/Windows/WindowsPlatformProcess.h" #include "Interfaces/IPluginManager.h" #include "gfesdk/sdk_types.h" #define LOCTEXT_NAMESPACE "NVIDIAGfeSDKPlugin" #define PLUGIN_VERSION "1.0.0" DEFINE_LOG_CATEGORY(LogGfeSDK); static void __stdcall LoggingCallback(GfeSDK::NVGSDK_LogLevel level, char const* text) { switch (level) { case GfeSDK::NVGSDK_LOG_NONE: break; case GfeSDK::NVGSDK_LOG_ERROR: UE_LOG(LogGfeSDK, Warning, TEXT("%s"), UTF8_TO_TCHAR(text)); break; case GfeSDK::NVGSDK_LOG_INFO: case GfeSDK::NVGSDK_LOG_DEBUG: case GfeSDK::NVGSDK_LOG_VERBOSE: default: UE_LOG(LogGfeSDK, Log, TEXT("%s"), UTF8_TO_TCHAR(text)); break; } } void FNVIDIAGfeSDK::StartupModule() { #if PLATFORM_WINDOWS #if _WIN64 FString WinDir = TEXT("Win64/"); #else FString WinDir = TEXT("Win32/"); #endif #else #error Platform currently unsupported #endif // PLATFORM_WINDOWS // Get the base directory of this plugin const FString PluginPath = IPluginManager::Get().FindPlugin(TEXT("NVIDIAGfeSDK"))->GetBaseDir(); FString RootDllPath = PluginPath / FString::Printf(TEXT("ThirdParty/NVIDIAGfeSDK/redist/")) / WinDir; FPlatformProcess::PushDllDirectory(*RootDllPath); LibHandle = FPlatformProcess::GetDllHandle(*(RootDllPath + "GfeSDK.dll")); FPlatformProcess::PopDllDirectory(*RootDllPath); if (!LibHandle) { UE_LOG(LogTemp, Warning, TEXT("Failed to load GfeSDK library.")); } else { UE_LOG(LogTemp, Log, TEXT("Using NVIDIAGfeSDKPlugin version %s"), TEXT(PLUGIN_VERSION)); GfeSDK::AttachLogListener(LoggingCallback); } } void FNVIDIAGfeSDK::ShutdownModule() { Release(); if (LibHandle) { FPlatformProcess::FreeDllHandle(LibHandle); LibHandle = nullptr; } } static GfeSDK::NVGSDK_LogLevel getLogLevel(ELogVerbosity::Type verbosity) { switch (verbosity) { case ELogVerbosity::NoLogging: return GfeSDK::NVGSDK_LOG_NONE; case ELogVerbosity::Fatal: case ELogVerbosity::Error: case ELogVerbosity::Warning: return GfeSDK::NVGSDK_LOG_ERROR; case ELogVerbosity::Display: return GfeSDK::NVGSDK_LOG_INFO; case ELogVerbosity::Log: return GfeSDK::NVGSDK_LOG_DEBUG; case ELogVerbosity::Verbose: case ELogVerbosity::VeryVerbose: return GfeSDK::NVGSDK_LOG_VERBOSE; default: return GfeSDK::NVGSDK_LOG_DEBUG; } } // Controls the log level of GfeSDK's internal logfile GfeSDK::NVGSDK_RetCode FNVIDIAGfeSDK::SetFileLogLevel(ELogVerbosity::Type Level) { if (!LibHandle) return GfeSDK::NVGSDK_ERR_MODULE_NOT_LOADED; return GfeSDK::SetFileLogLevel(getLogLevel(Level)); } // Controls the log level of logs that GfeSDK sends to the unreal logfile GfeSDK::NVGSDK_RetCode FNVIDIAGfeSDK::SetUnrealLogLevel(ELogVerbosity::Type Level) { if (!LibHandle) return GfeSDK::NVGSDK_ERR_MODULE_NOT_LOADED; return GfeSDK::SetListenerLogLevel(getLogLevel(Level)); } static const EGfeSDKScope ScopeMap[(size_t)EGfeSDKScope::MAX] = { EGfeSDKScope::Highlights, EGfeSDKScope::HighlightsRecordVideo, EGfeSDKScope::HighlightsRecordScreenshot }; static const EGfeSDKPermission PermissionMap[] = { EGfeSDKPermission::Granted, EGfeSDKPermission::MustAsk, EGfeSDKPermission::Denied, EGfeSDKPermission::Unknown }; void __stdcall OnNotificationCallback(GfeSDK::NVGSDK_NotificationType type, GfeSDK::NVGSDK_Notification const* response, void* context) { FNVIDIAGfeSDK* SDKObject = static_cast(context); switch (type) { case GfeSDK::NVGSDK_NOTIFICATION_PERMISSIONS_CHANGED: { FGfeSDKPermissionsChangedData PermissionsChangedData; for (size_t i = 0; i < response->permissionsChanged.scopePermissionTableSize; i++) { PermissionsChangedData.ScopePermissions.Add(ScopeMap[response->permissionsChanged.scopePermissionTable[i].scope], PermissionMap[response->permissionsChanged.scopePermissionTable[i].permission]); } if (SDKObject) SDKObject->PermissionsChangedDelegate.ExecuteIfBound(PermissionsChangedData); } } } EGfeSDKReturnCode FNVIDIAGfeSDK::Create(FGfeSDKCreateInputParams const& InputParams, FGfeSDKCreateResponse& Response) { if (!GFEHandle) { GfeSDK::NVGSDK_HANDLE* Handle = nullptr; GfeSDK::NVGSDK_CreateInputParams InputParamsCreate; memset(&InputParamsCreate, 0, sizeof(InputParamsCreate)); GfeSDK::NVGSDK_CreateResponse OutputParamsCreate; std::string appNameUTF = TCHAR_TO_UTF8(*InputParams.AppName); InputParamsCreate.appName = appNameUTF.c_str(); InputParamsCreate.pollForCallbacks = InputParams.PollForCallbacks; std::vector Scopes(InputParams.RequiredScopes.Num()); for (size_t i = 0; i cScopePermissionList(Scopes.size()); OutputParamsCreate.scopePermissionTable = &cScopePermissionList[0]; OutputParamsCreate.scopePermissionTableSize = Scopes.size(); GfeSDK::NVGSDK_RetCode Result = GfeSDK::NVGSDK_Create(&Handle, &InputParamsCreate, &OutputParamsCreate); if (GfeSDK::NVGSDK_SUCCEEDED(Result)) { GFEHandle = Handle; Response.VersionMajor = OutputParamsCreate.versionMajor; Response.VersionMinor = OutputParamsCreate.versionMinor; Response.NVIDIAGfeVersion = FString(OutputParamsCreate.gfeVersionStr); SdkCore.Reset(new FGfeSDKCore(GFEHandle)); SdkHighlights.Reset(new FGfeSDKHighlights(GFEHandle)); for (size_t i = 0; i < OutputParamsCreate.scopePermissionTableSize; i++) { Response.ScopePermissions.Add( TranslateEnum(kScopeSdkToUnreal, OutputParamsCreate.scopePermissionTable[i].scope, EGfeSDKScope::MAX), TranslateEnum(kPermissionSdkToUnreal, OutputParamsCreate.scopePermissionTable[i].permission, EGfeSDKPermission::MAX)); } // Save it for future when GFEHandle exists. SdkResponseRecord = Response; } else { // clear the response Response = FGfeSDKCreateResponse(); UE_LOG(LogGfeSDK, Error, TEXT("Failed to create GfeSDK: %d"), (int)Result); } return TranslateReturnCodeToUnreal(Result); } else { // Use saved value. Response = SdkResponseRecord; return TranslateReturnCodeToUnreal(GfeSDK::NVGSDK_RetCode::NVGSDK_SUCCESS); } } void FNVIDIAGfeSDK::Release() { if (GFEHandle) { NVGSDK_Release(GFEHandle); GFEHandle = nullptr; SdkResponseRecord = FGfeSDKCreateResponse(); } SdkHighlights.Reset(); } FGfeSDKCore* FNVIDIAGfeSDK::Core() { return SdkCore.Get(); } FGfeSDKHighlights* FNVIDIAGfeSDK::Highlights() { return SdkHighlights.Get(); } IMPLEMENT_MODULE(FNVIDIAGfeSDK, NVIDIAGfeSDK) #undef LOCTEXT_NAMESPACE