Files
UnrealEngineUWP/Engine/Plugins/Runtime/OpenCV/Source/OpenCVHelper/Private/OpenCVHelperModule.cpp
simon therriault f8b8399d69 - Adding linux platform for opencv library
#jira UETOOL-4743
#rb geoffrey.douglas, alejandro.arango, brandon.schaefer
#preflight 61f04feafd5285142b203c77

#ROBOMERGE-AUTHOR: simon.therriault
#ROBOMERGE-SOURCE: CL 18726707 in //UE5/Release-5.0/... via CL 18726720 via CL 18726894
#ROBOMERGE-BOT: UE5 (Release-Engine-Test -> Main) (v903-18687472)

[CL 18726910 by simon therriault in ue5-main branch]
2022-01-25 14:54:09 -05:00

114 lines
2.7 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "IOpenCVHelperModule.h"
#include "Containers/Set.h"
#include "Misc/ScopeLock.h"
#include "Modules/ModuleManager.h" // for IMPLEMENT_MODULE()
#include "Interfaces/IPluginManager.h"
#include "HAL/PlatformProcess.h"
#if WITH_OPENCV
#include "OpenCVHelper.h"
#include "PreOpenCVHeaders.h"
#include "opencv2/unreal.hpp"
#include "PostOpenCVHeaders.h"
#endif
namespace OpenCVHelperModule
{
#if WITH_OPENCV
static TSet<void*> UnrealAllocationsSet;
static FCriticalSection UnrealAllocationsSetMutex;
static void* UnrealMalloc(size_t Count, uint32_t Alignment)
{
void* Address = FMemory::Malloc(static_cast<SIZE_T>(Count), static_cast<uint32>(Alignment));
{
FScopeLock Lock(&UnrealAllocationsSetMutex);
UnrealAllocationsSet.Add(Address);
}
return Address;
}
static void UnrealFree(void* Original)
{
// Only free allocations made by Unreal. Any allocations made before new/delete was overridden will have to leak.
{
FScopeLock Lock(&UnrealAllocationsSetMutex);
if (!UnrealAllocationsSet.Contains(Original))
{
return;
}
UnrealAllocationsSet.Remove(Original);
}
FMemory::Free(Original);
}
#endif //WITH_OPENCV
}
class FOpenCVHelperModule : public IOpenCVHelperModule
{
public:
FOpenCVHelperModule();
public:
//~ IModuleInterface interface
virtual void StartupModule() override;
virtual void ShutdownModule() override;
private:
void* OpenCvDllHandle;
};
FOpenCVHelperModule::FOpenCVHelperModule()
: OpenCvDllHandle(nullptr)
{}
void FOpenCVHelperModule::StartupModule()
{
const FString PluginDir = IPluginManager::Get().FindPlugin(TEXT("OpenCV"))->GetBaseDir();
#if WITH_OPENCV
#if defined(OPENCV_DLL_NAME)
const FString OpenCvBinPath = PluginDir / TEXT(PREPROCESSOR_TO_STRING(OPENCV_PLATFORM_PATH));
const FString DLLPath = OpenCvBinPath / TEXT(PREPROCESSOR_TO_STRING(OPENCV_DLL_NAME));
FPlatformProcess::PushDllDirectory(*OpenCvBinPath);
OpenCvDllHandle = FPlatformProcess::GetDllHandle(*DLLPath);
FPlatformProcess::PopDllDirectory(*OpenCvBinPath);
#endif
// We need to tell OpenCV to use Unreal's memory allocator to avoid crashes.
// These may happen when Unreal passes a container to OpenCV, then OpenCV allocates memory for that container
// and then Unreal tries to release the memory in it.
cv::unreal::SetMallocAndFree(&OpenCVHelperModule::UnrealMalloc, &OpenCVHelperModule::UnrealFree);
#endif
}
void FOpenCVHelperModule::ShutdownModule()
{
#if WITH_OPENCV
if (OpenCvDllHandle)
{
FPlatformProcess::FreeDllHandle(OpenCvDllHandle);
OpenCvDllHandle = nullptr;
}
// Note: Seems safer to not put back the original new/delete in OpenCV and keep Unreal's versions even after this module unloads.
#endif
}
IMPLEMENT_MODULE(FOpenCVHelperModule, OpenCVHelper);