VRTowerDef/Plugins/MetaXR/Source/OculusXRHMD/Private/OculusXRHMD_Layer.h

234 lines
8.4 KiB
C
Raw Normal View History

2024-05-29 08:53:41 +00:00
// @lint-ignore-every LICENSELINT
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "OculusXRHMDPrivate.h"
#include "ProceduralMeshComponent.h"
#if OCULUS_HMD_SUPPORTED_PLATFORMS
#include "OculusXRHMD_CustomPresent.h"
#include "XRSwapChain.h"
#include "OculusXRPassthroughLayerShapes.h"
namespace OculusXRHMD
{
//-------------------------------------------------------------------------------------------------
// FOvrpLayer
//-------------------------------------------------------------------------------------------------
class FDeferredDeletionQueue;
class FOvrpLayer : public TSharedFromThis<FOvrpLayer, ESPMode::ThreadSafe>
{
public:
FOvrpLayer(uint32 InOvrpLayerId, FDeferredDeletionQueue* InDeferredDeletion);
~FOvrpLayer();
protected:
uint32 OvrpLayerId;
private:
FDeferredDeletionQueue* DeferredDeletion; // necessary for deferred deletion queue of the actual OvrpLayer
};
typedef TSharedPtr<FOvrpLayer, ESPMode::ThreadSafe> FOvrpLayerPtr;
//-------------------------------------------------------------------------------------------------
// FLayer
//-------------------------------------------------------------------------------------------------
class FLayer : public TSharedFromThis<FLayer, ESPMode::ThreadSafe>
{
public:
FLayer(uint32 InId);
FLayer(const FLayer& InLayer);
~FLayer();
uint32 GetId() const { return Id; }
int GetOvrpId() const { return OvrpLayerId; }
void SetDesc(const IStereoLayers::FLayerDesc& InDesc);
void SetDesc(const FSettings* Settings, const IStereoLayers::FLayerDesc& InDesc);
const IStereoLayers::FLayerDesc& GetDesc() const { return Desc; }
void SetEyeLayerDesc(const ovrpLayerDesc_EyeFov& InEyeLayerDesc);
const FXRSwapChainPtr& GetSwapChain() const { return SwapChain; }
const FXRSwapChainPtr& GetRightSwapChain() const { return RightSwapChain; }
const FXRSwapChainPtr& GetDepthSwapChain() const { return DepthSwapChain; }
const FXRSwapChainPtr& GetFoveationSwapChain() const { return FoveationSwapChain; }
const FXRSwapChainPtr& GetMotionVectorSwapChain() const { return MotionVectorSwapChain; }
const FXRSwapChainPtr& GetMotionVectorDepthSwapChain() const { return MotionVectorDepthSwapChain; }
void MarkTextureForUpdate() { bUpdateTexture = true; }
bool NeedsPokeAHole();
void HandlePokeAHoleComponent();
void BuildPokeAHoleMesh(TArray<FVector>& Vertices, TArray<int32>& Triangles, TArray<FVector2D>& UV0);
bool NeedsPassthroughPokeAHole();
bool ShapeNeedsTextures(ovrpShape shape);
FTextureRHIRef GetTexture() { return Desc.Texture; }
TSharedPtr<FLayer, ESPMode::ThreadSafe> Clone() const;
bool CanReuseResources(const FLayer* InLayer) const;
bool Initialize_RenderThread(const FSettings* Settings, FCustomPresent* CustomPresent, FDeferredDeletionQueue* DeferredDeletion, FRHICommandListImmediate& RHICmdList, const FLayer* InLayer = nullptr);
void UpdateTexture_RenderThread(const FSettings* Settings, FCustomPresent* CustomPresent, FRHICommandListImmediate& RHICmdList);
void UpdatePassthrough_RenderThread(FCustomPresent* CustomPresent, FRHICommandListImmediate& RHICmdList, const FGameFrame* Frame);
const ovrpLayerSubmit* UpdateLayer_RHIThread(const FSettings* Settings, const FGameFrame* Frame, const int LayerIndex);
void IncrementSwapChainIndex_RHIThread(FCustomPresent* CustomPresent);
void ReleaseResources_RHIThread();
bool IsVisible() { return (Desc.Flags & IStereoLayers::LAYER_FLAG_HIDDEN) == 0; }
bool bNeedsTexSrgbCreate;
void AddPassthroughMesh_RenderThread(const TArray<FVector>& Vertices, const TArray<int32>& Triangles, FMatrix Transformation, uint64_t& OutMeshHandle, uint64_t& OutInstanceHandle);
void UpdatePassthroughMeshTransform_RenderThread(uint64_t InstanceHandle, FMatrix Transformation);
void RemovePassthroughMesh_RenderThread(uint64_t MeshHandle, uint64_t InstanceHandle);
void DestroyLayer();
protected:
struct FPassthroughMesh
{
FPassthroughMesh(uint64_t MeshHandle, uint64_t InstanceHandle)
: MeshHandle(MeshHandle)
, InstanceHandle(InstanceHandle)
{
}
uint64_t MeshHandle;
uint64_t InstanceHandle;
};
typedef TSharedPtr<TMap<FString, FPassthroughMesh>, ESPMode::ThreadSafe> FUserDefinedGeometryMapPtr;
void UpdatePassthroughStyle_RenderThread(const FEdgeStyleParameters& EdgeStyleParameters);
struct FPassthroughPokeActor
{
FPassthroughPokeActor(){};
FPassthroughPokeActor(UProceduralMeshComponent* PokeAHoleComponentPtr, AActor* PokeAHoleActor)
: PokeAHoleComponentPtr(PokeAHoleComponentPtr)
, PokeAHoleActor(PokeAHoleActor){};
UProceduralMeshComponent* PokeAHoleComponentPtr;
AActor* PokeAHoleActor;
};
typedef TSharedPtr<TMap<FString, FPassthroughPokeActor>, ESPMode::ThreadSafe> FPassthroughPokeActorMapPtr;
bool BuildPassthroughPokeActor(FOculusPassthroughMeshRef PassthroughMesh, FPassthroughPokeActor& OutPassthroughPokeActor);
void UpdatePassthroughPokeActors_GameThread();
uint32 Id;
IStereoLayers::FLayerDesc Desc;
int OvrpLayerId;
ovrpLayerDescUnion OvrpLayerDesc;
ovrpLayerSubmitUnion OvrpLayerSubmit;
FOvrpLayerPtr OvrpLayer;
FXRSwapChainPtr SwapChain;
FXRSwapChainPtr DepthSwapChain;
FXRSwapChainPtr FoveationSwapChain;
FXRSwapChainPtr RightSwapChain;
FXRSwapChainPtr RightDepthSwapChain;
FXRSwapChainPtr MotionVectorSwapChain;
FXRSwapChainPtr MotionVectorDepthSwapChain;
FTextureRHIRef InvAlphaTexture;
bool bUpdateTexture;
bool bInvertY;
bool bHasDepth;
bool bSupportDepthComposite;
UProceduralMeshComponent* PokeAHoleComponentPtr;
AActor* PokeAHoleActor;
FUserDefinedGeometryMapPtr UserDefinedGeometryMap;
FPassthroughPokeActorMapPtr PassthroughPokeActorMap;
};
typedef TSharedPtr<FLayer, ESPMode::ThreadSafe> FLayerPtr;
//-------------------------------------------------------------------------------------------------
// FLayerPtr_CompareId
//-------------------------------------------------------------------------------------------------
struct FLayerPtr_CompareId
{
FORCEINLINE bool operator()(const FLayerPtr& A, const FLayerPtr& B) const
{
return A->GetId() < B->GetId();
}
};
//-------------------------------------------------------------------------------------------------
// FLayerPtr_ComparePriority
//-------------------------------------------------------------------------------------------------
struct FLayerPtr_ComparePriority
{
FORCEINLINE bool operator()(const FLayerPtr& A, const FLayerPtr& B) const
{
if (A->GetDesc().Priority < B->GetDesc().Priority)
return true;
if (A->GetDesc().Priority > B->GetDesc().Priority)
return false;
return A->GetId() < B->GetId();
}
};
struct FLayerPtr_CompareTotal
{
FORCEINLINE int32 GetLayerTypePriority(const FLayerPtr& A) const
{
// Draw FReconstructedLayer, PoleAHole layers (Android only), EyeFov layer, followed by other layers
const bool IsEyeFov = (A->GetId() == 0);
const bool IsPokeAHole = A->NeedsPokeAHole() || A->NeedsPassthroughPokeAHole();
bool IsUnderlay = false;
if (A->GetDesc().HasShape<FReconstructedLayer>())
{
const FReconstructedLayer& ReconstructedLayerProps = A->GetDesc().GetShape<FReconstructedLayer>();
IsUnderlay = (ReconstructedLayerProps.PassthroughLayerOrder == PassthroughLayerOrder_Underlay);
}
else if (A->GetDesc().HasShape<FUserDefinedLayer>())
{
const FUserDefinedLayer& UserDefinedLayerProps = A->GetDesc().GetShape<FUserDefinedLayer>();
IsUnderlay = (UserDefinedLayerProps.PassthroughLayerOrder == PassthroughLayerOrder_Underlay);
}
const int32 Priority = IsUnderlay ? -2 : IsPokeAHole ? -1
: IsEyeFov ? 0
: 1;
return Priority;
}
FORCEINLINE bool operator()(const FLayerPtr& A, const FLayerPtr& B) const
{
// First order layers by type
int32 PassA = GetLayerTypePriority(A);
int32 PassB = GetLayerTypePriority(B);
if (PassA != PassB)
return PassA < PassB;
// Draw non-FaceLocked layers first
const IStereoLayers::FLayerDesc& DescA = A->GetDesc();
const IStereoLayers::FLayerDesc& DescB = B->GetDesc();
bool bFaceLockedA = (DescA.PositionType == IStereoLayers::ELayerType::FaceLocked);
bool bFaceLockedB = (DescB.PositionType == IStereoLayers::ELayerType::FaceLocked);
if (bFaceLockedA != bFaceLockedB)
return !bFaceLockedA;
// Draw layers by ascending priority
if (DescA.Priority != DescB.Priority)
return DescA.Priority < DescB.Priority;
// Draw layers by ascending id
return A->GetId() < B->GetId();
}
};
} // namespace OculusXRHMD
#endif //OCULUS_HMD_SUPPORTED_PLATFORMS