Init
This commit is contained in:
83
physx/source/pvd/include/PsPvd.h
Normal file
83
physx/source/pvd/include/PsPvd.h
Normal file
@ -0,0 +1,83 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifndef PXPVDSDK_PSPVD_H
|
||||
#define PXPVDSDK_PSPVD_H
|
||||
|
||||
/** \addtogroup pvd
|
||||
@{
|
||||
*/
|
||||
#include "pvd/PxPvd.h"
|
||||
#include "PsBroadcast.h"
|
||||
|
||||
#if !PX_DOXYGEN
|
||||
namespace physx
|
||||
{
|
||||
#endif
|
||||
|
||||
class PxPvdTransport;
|
||||
|
||||
#if !PX_DOXYGEN
|
||||
namespace pvdsdk
|
||||
{
|
||||
#endif
|
||||
|
||||
class PvdDataStream;
|
||||
class PvdClient;
|
||||
class PvdOMMetaDataProvider;
|
||||
|
||||
// PsPvd is used for advanced user, it support custom pvd client API
|
||||
class PsPvd : public physx::PxPvd, public shdfnd::AllocationListener
|
||||
{
|
||||
public:
|
||||
virtual void addClient(PvdClient* client) = 0;
|
||||
virtual void removeClient(PvdClient* client) = 0;
|
||||
|
||||
virtual bool registerObject(const void* inItem) = 0;
|
||||
virtual bool unRegisterObject(const void* inItem) = 0;
|
||||
|
||||
//AllocationListener
|
||||
void onAllocation(size_t size, const char* typeName, const char* filename, int line, void* allocatedMemory) = 0;
|
||||
void onDeallocation(void* addr) = 0;
|
||||
|
||||
virtual PvdOMMetaDataProvider& getMetaDataProvider() = 0;
|
||||
|
||||
virtual uint64_t getNextStreamId() = 0;
|
||||
// Call to flush events to PVD
|
||||
virtual void flush() = 0;
|
||||
|
||||
};
|
||||
|
||||
#if !PX_DOXYGEN
|
||||
} // namespace pvdsdk
|
||||
} // namespace physx
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
#endif // PXPVDSDK_PSPVD_H
|
||||
231
physx/source/pvd/include/PxProfileAllocatorWrapper.h
Normal file
231
physx/source/pvd/include/PxProfileAllocatorWrapper.h
Normal file
@ -0,0 +1,231 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
|
||||
#ifndef PXPVDSDK_PXPROFILEALLOCATORWRAPPER_H
|
||||
#define PXPVDSDK_PXPROFILEALLOCATORWRAPPER_H
|
||||
|
||||
#include "foundation/PxPreprocessor.h"
|
||||
#include "foundation/PxAllocatorCallback.h"
|
||||
#include "foundation/PxErrorCallback.h"
|
||||
#include "foundation/PxAssert.h"
|
||||
|
||||
#include "PsArray.h"
|
||||
#include "PsHashMap.h"
|
||||
|
||||
namespace physx { namespace profile {
|
||||
|
||||
/**
|
||||
\brief Helper struct to encapsulate the user allocator callback
|
||||
Useful for array and hash templates
|
||||
*/
|
||||
struct PxProfileAllocatorWrapper
|
||||
{
|
||||
PxAllocatorCallback* mUserAllocator;
|
||||
|
||||
PxProfileAllocatorWrapper( PxAllocatorCallback& inUserAllocator )
|
||||
: mUserAllocator( &inUserAllocator )
|
||||
{
|
||||
}
|
||||
|
||||
PxProfileAllocatorWrapper( PxAllocatorCallback* inUserAllocator )
|
||||
: mUserAllocator( inUserAllocator )
|
||||
{
|
||||
}
|
||||
|
||||
PxAllocatorCallback& getAllocator() const
|
||||
{
|
||||
PX_ASSERT( NULL != mUserAllocator );
|
||||
return *mUserAllocator;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Helper class to encapsulate the reflection allocator
|
||||
*/
|
||||
template <typename T>
|
||||
class PxProfileWrapperReflectionAllocator
|
||||
{
|
||||
static const char* getName()
|
||||
{
|
||||
#if PX_LINUX || PX_ANDROID || PX_PS4 || PX_IOS || PX_OSX || PX_EMSCRIPTEN || PX_SWITCH
|
||||
return __PRETTY_FUNCTION__;
|
||||
#else
|
||||
return typeid(T).name();
|
||||
#endif
|
||||
}
|
||||
PxProfileAllocatorWrapper* mWrapper;
|
||||
|
||||
public:
|
||||
PxProfileWrapperReflectionAllocator(PxProfileAllocatorWrapper& inWrapper) : mWrapper( &inWrapper ) {}
|
||||
PxProfileWrapperReflectionAllocator( const PxProfileWrapperReflectionAllocator& inOther )
|
||||
: mWrapper( inOther.mWrapper )
|
||||
{
|
||||
}
|
||||
PxProfileWrapperReflectionAllocator& operator=( const PxProfileWrapperReflectionAllocator& inOther )
|
||||
{
|
||||
mWrapper = inOther.mWrapper;
|
||||
return *this;
|
||||
}
|
||||
PxAllocatorCallback& getAllocator() { return mWrapper->getAllocator(); }
|
||||
void* allocate(size_t size, const char* filename, int line)
|
||||
{
|
||||
#if PX_CHECKED // checked and debug builds
|
||||
if(!size)
|
||||
return 0;
|
||||
return getAllocator().allocate(size, getName(), filename, line);
|
||||
#else
|
||||
return getAllocator().allocate(size, "<no allocation names in this config>", filename, line);
|
||||
#endif
|
||||
}
|
||||
void deallocate(void* ptr)
|
||||
{
|
||||
if(ptr)
|
||||
getAllocator().deallocate(ptr);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Helper class to encapsulate the named allocator
|
||||
*/
|
||||
struct PxProfileWrapperNamedAllocator
|
||||
{
|
||||
PxProfileAllocatorWrapper* mWrapper;
|
||||
const char* mAllocationName;
|
||||
PxProfileWrapperNamedAllocator(PxProfileAllocatorWrapper& inWrapper, const char* inAllocationName)
|
||||
: mWrapper( &inWrapper )
|
||||
, mAllocationName( inAllocationName )
|
||||
{}
|
||||
PxProfileWrapperNamedAllocator( const PxProfileWrapperNamedAllocator& inOther )
|
||||
: mWrapper( inOther.mWrapper )
|
||||
, mAllocationName( inOther.mAllocationName )
|
||||
{
|
||||
}
|
||||
PxProfileWrapperNamedAllocator& operator=( const PxProfileWrapperNamedAllocator& inOther )
|
||||
{
|
||||
mWrapper = inOther.mWrapper;
|
||||
mAllocationName = inOther.mAllocationName;
|
||||
return *this;
|
||||
}
|
||||
PxAllocatorCallback& getAllocator() { return mWrapper->getAllocator(); }
|
||||
void* allocate(size_t size, const char* filename, int line)
|
||||
{
|
||||
if(!size)
|
||||
return 0;
|
||||
return getAllocator().allocate(size, mAllocationName, filename, line);
|
||||
}
|
||||
void deallocate(void* ptr)
|
||||
{
|
||||
if(ptr)
|
||||
getAllocator().deallocate(ptr);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Helper struct to encapsulate the array
|
||||
*/
|
||||
template<class T>
|
||||
struct PxProfileArray : public shdfnd::Array<T, PxProfileWrapperReflectionAllocator<T> >
|
||||
{
|
||||
typedef PxProfileWrapperReflectionAllocator<T> TAllocatorType;
|
||||
|
||||
PxProfileArray( PxProfileAllocatorWrapper& inWrapper )
|
||||
: shdfnd::Array<T, TAllocatorType >( TAllocatorType( inWrapper ) )
|
||||
{
|
||||
}
|
||||
|
||||
PxProfileArray( const PxProfileArray< T >& inOther )
|
||||
: shdfnd::Array<T, TAllocatorType >( inOther, inOther )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Helper struct to encapsulate the array
|
||||
*/
|
||||
template<typename TKeyType, typename TValueType, typename THashType=shdfnd::Hash<TKeyType> >
|
||||
struct PxProfileHashMap : public shdfnd::HashMap<TKeyType, TValueType, THashType, PxProfileWrapperReflectionAllocator< TValueType > >
|
||||
{
|
||||
typedef shdfnd::HashMap<TKeyType, TValueType, THashType, PxProfileWrapperReflectionAllocator< TValueType > > THashMapType;
|
||||
typedef PxProfileWrapperReflectionAllocator<TValueType> TAllocatorType;
|
||||
PxProfileHashMap( PxProfileAllocatorWrapper& inWrapper )
|
||||
: THashMapType( TAllocatorType( inWrapper ) )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Helper function to encapsulate the profile allocation
|
||||
*/
|
||||
template<typename TDataType>
|
||||
inline TDataType* PxProfileAllocate( PxAllocatorCallback* inAllocator, const char* file, int inLine )
|
||||
{
|
||||
PxProfileAllocatorWrapper wrapper( inAllocator );
|
||||
typedef PxProfileWrapperReflectionAllocator< TDataType > TAllocator;
|
||||
TAllocator theAllocator( wrapper );
|
||||
return reinterpret_cast<TDataType*>( theAllocator.allocate( sizeof( TDataType ), file, inLine ) );
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Helper function to encapsulate the profile allocation
|
||||
*/
|
||||
template<typename TDataType>
|
||||
inline TDataType* PxProfileAllocate( PxAllocatorCallback& inAllocator, const char* file, int inLine )
|
||||
{
|
||||
return PxProfileAllocate<TDataType>( &inAllocator, file, inLine );
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Helper function to encapsulate the profile deallocation
|
||||
*/
|
||||
template<typename TDataType>
|
||||
inline void PxProfileDeleteAndDeallocate( PxProfileAllocatorWrapper& inAllocator, TDataType* inDType )
|
||||
{
|
||||
PX_ASSERT(inDType);
|
||||
PxAllocatorCallback& allocator( inAllocator.getAllocator() );
|
||||
inDType->~TDataType();
|
||||
allocator.deallocate( inDType );
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Helper function to encapsulate the profile deallocation
|
||||
*/
|
||||
template<typename TDataType>
|
||||
inline void PxProfileDeleteAndDeallocate( PxAllocatorCallback& inAllocator, TDataType* inDType )
|
||||
{
|
||||
PxProfileAllocatorWrapper wrapper( &inAllocator );
|
||||
PxProfileDeleteAndDeallocate( wrapper, inDType );
|
||||
}
|
||||
|
||||
} }
|
||||
|
||||
#define PX_PROFILE_NEW( allocator, dtype ) new (physx::profile::PxProfileAllocate<dtype>( allocator, __FILE__, __LINE__ )) dtype
|
||||
#define PX_PROFILE_DELETE( allocator, obj ) physx::profile::PxProfileDeleteAndDeallocate( allocator, obj );
|
||||
|
||||
#endif // PXPVDSDK_PXPROFILEALLOCATORWRAPPER_H
|
||||
76
physx/source/pvd/include/PxPvdClient.h
Normal file
76
physx/source/pvd/include/PxPvdClient.h
Normal file
@ -0,0 +1,76 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifndef PXPVDSDK_PXPVDCLIENT_H
|
||||
#define PXPVDSDK_PXPVDCLIENT_H
|
||||
|
||||
/** \addtogroup pvd
|
||||
@{
|
||||
*/
|
||||
#include "foundation/PxFlags.h"
|
||||
#include "foundation/PxVec3.h"
|
||||
|
||||
#if !PX_DOXYGEN
|
||||
namespace physx
|
||||
{
|
||||
namespace pvdsdk
|
||||
{
|
||||
#endif
|
||||
|
||||
class PvdDataStream;
|
||||
class PvdUserRenderer;
|
||||
|
||||
/**
|
||||
\brief PvdClient is the per-client connection to PVD.
|
||||
It provides callback when PVD is connected/disconnted.
|
||||
It provides access to the internal object so that advanced users can create extension client.
|
||||
*/
|
||||
class PvdClient
|
||||
{
|
||||
public:
|
||||
virtual PvdDataStream* getDataStream() = 0;
|
||||
|
||||
virtual bool isConnected() const = 0;
|
||||
virtual void onPvdConnected() = 0;
|
||||
virtual void onPvdDisconnected() = 0;
|
||||
virtual void flush() = 0;
|
||||
|
||||
protected:
|
||||
virtual ~PvdClient()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#if !PX_DOXYGEN
|
||||
} // namespace pvdsdk
|
||||
} // namespace physx
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
#endif // PXPVDSDK_PXPVDCLIENT_H
|
||||
272
physx/source/pvd/include/PxPvdDataStream.h
Normal file
272
physx/source/pvd/include/PxPvdDataStream.h
Normal file
@ -0,0 +1,272 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
#ifndef PXPVDSDK_PXPVDDATASTREAM_H
|
||||
#define PXPVDSDK_PXPVDDATASTREAM_H
|
||||
|
||||
/** \addtogroup pvd
|
||||
@{
|
||||
*/
|
||||
#include "pvd/PxPvd.h"
|
||||
#include "PxPvdErrorCodes.h"
|
||||
#include "PxPvdObjectModelBaseTypes.h"
|
||||
|
||||
#if !PX_DOXYGEN
|
||||
namespace physx
|
||||
{
|
||||
namespace pvdsdk
|
||||
{
|
||||
#endif
|
||||
|
||||
class PvdPropertyDefinitionHelper;
|
||||
|
||||
class PvdMetaDataStream
|
||||
{
|
||||
protected:
|
||||
virtual ~PvdMetaDataStream()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
virtual PvdError createClass(const NamespacedName& nm) = 0;
|
||||
template <typename TDataType>
|
||||
PvdError createClass()
|
||||
{
|
||||
return createClass(getPvdNamespacedNameForType<TDataType>());
|
||||
}
|
||||
|
||||
virtual PvdError deriveClass(const NamespacedName& parent, const NamespacedName& child) = 0;
|
||||
template <typename TParentType, typename TChildType>
|
||||
PvdError deriveClass()
|
||||
{
|
||||
return deriveClass(getPvdNamespacedNameForType<TParentType>(), getPvdNamespacedNameForType<TChildType>());
|
||||
}
|
||||
|
||||
virtual bool isClassExist(const NamespacedName& nm) = 0;
|
||||
template <typename TDataType>
|
||||
bool isClassExist()
|
||||
{
|
||||
return isClassExist(getPvdNamespacedNameForType<TDataType>());
|
||||
}
|
||||
|
||||
virtual PvdError createProperty(const NamespacedName& clsName, const char* name, const char* semantic,
|
||||
const NamespacedName& dtypeName, PropertyType::Enum propertyType,
|
||||
DataRef<NamedValue> values = DataRef<NamedValue>()) = 0;
|
||||
template <typename TClsType, typename TDataType>
|
||||
PvdError createProperty(String name, String semantic = "", PropertyType::Enum propertyType = PropertyType::Scalar,
|
||||
DataRef<NamedValue> values = DataRef<NamedValue>())
|
||||
{
|
||||
return createProperty(getPvdNamespacedNameForType<TClsType>(), name, semantic,
|
||||
getPvdNamespacedNameForType<TDataType>(), propertyType, values);
|
||||
}
|
||||
|
||||
virtual PvdError createPropertyMessage(const NamespacedName& cls, const NamespacedName& msgName,
|
||||
DataRef<PropertyMessageArg> entries, uint32_t messageSizeInBytes) = 0;
|
||||
|
||||
template <typename TClsType, typename TMsgType>
|
||||
PvdError createPropertyMessage(DataRef<PropertyMessageArg> entries)
|
||||
{
|
||||
return createPropertyMessage(getPvdNamespacedNameForType<TClsType>(), getPvdNamespacedNameForType<TMsgType>(),
|
||||
entries, sizeof(TMsgType));
|
||||
}
|
||||
};
|
||||
|
||||
class PvdInstanceDataStream
|
||||
{
|
||||
protected:
|
||||
virtual ~PvdInstanceDataStream()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
virtual PvdError createInstance(const NamespacedName& cls, const void* instance) = 0;
|
||||
|
||||
template <typename TDataType>
|
||||
PvdError createInstance(const TDataType* inst)
|
||||
{
|
||||
return createInstance(getPvdNamespacedNameForType<TDataType>(), inst);
|
||||
}
|
||||
virtual bool isInstanceValid(const void* instance) = 0;
|
||||
|
||||
// If the property will fit or is already completely in memory
|
||||
virtual PvdError setPropertyValue(const void* instance, String name, DataRef<const uint8_t> data,
|
||||
const NamespacedName& incomingTypeName) = 0;
|
||||
template <typename TDataType>
|
||||
PvdError setPropertyValue(const void* instance, String name, const TDataType& value)
|
||||
{
|
||||
const uint8_t* dataStart = reinterpret_cast<const uint8_t*>(&value);
|
||||
return setPropertyValue(instance, name, DataRef<const uint8_t>(dataStart, dataStart + sizeof(TDataType)),
|
||||
getPvdNamespacedNameForType<TDataType>());
|
||||
}
|
||||
|
||||
template <typename TDataType>
|
||||
PvdError setPropertyValue(const void* instance, String name, const TDataType* value, uint32_t numItems)
|
||||
{
|
||||
const uint8_t* dataStart = reinterpret_cast<const uint8_t*>(value);
|
||||
return setPropertyValue(instance, name,
|
||||
DataRef<const uint8_t>(dataStart, dataStart + sizeof(TDataType) * numItems),
|
||||
getPvdNamespacedNameForType<TDataType>());
|
||||
}
|
||||
|
||||
// Else if the property is very large (contact reports) you can send it in chunks.
|
||||
virtual PvdError beginSetPropertyValue(const void* instance, String name, const NamespacedName& incomingTypeName) = 0;
|
||||
|
||||
template <typename TDataType>
|
||||
PvdError beginSetPropertyValue(const void* instance, String name)
|
||||
{
|
||||
return beginSetPropertyValue(instance, name, getPvdNamespacedNameForType<TDataType>());
|
||||
}
|
||||
virtual PvdError appendPropertyValueData(DataRef<const uint8_t> data) = 0;
|
||||
|
||||
template <typename TDataType>
|
||||
PvdError appendPropertyValueData(const TDataType* value, uint32_t numItems)
|
||||
{
|
||||
const uint8_t* dataStart = reinterpret_cast<const uint8_t*>(value);
|
||||
return appendPropertyValueData(DataRef<const uint8_t>(dataStart, dataStart + numItems * sizeof(TDataType)));
|
||||
}
|
||||
|
||||
virtual PvdError endSetPropertyValue() = 0;
|
||||
|
||||
// Set a set of properties to various values on an object.
|
||||
|
||||
virtual PvdError setPropertyMessage(const void* instance, const NamespacedName& msgName,
|
||||
DataRef<const uint8_t> data) = 0;
|
||||
|
||||
template <typename TDataType>
|
||||
PvdError setPropertyMessage(const void* instance, const TDataType& value)
|
||||
{
|
||||
const uint8_t* dataStart = reinterpret_cast<const uint8_t*>(&value);
|
||||
return setPropertyMessage(instance, getPvdNamespacedNameForType<TDataType>(),
|
||||
DataRef<const uint8_t>(dataStart, sizeof(TDataType)));
|
||||
}
|
||||
// If you need to send of lot of identical messages, this avoids a hashtable lookup per message.
|
||||
virtual PvdError beginPropertyMessageGroup(const NamespacedName& msgName) = 0;
|
||||
|
||||
template <typename TDataType>
|
||||
PvdError beginPropertyMessageGroup()
|
||||
{
|
||||
return beginPropertyMessageGroup(getPvdNamespacedNameForType<TDataType>());
|
||||
}
|
||||
virtual PvdError sendPropertyMessageFromGroup(const void* instance, DataRef<const uint8_t> data) = 0;
|
||||
|
||||
template <typename TDataType>
|
||||
PvdError sendPropertyMessageFromGroup(const void* instance, const TDataType& value)
|
||||
{
|
||||
const uint8_t* dataStart = reinterpret_cast<const uint8_t*>(&value);
|
||||
return sendPropertyMessageFromGroup(instance, DataRef<const uint8_t>(dataStart, sizeof(TDataType)));
|
||||
}
|
||||
|
||||
virtual PvdError endPropertyMessageGroup() = 0;
|
||||
|
||||
// These functions ensure the target array doesn't contain duplicates
|
||||
virtual PvdError pushBackObjectRef(const void* instId, String propName, const void* objRef) = 0;
|
||||
virtual PvdError removeObjectRef(const void* instId, String propName, const void* objRef) = 0;
|
||||
|
||||
// Instance elimination.
|
||||
virtual PvdError destroyInstance(const void* key) = 0;
|
||||
|
||||
// Profiling hooks
|
||||
virtual PvdError beginSection(const void* instance, String name) = 0;
|
||||
virtual PvdError endSection(const void* instance, String name) = 0;
|
||||
|
||||
// Origin Shift
|
||||
virtual PvdError originShift(const void* scene, PxVec3 shift) = 0;
|
||||
|
||||
public:
|
||||
/*For some cases, pvd command cannot be run immediately. For example, when create joints, while the actors may still
|
||||
*pending for insert, the joints update commands can be run deffered.
|
||||
*/
|
||||
class PvdCommand
|
||||
{
|
||||
public:
|
||||
// Assigned is needed for copying
|
||||
PvdCommand(const PvdCommand&)
|
||||
{
|
||||
}
|
||||
PvdCommand& operator=(const PvdCommand&)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
PvdCommand()
|
||||
{
|
||||
}
|
||||
virtual ~PvdCommand()
|
||||
{
|
||||
}
|
||||
|
||||
// Not pure virtual so can have default PvdCommand obj
|
||||
virtual bool canRun(PvdInstanceDataStream&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual void run(PvdInstanceDataStream&)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// PVD SDK provide this helper function to allocate cmd's memory and release them at after flush the command queue
|
||||
virtual void* allocateMemForCmd(uint32_t length) = 0;
|
||||
|
||||
// PVD will call the destructor of PvdCommand object at the end fo flushPvdCommand
|
||||
virtual void pushPvdCommand(PvdCommand& cmd) = 0;
|
||||
virtual void flushPvdCommand() = 0;
|
||||
};
|
||||
|
||||
class PvdDataStream : public PvdInstanceDataStream, public PvdMetaDataStream
|
||||
{
|
||||
protected:
|
||||
virtual ~PvdDataStream()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
virtual void release() = 0;
|
||||
virtual bool isConnected() = 0;
|
||||
|
||||
virtual void addProfileZone(void* zone, const char* name) = 0;
|
||||
virtual void addProfileZoneEvent(void* zone, const char* name, uint16_t eventId, bool compileTimeEnabled) = 0;
|
||||
|
||||
virtual PvdPropertyDefinitionHelper& getPropertyDefinitionHelper() = 0;
|
||||
|
||||
virtual void setIsTopLevelUIElement(const void* instance, bool topLevel) = 0;
|
||||
virtual void sendErrorMessage(uint32_t code, const char* message, const char* file, uint32_t line) = 0;
|
||||
virtual void updateCamera(const char* name, const PxVec3& origin, const PxVec3& up, const PxVec3& target) = 0;
|
||||
|
||||
/**
|
||||
\brief Create a new PvdDataStream.
|
||||
\param pvd A pointer to a valid PxPvd instance. This must be non-null.
|
||||
*/
|
||||
static PvdDataStream* create(PxPvd* pvd);
|
||||
};
|
||||
#if !PX_DOXYGEN
|
||||
} // pvdsdk
|
||||
} // physx
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
#endif // PXPVDSDK_PXPVDDATASTREAM_H
|
||||
120
physx/source/pvd/include/PxPvdDataStreamHelpers.h
Normal file
120
physx/source/pvd/include/PxPvdDataStreamHelpers.h
Normal file
@ -0,0 +1,120 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
#ifndef PXPVDSDK_PXPVDDATASTREAMHELPERS_H
|
||||
#define PXPVDSDK_PXPVDDATASTREAMHELPERS_H
|
||||
|
||||
/** \addtogroup pvd
|
||||
@{
|
||||
*/
|
||||
#include "PxPvdObjectModelBaseTypes.h"
|
||||
|
||||
#if !PX_DOXYGEN
|
||||
namespace physx
|
||||
{
|
||||
namespace pvdsdk
|
||||
{
|
||||
#endif
|
||||
|
||||
class PvdPropertyDefinitionHelper
|
||||
{
|
||||
protected:
|
||||
virtual ~PvdPropertyDefinitionHelper()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
Push a name c such that it appends such as a.b.c.
|
||||
*/
|
||||
virtual void pushName(const char* inName, const char* inAppendStr = ".") = 0;
|
||||
/**
|
||||
Push a name c such that it appends like a.b[c]
|
||||
*/
|
||||
virtual void pushBracketedName(const char* inName, const char* leftBracket = "[", const char* rightBracket = "]") = 0;
|
||||
/**
|
||||
* Pop the current name
|
||||
*/
|
||||
virtual void popName() = 0;
|
||||
|
||||
virtual void clearNameStack() = 0;
|
||||
/**
|
||||
* Get the current name at the top of the name stack.
|
||||
* Would return "a.b.c" or "a.b[c]" in the above examples.
|
||||
*/
|
||||
virtual const char* getTopName() = 0;
|
||||
|
||||
virtual void addNamedValue(const char* name, uint32_t value) = 0;
|
||||
virtual void clearNamedValues() = 0;
|
||||
virtual DataRef<NamedValue> getNamedValues() = 0;
|
||||
|
||||
/**
|
||||
* Define a property using the top of the name stack and the passed-in semantic
|
||||
*/
|
||||
virtual void createProperty(const NamespacedName& clsName, const char* inSemantic, const NamespacedName& dtypeName,
|
||||
PropertyType::Enum propType = PropertyType::Scalar) = 0;
|
||||
|
||||
template <typename TClsType, typename TDataType>
|
||||
void createProperty(const char* inSemantic = "", PropertyType::Enum propType = PropertyType::Scalar)
|
||||
{
|
||||
createProperty(getPvdNamespacedNameForType<TClsType>(), inSemantic, getPvdNamespacedNameForType<TDataType>(),
|
||||
propType);
|
||||
}
|
||||
|
||||
// The datatype used for instances needs to be pointer unless you actually have pvdsdk::InstanceId members on your
|
||||
// value structs.
|
||||
virtual void addPropertyMessageArg(const NamespacedName& inDatatype, uint32_t inOffset, uint32_t inSize) = 0;
|
||||
|
||||
template <typename TDataType>
|
||||
void addPropertyMessageArg(uint32_t offset)
|
||||
{
|
||||
addPropertyMessageArg(getPvdNamespacedNameForType<TDataType>(), offset, static_cast<uint32_t>(sizeof(TDataType)));
|
||||
}
|
||||
virtual void addPropertyMessage(const NamespacedName& clsName, const NamespacedName& msgName,
|
||||
uint32_t inStructSizeInBytes) = 0;
|
||||
template <typename TClsType, typename TMsgType>
|
||||
void addPropertyMessage()
|
||||
{
|
||||
addPropertyMessage(getPvdNamespacedNameForType<TClsType>(), getPvdNamespacedNameForType<TMsgType>(),
|
||||
static_cast<uint32_t>(sizeof(TMsgType)));
|
||||
}
|
||||
virtual void clearPropertyMessageArgs() = 0;
|
||||
|
||||
void clearBufferedData()
|
||||
{
|
||||
clearNameStack();
|
||||
clearPropertyMessageArgs();
|
||||
clearNamedValues();
|
||||
}
|
||||
};
|
||||
|
||||
#if !PX_DOXYGEN
|
||||
} // pvdsdk
|
||||
} // physx
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
#endif // PXPVDSDK_PXPVDDATASTREAMHELPERS_H
|
||||
62
physx/source/pvd/include/PxPvdErrorCodes.h
Normal file
62
physx/source/pvd/include/PxPvdErrorCodes.h
Normal file
@ -0,0 +1,62 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
#ifndef PXPVDSDK_PXPVDERRORCODES_H
|
||||
#define PXPVDSDK_PXPVDERRORCODES_H
|
||||
|
||||
/** \addtogroup pvd
|
||||
@{
|
||||
*/
|
||||
|
||||
#include "foundation/Px.h"
|
||||
|
||||
#if !PX_DOXYGEN
|
||||
namespace physx
|
||||
{
|
||||
namespace pvdsdk
|
||||
{
|
||||
#endif
|
||||
|
||||
struct PvdErrorType
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Success = 0,
|
||||
NetworkError,
|
||||
ArgumentError,
|
||||
Disconnect,
|
||||
InternalProblem
|
||||
};
|
||||
};
|
||||
|
||||
typedef PvdErrorType::Enum PvdError;
|
||||
|
||||
#if !PX_DOXYGEN
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/** @} */
|
||||
#endif // PXPVDSDK_PXPVDERRORCODES_H
|
||||
428
physx/source/pvd/include/PxPvdObjectModelBaseTypes.h
Normal file
428
physx/source/pvd/include/PxPvdObjectModelBaseTypes.h
Normal file
@ -0,0 +1,428 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef PXPVDSDK_PXPVDOBJECTMODELBASETYPES_H
|
||||
#define PXPVDSDK_PXPVDOBJECTMODELBASETYPES_H
|
||||
|
||||
/** \addtogroup pvd
|
||||
@{
|
||||
*/
|
||||
#include "foundation/PxAssert.h"
|
||||
|
||||
#if !PX_DOXYGEN
|
||||
namespace physx
|
||||
{
|
||||
namespace pvdsdk
|
||||
{
|
||||
#endif
|
||||
|
||||
using namespace physx;
|
||||
|
||||
inline const char* nonNull(const char* str)
|
||||
{
|
||||
return str ? str : "";
|
||||
}
|
||||
// strcmp will crash if passed a null string, however,
|
||||
// so we need to make sure that doesn't happen. We do that
|
||||
// by equating NULL and the empty string, "".
|
||||
inline bool safeStrEq(const char* lhs, const char* rhs)
|
||||
{
|
||||
return ::strcmp(nonNull(lhs), nonNull(rhs)) == 0;
|
||||
}
|
||||
|
||||
// Does this string have useful information in it.
|
||||
inline bool isMeaningful(const char* str)
|
||||
{
|
||||
return *(nonNull(str)) > 0;
|
||||
}
|
||||
|
||||
inline uint32_t safeStrLen(const char* str)
|
||||
{
|
||||
str = nonNull(str);
|
||||
return static_cast<uint32_t>(strlen(str));
|
||||
}
|
||||
|
||||
struct ObjectRef
|
||||
{
|
||||
int32_t mInstanceId;
|
||||
|
||||
ObjectRef(int32_t iid = -1) : mInstanceId(iid)
|
||||
{
|
||||
}
|
||||
operator int32_t() const
|
||||
{
|
||||
return mInstanceId;
|
||||
}
|
||||
bool hasValue() const
|
||||
{
|
||||
return mInstanceId > 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct U32Array4
|
||||
{
|
||||
uint32_t mD0;
|
||||
uint32_t mD1;
|
||||
uint32_t mD2;
|
||||
uint32_t mD3;
|
||||
U32Array4(uint32_t d0, uint32_t d1, uint32_t d2, uint32_t d3) : mD0(d0), mD1(d1), mD2(d2), mD3(d3)
|
||||
{
|
||||
}
|
||||
U32Array4() : mD0(0), mD1(0), mD2(0), mD3(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
typedef bool PvdBool;
|
||||
typedef const char* String;
|
||||
typedef void* VoidPtr;
|
||||
typedef double PvdF64;
|
||||
typedef float PvdF32;
|
||||
typedef int64_t PvdI64;
|
||||
typedef uint64_t PvdU64;
|
||||
typedef int32_t PvdI32;
|
||||
typedef uint32_t PvdU32;
|
||||
typedef int16_t PvdI16;
|
||||
typedef uint16_t PvdU16;
|
||||
typedef int8_t PvdI8;
|
||||
typedef uint8_t PvdU8;
|
||||
|
||||
struct PvdColor
|
||||
{
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
uint8_t a;
|
||||
PvdColor(uint8_t _r, uint8_t _g, uint8_t _b, uint8_t _a = 255) : r(_r), g(_g), b(_b), a(_a)
|
||||
{
|
||||
}
|
||||
PvdColor() : r(0), g(0), b(0), a(255)
|
||||
{
|
||||
}
|
||||
PvdColor(uint32_t abgr)
|
||||
{
|
||||
uint8_t* valPtr = reinterpret_cast<uint8_t*>(&abgr);
|
||||
r = valPtr[0];
|
||||
g = valPtr[1];
|
||||
b = valPtr[2];
|
||||
a = valPtr[3];
|
||||
}
|
||||
};
|
||||
|
||||
struct StringHandle
|
||||
{
|
||||
uint32_t mHandle;
|
||||
StringHandle(uint32_t val = 0) : mHandle(val)
|
||||
{
|
||||
}
|
||||
operator uint32_t() const
|
||||
{
|
||||
return mHandle;
|
||||
}
|
||||
};
|
||||
|
||||
#define DECLARE_TYPES \
|
||||
DECLARE_BASE_PVD_TYPE(PvdI8) \
|
||||
DECLARE_BASE_PVD_TYPE(PvdU8) \
|
||||
DECLARE_BASE_PVD_TYPE(PvdI16) \
|
||||
DECLARE_BASE_PVD_TYPE(PvdU16) \
|
||||
DECLARE_BASE_PVD_TYPE(PvdI32) \
|
||||
DECLARE_BASE_PVD_TYPE(PvdU32) \
|
||||
DECLARE_BASE_PVD_TYPE(PvdI64) \
|
||||
DECLARE_BASE_PVD_TYPE(PvdU64) \
|
||||
DECLARE_BASE_PVD_TYPE(PvdF32) \
|
||||
DECLARE_BASE_PVD_TYPE(PvdF64) \
|
||||
DECLARE_BASE_PVD_TYPE(PvdBool) \
|
||||
DECLARE_BASE_PVD_TYPE(PvdColor) \
|
||||
DECLARE_BASE_PVD_TYPE(String) \
|
||||
DECLARE_BASE_PVD_TYPE(StringHandle) \
|
||||
DECLARE_BASE_PVD_TYPE(ObjectRef) \
|
||||
DECLARE_BASE_PVD_TYPE(VoidPtr) \
|
||||
DECLARE_BASE_PVD_TYPE(PxVec2) \
|
||||
DECLARE_BASE_PVD_TYPE(PxVec3) \
|
||||
DECLARE_BASE_PVD_TYPE(PxVec4) \
|
||||
DECLARE_BASE_PVD_TYPE(PxBounds3) \
|
||||
DECLARE_BASE_PVD_TYPE(PxQuat) \
|
||||
DECLARE_BASE_PVD_TYPE(PxTransform) \
|
||||
DECLARE_BASE_PVD_TYPE(PxMat33) \
|
||||
DECLARE_BASE_PVD_TYPE(PxMat44) \
|
||||
DECLARE_BASE_PVD_TYPE(U32Array4)
|
||||
|
||||
struct PvdBaseType
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
None = 0,
|
||||
InternalStart = 1,
|
||||
InternalStop = 64,
|
||||
#define DECLARE_BASE_PVD_TYPE(type) type,
|
||||
DECLARE_TYPES
|
||||
Last
|
||||
#undef DECLARE_BASE_PVD_TYPE
|
||||
};
|
||||
};
|
||||
struct NamespacedName
|
||||
{
|
||||
String mNamespace;
|
||||
String mName;
|
||||
NamespacedName(String ns, String nm) : mNamespace(ns), mName(nm)
|
||||
{
|
||||
}
|
||||
NamespacedName(String nm = "") : mNamespace(""), mName(nm)
|
||||
{
|
||||
}
|
||||
bool operator==(const NamespacedName& other) const
|
||||
{
|
||||
return safeStrEq(mNamespace, other.mNamespace) && safeStrEq(mName, other.mName);
|
||||
}
|
||||
};
|
||||
|
||||
struct NamedValue
|
||||
{
|
||||
String mName;
|
||||
uint32_t mValue;
|
||||
NamedValue(String nm = "", uint32_t val = 0) : mName(nm), mValue(val)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct BaseDataTypeToTypeMap
|
||||
{
|
||||
bool compile_error;
|
||||
};
|
||||
template <PvdBaseType::Enum>
|
||||
struct BaseTypeToDataTypeMap
|
||||
{
|
||||
bool compile_error;
|
||||
};
|
||||
|
||||
// Users can extend this mapping with new datatypes.
|
||||
template <typename T>
|
||||
struct PvdDataTypeToNamespacedNameMap
|
||||
{
|
||||
bool Name;
|
||||
};
|
||||
// This mapping tells you the what class id to use for the base datatypes
|
||||
//
|
||||
#define DECLARE_BASE_PVD_TYPE(type) \
|
||||
template <> \
|
||||
struct BaseDataTypeToTypeMap<type> \
|
||||
{ \
|
||||
enum Enum \
|
||||
{ \
|
||||
BaseTypeEnum = PvdBaseType::type \
|
||||
}; \
|
||||
}; \
|
||||
template <> \
|
||||
struct BaseDataTypeToTypeMap<const type&> \
|
||||
{ \
|
||||
enum Enum \
|
||||
{ \
|
||||
BaseTypeEnum = PvdBaseType::type \
|
||||
}; \
|
||||
}; \
|
||||
template <> \
|
||||
struct BaseTypeToDataTypeMap<PvdBaseType::type> \
|
||||
{ \
|
||||
typedef type TDataType; \
|
||||
}; \
|
||||
template <> \
|
||||
struct PvdDataTypeToNamespacedNameMap<type> \
|
||||
{ \
|
||||
NamespacedName Name; \
|
||||
PvdDataTypeToNamespacedNameMap<type>() : Name("physx3", #type) \
|
||||
{ \
|
||||
} \
|
||||
}; \
|
||||
template <> \
|
||||
struct PvdDataTypeToNamespacedNameMap<const type&> \
|
||||
{ \
|
||||
NamespacedName Name; \
|
||||
PvdDataTypeToNamespacedNameMap<const type&>() : Name("physx3", #type) \
|
||||
{ \
|
||||
} \
|
||||
};
|
||||
|
||||
DECLARE_TYPES
|
||||
#undef DECLARE_BASE_PVD_TYPE
|
||||
|
||||
template <typename TDataType>
|
||||
inline int32_t getPvdTypeForType()
|
||||
{
|
||||
return static_cast<PvdBaseType::Enum>(BaseDataTypeToTypeMap<TDataType>::BaseTypeEnum);
|
||||
}
|
||||
template <typename TDataType>
|
||||
inline NamespacedName getPvdNamespacedNameForType()
|
||||
{
|
||||
return PvdDataTypeToNamespacedNameMap<TDataType>().Name;
|
||||
}
|
||||
|
||||
#define DEFINE_PVD_TYPE_NAME_MAP(type, ns, name) \
|
||||
template <> \
|
||||
struct PvdDataTypeToNamespacedNameMap<type> \
|
||||
{ \
|
||||
NamespacedName Name; \
|
||||
PvdDataTypeToNamespacedNameMap<type>() : Name(ns, name) \
|
||||
{ \
|
||||
} \
|
||||
};
|
||||
|
||||
#define DEFINE_PVD_TYPE_ALIAS(newType, oldType) \
|
||||
template <> \
|
||||
struct PvdDataTypeToNamespacedNameMap<newType> \
|
||||
{ \
|
||||
NamespacedName Name; \
|
||||
PvdDataTypeToNamespacedNameMap<newType>() : Name(PvdDataTypeToNamespacedNameMap<oldType>().Name) \
|
||||
{ \
|
||||
} \
|
||||
};
|
||||
|
||||
DEFINE_PVD_TYPE_ALIAS(const void*, void*)
|
||||
|
||||
struct ArrayData
|
||||
{
|
||||
uint8_t* mBegin;
|
||||
uint8_t* mEnd;
|
||||
uint8_t* mCapacity; //>= stop
|
||||
ArrayData(uint8_t* beg = NULL, uint8_t* end = NULL, uint8_t* cap = NULL) : mBegin(beg), mEnd(end), mCapacity(cap)
|
||||
{
|
||||
}
|
||||
uint8_t* begin()
|
||||
{
|
||||
return mBegin;
|
||||
}
|
||||
uint8_t* end()
|
||||
{
|
||||
return mEnd;
|
||||
}
|
||||
uint32_t byteCapacity()
|
||||
{
|
||||
return static_cast<uint32_t>(mCapacity - mBegin);
|
||||
}
|
||||
uint32_t byteSize() const
|
||||
{
|
||||
return static_cast<uint32_t>(mEnd - mBegin);
|
||||
} // in bytes
|
||||
uint32_t numberOfItems(uint32_t objectByteSize)
|
||||
{
|
||||
if(objectByteSize)
|
||||
return byteSize() / objectByteSize;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void forgetData()
|
||||
{
|
||||
mBegin = mEnd = mCapacity = 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class DataRef
|
||||
{
|
||||
const T* mBegin;
|
||||
const T* mEnd;
|
||||
|
||||
public:
|
||||
DataRef(const T* b, uint32_t count) : mBegin(b), mEnd(b + count)
|
||||
{
|
||||
}
|
||||
DataRef(const T* b = NULL, const T* e = NULL) : mBegin(b), mEnd(e)
|
||||
{
|
||||
}
|
||||
DataRef(const DataRef& o) : mBegin(o.mBegin), mEnd(o.mEnd)
|
||||
{
|
||||
}
|
||||
DataRef& operator=(const DataRef& o)
|
||||
{
|
||||
mBegin = o.mBegin;
|
||||
mEnd = o.mEnd;
|
||||
return *this;
|
||||
}
|
||||
uint32_t size() const
|
||||
{
|
||||
return static_cast<uint32_t>(mEnd - mBegin);
|
||||
}
|
||||
const T* begin() const
|
||||
{
|
||||
return mBegin;
|
||||
}
|
||||
const T* end() const
|
||||
{
|
||||
return mEnd;
|
||||
}
|
||||
const T& operator[](uint32_t idx) const
|
||||
{
|
||||
PX_ASSERT(idx < size());
|
||||
return mBegin[idx];
|
||||
}
|
||||
const T& back() const
|
||||
{
|
||||
PX_ASSERT(mEnd > mBegin);
|
||||
return *(mEnd - 1);
|
||||
}
|
||||
};
|
||||
|
||||
struct PropertyType
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Unknown = 0,
|
||||
Scalar,
|
||||
Array
|
||||
};
|
||||
};
|
||||
|
||||
// argument to the create property message function
|
||||
struct PropertyMessageArg
|
||||
{
|
||||
String mPropertyName;
|
||||
NamespacedName mDatatypeName;
|
||||
// where in the message this property starts.
|
||||
uint32_t mMessageOffset;
|
||||
// size of this entry object
|
||||
uint32_t mByteSize;
|
||||
|
||||
PropertyMessageArg(String propName, NamespacedName dtype, uint32_t msgOffset, uint32_t byteSize)
|
||||
: mPropertyName(propName), mDatatypeName(dtype), mMessageOffset(msgOffset), mByteSize(byteSize)
|
||||
{
|
||||
}
|
||||
PropertyMessageArg() : mPropertyName(""), mMessageOffset(0), mByteSize(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class PvdUserRenderer;
|
||||
DEFINE_PVD_TYPE_NAME_MAP(PvdUserRenderer, "_debugger_", "PvdUserRenderer")
|
||||
|
||||
#if !PX_DOXYGEN
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
#endif // PXPVDSDK_PXPVDOBJECTMODELBASETYPES_H
|
||||
140
physx/source/pvd/include/PxPvdRenderBuffer.h
Normal file
140
physx/source/pvd/include/PxPvdRenderBuffer.h
Normal file
@ -0,0 +1,140 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifndef PXPVDSDK_PXPVDRENDERBUFFER_H
|
||||
#define PXPVDSDK_PXPVDRENDERBUFFER_H
|
||||
|
||||
/** \addtogroup pvd
|
||||
@{
|
||||
*/
|
||||
|
||||
#include "foundation/PxVec3.h"
|
||||
|
||||
#if !PX_DOXYGEN
|
||||
namespace physx
|
||||
{
|
||||
namespace pvdsdk
|
||||
{
|
||||
#endif
|
||||
|
||||
/**
|
||||
\brief Default color values used for debug rendering.
|
||||
*/
|
||||
struct PvdDebugColor
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
eARGB_BLACK = 0xff000000,
|
||||
eARGB_RED = 0xffff0000,
|
||||
eARGB_GREEN = 0xff00ff00,
|
||||
eARGB_BLUE = 0xff0000ff,
|
||||
eARGB_YELLOW = 0xffffff00,
|
||||
eARGB_MAGENTA = 0xffff00ff,
|
||||
eARGB_CYAN = 0xff00ffff,
|
||||
eARGB_WHITE = 0xffffffff,
|
||||
eARGB_GREY = 0xff808080,
|
||||
eARGB_DARKRED = 0x88880000,
|
||||
eARGB_DARKGREEN = 0x88008800,
|
||||
eARGB_DARKBLUE = 0x88000088
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Used to store a single point and colour for debug rendering.
|
||||
*/
|
||||
struct PvdDebugPoint
|
||||
{
|
||||
PvdDebugPoint(const PxVec3& p, const uint32_t& c) : pos(p), color(c)
|
||||
{
|
||||
}
|
||||
|
||||
PxVec3 pos;
|
||||
uint32_t color;
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Used to store a single line and colour for debug rendering.
|
||||
*/
|
||||
struct PvdDebugLine
|
||||
{
|
||||
PvdDebugLine(const PxVec3& p0, const PxVec3& p1, const uint32_t& c) : pos0(p0), color0(c), pos1(p1), color1(c)
|
||||
{
|
||||
}
|
||||
|
||||
PxVec3 pos0;
|
||||
uint32_t color0;
|
||||
PxVec3 pos1;
|
||||
uint32_t color1;
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Used to store a single triangle and colour for debug rendering.
|
||||
*/
|
||||
struct PvdDebugTriangle
|
||||
{
|
||||
PvdDebugTriangle(const PxVec3& p0, const PxVec3& p1, const PxVec3& p2, const uint32_t& c)
|
||||
: pos0(p0), color0(c), pos1(p1), color1(c), pos2(p2), color2(c)
|
||||
{
|
||||
}
|
||||
|
||||
PxVec3 pos0;
|
||||
uint32_t color0;
|
||||
PxVec3 pos1;
|
||||
uint32_t color1;
|
||||
PxVec3 pos2;
|
||||
uint32_t color2;
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Used to store a text for debug rendering. Doesn't own 'string' array.
|
||||
*/
|
||||
struct PvdDebugText
|
||||
{
|
||||
PvdDebugText() : string(0)
|
||||
{
|
||||
}
|
||||
|
||||
PvdDebugText(const PxVec3& p, const float& s, const uint32_t& c, const char* str)
|
||||
: position(p), size(s), color(c), string(str)
|
||||
{
|
||||
}
|
||||
|
||||
PxVec3 position;
|
||||
float size;
|
||||
uint32_t color;
|
||||
const char* string;
|
||||
};
|
||||
|
||||
#if !PX_DOXYGEN
|
||||
}
|
||||
} // namespace physx
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
#endif // PXPVDSDK_PXPVDRENDERBUFFER_H
|
||||
107
physx/source/pvd/include/PxPvdUserRenderer.h
Normal file
107
physx/source/pvd/include/PxPvdUserRenderer.h
Normal file
@ -0,0 +1,107 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
#ifndef PXPVDSDK_PXPVDUSERRENDERER_H
|
||||
#define PXPVDSDK_PXPVDUSERRENDERER_H
|
||||
|
||||
/** \addtogroup pvd
|
||||
@{
|
||||
*/
|
||||
#include "foundation/PxVec3.h"
|
||||
#include "foundation/PxTransform.h"
|
||||
#include "pvd/PxPvd.h"
|
||||
|
||||
#include "PxPvdDataStream.h"
|
||||
#include "PxPvdRenderBuffer.h"
|
||||
#include "PsUserAllocated.h"
|
||||
|
||||
#if !PX_DOXYGEN
|
||||
namespace physx
|
||||
{
|
||||
#endif
|
||||
|
||||
class PxPvd;
|
||||
|
||||
#if !PX_DOXYGEN
|
||||
namespace pvdsdk
|
||||
{
|
||||
#endif
|
||||
|
||||
class RendererEventClient;
|
||||
|
||||
class PvdUserRenderer : public shdfnd::UserAllocated
|
||||
{
|
||||
protected:
|
||||
virtual ~PvdUserRenderer()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
virtual void release() = 0;
|
||||
virtual void setClient(RendererEventClient* client) = 0;
|
||||
|
||||
// Instance to associate the further rendering with.
|
||||
virtual void setInstanceId(const void* instanceId) = 0;
|
||||
// Draw these points associated with this instance
|
||||
virtual void drawPoints(const PvdDebugPoint* points, uint32_t count) = 0;
|
||||
// Draw these lines associated with this instance
|
||||
virtual void drawLines(const PvdDebugLine* lines, uint32_t count) = 0;
|
||||
// Draw these triangles associated with this instance
|
||||
virtual void drawTriangles(const PvdDebugTriangle* triangles, uint32_t count) = 0;
|
||||
// Draw this text associated with this instance
|
||||
virtual void drawText(const PvdDebugText& text) = 0;
|
||||
|
||||
// Draw SDK debug render
|
||||
virtual void drawRenderbuffer(const PvdDebugPoint* pointData, uint32_t pointCount, const PvdDebugLine* lineData,
|
||||
uint32_t lineCount, const PvdDebugTriangle* triangleData, uint32_t triangleCount) = 0;
|
||||
|
||||
// Constraint visualization routines
|
||||
virtual void visualizeJointFrames(const PxTransform& parent, const PxTransform& child) = 0;
|
||||
virtual void visualizeLinearLimit(const PxTransform& t0, const PxTransform& t1, float value, bool active) = 0;
|
||||
virtual void visualizeAngularLimit(const PxTransform& t0, float lower, float upper, bool active) = 0;
|
||||
virtual void visualizeLimitCone(const PxTransform& t, float tanQSwingY, float tanQSwingZ, bool active) = 0;
|
||||
virtual void visualizeDoubleCone(const PxTransform& t, float angle, bool active) = 0;
|
||||
|
||||
// Clear the immedate buffer.
|
||||
virtual void flushRenderEvents() = 0;
|
||||
|
||||
static PvdUserRenderer* create(uint32_t bufferSize = 0x2000);
|
||||
};
|
||||
|
||||
class RendererEventClient
|
||||
{
|
||||
public:
|
||||
virtual ~RendererEventClient(){}
|
||||
|
||||
virtual void handleBufferFlush(const uint8_t* inData, uint32_t inLength) = 0;
|
||||
};
|
||||
|
||||
#if !PX_DOXYGEN
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/** @} */
|
||||
#endif // PXPVDSDK_PXPVDUSERRENDERER_H
|
||||
58
physx/source/pvd/src/PxProfileContextProvider.h
Normal file
58
physx/source/pvd/src/PxProfileContextProvider.h
Normal file
@ -0,0 +1,58 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef PXPVDSDK_PXPROFILECONTEXTPROVIDER_H
|
||||
#define PXPVDSDK_PXPROFILECONTEXTPROVIDER_H
|
||||
|
||||
#include "foundation/Px.h"
|
||||
|
||||
namespace physx { namespace profile {
|
||||
|
||||
struct PxProfileEventExecutionContext
|
||||
{
|
||||
uint32_t mThreadId;
|
||||
uint8_t mCpuId;
|
||||
uint8_t mThreadPriority;
|
||||
|
||||
PxProfileEventExecutionContext( uint32_t inThreadId = 0, uint8_t inThreadPriority = 2 /*eThreadPriorityNormal*/, uint8_t inCpuId = 0 )
|
||||
: mThreadId( inThreadId )
|
||||
, mCpuId( inCpuId )
|
||||
, mThreadPriority( inThreadPriority )
|
||||
{
|
||||
}
|
||||
|
||||
bool operator==( const PxProfileEventExecutionContext& inOther ) const
|
||||
{
|
||||
return mThreadId == inOther.mThreadId
|
||||
&& mCpuId == inOther.mCpuId
|
||||
&& mThreadPriority == inOther.mThreadPriority;
|
||||
}
|
||||
};
|
||||
|
||||
} }
|
||||
|
||||
#endif // PXPVDSDK_PXPROFILECONTEXTPROVIDER_H
|
||||
52
physx/source/pvd/src/PxProfileContextProviderImpl.h
Normal file
52
physx/source/pvd/src/PxProfileContextProviderImpl.h
Normal file
@ -0,0 +1,52 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef PXPVDSDK_PXPROFILECONTEXTPROVIDERIMPL_H
|
||||
#define PXPVDSDK_PXPROFILECONTEXTPROVIDERIMPL_H
|
||||
|
||||
#include "PxProfileContextProvider.h"
|
||||
|
||||
#include "PsThread.h"
|
||||
|
||||
namespace physx { namespace profile {
|
||||
|
||||
struct PxDefaultContextProvider
|
||||
{
|
||||
PxProfileEventExecutionContext getExecutionContext()
|
||||
{
|
||||
shdfnd::Thread::Id theId( shdfnd::Thread::getId() );
|
||||
return PxProfileEventExecutionContext( static_cast<uint32_t>( theId ), static_cast<uint8_t>( shdfnd::ThreadPriority::eNORMAL ), 0 );
|
||||
}
|
||||
|
||||
uint32_t getThreadId()
|
||||
{
|
||||
return static_cast<uint32_t>( shdfnd::Thread::getId() );
|
||||
}
|
||||
};
|
||||
} }
|
||||
|
||||
#endif // PXPVDSDK_PXPROFILECONTEXTPROVIDERIMPL_H
|
||||
167
physx/source/pvd/src/PxProfileDataBuffer.h
Normal file
167
physx/source/pvd/src/PxProfileDataBuffer.h
Normal file
@ -0,0 +1,167 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
|
||||
#ifndef PXPVDSDK_PXPROFILEDATABUFFER_H
|
||||
#define PXPVDSDK_PXPROFILEDATABUFFER_H
|
||||
|
||||
#include "PxProfileAllocatorWrapper.h"
|
||||
#include "PxProfileMemoryBuffer.h"
|
||||
#include "PxProfileEventBufferClient.h"
|
||||
|
||||
namespace physx { namespace profile {
|
||||
|
||||
template<typename TMutex
|
||||
, typename TScopedLock>
|
||||
class DataBuffer //base class for buffers that cache data and then dump the data to clients.
|
||||
{
|
||||
public:
|
||||
typedef TMutex TMutexType;
|
||||
typedef TScopedLock TScopedLockType;
|
||||
typedef PxProfileWrapperNamedAllocator TU8AllocatorType;
|
||||
|
||||
typedef MemoryBuffer<TU8AllocatorType > TMemoryBufferType;
|
||||
typedef PxProfileArray<PxProfileEventBufferClient*> TBufferClientArray;
|
||||
|
||||
protected:
|
||||
|
||||
PxProfileAllocatorWrapper mWrapper;
|
||||
TMemoryBufferType mDataArray;
|
||||
TBufferClientArray mBufferClients;
|
||||
uint32_t mBufferFullAmount;
|
||||
EventContextInformation mEventContextInformation;
|
||||
TMutexType* mBufferMutex;
|
||||
volatile bool mHasClients;
|
||||
EventSerializer<TMemoryBufferType > mSerializer;
|
||||
|
||||
public:
|
||||
|
||||
DataBuffer( PxAllocatorCallback* inFoundation
|
||||
, uint32_t inBufferFullAmount
|
||||
, TMutexType* inBufferMutex
|
||||
, const char* inAllocationName )
|
||||
: mWrapper( inFoundation )
|
||||
, mDataArray( TU8AllocatorType( mWrapper, inAllocationName ) )
|
||||
, mBufferClients( mWrapper )
|
||||
, mBufferFullAmount( inBufferFullAmount )
|
||||
, mBufferMutex( inBufferMutex )
|
||||
, mHasClients( false )
|
||||
, mSerializer( &mDataArray )
|
||||
{
|
||||
//The data array is never resized really. We ensure
|
||||
//it is bigger than it will ever need to be.
|
||||
mDataArray.reserve( inBufferFullAmount + 68 );
|
||||
}
|
||||
|
||||
virtual ~DataBuffer()
|
||||
{
|
||||
while(mBufferClients.size() )
|
||||
{
|
||||
removeClient( *mBufferClients[0] );
|
||||
}
|
||||
}
|
||||
|
||||
PxProfileAllocatorWrapper& getWrapper() { return mWrapper; }
|
||||
TMutexType* getBufferMutex() { return mBufferMutex; }
|
||||
void setBufferMutex(TMutexType* mutex) { mBufferMutex = mutex; }
|
||||
|
||||
void addClient( PxProfileEventBufferClient& inClient )
|
||||
{
|
||||
TScopedLockType lock( mBufferMutex );
|
||||
mBufferClients.pushBack( &inClient );
|
||||
mHasClients = true;
|
||||
}
|
||||
|
||||
void removeClient( PxProfileEventBufferClient& inClient )
|
||||
{
|
||||
TScopedLockType lock( mBufferMutex );
|
||||
for ( uint32_t idx =0; idx < mBufferClients.size(); ++idx )
|
||||
{
|
||||
if (mBufferClients[idx] == &inClient )
|
||||
{
|
||||
inClient.handleClientRemoved();
|
||||
mBufferClients.replaceWithLast( idx );
|
||||
break;
|
||||
}
|
||||
}
|
||||
mHasClients = mBufferClients.size() != 0;
|
||||
}
|
||||
|
||||
|
||||
bool hasClients() const
|
||||
{
|
||||
return mHasClients;
|
||||
}
|
||||
|
||||
virtual void flushEvents()
|
||||
{
|
||||
TScopedLockType lock(mBufferMutex);
|
||||
const uint8_t* theData = mDataArray.begin();
|
||||
uint32_t theDataSize = mDataArray.size();
|
||||
sendDataToClients(theData, theDataSize);
|
||||
mDataArray.clear();
|
||||
clearCachedData();
|
||||
}
|
||||
|
||||
//Used for chaining together event buffers.
|
||||
virtual void handleBufferFlush( const uint8_t* inData, uint32_t inDataSize )
|
||||
{
|
||||
TScopedLockType lock( mBufferMutex );
|
||||
if ( inData && inDataSize )
|
||||
{
|
||||
clearCachedData();
|
||||
if ( mDataArray.size() + inDataSize >= mBufferFullAmount )
|
||||
flushEvents();
|
||||
if ( inDataSize >= mBufferFullAmount )
|
||||
sendDataToClients( inData, inDataSize );
|
||||
else
|
||||
mDataArray.write( inData, inDataSize );
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void clearCachedData()
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void sendDataToClients( const uint8_t* inData, uint32_t inDataSize )
|
||||
{
|
||||
uint32_t clientCount = mBufferClients.size();
|
||||
for( uint32_t idx =0; idx < clientCount; ++idx )
|
||||
mBufferClients[idx]->handleBufferFlush( inData, inDataSize );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
|
||||
#endif // PXPVDSDK_PXPROFILEDATABUFFER_H
|
||||
218
physx/source/pvd/src/PxProfileDataParsing.h
Normal file
218
physx/source/pvd/src/PxProfileDataParsing.h
Normal file
@ -0,0 +1,218 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
|
||||
#ifndef PXPVDSDK_PXPROFILEDATAPARSING_H
|
||||
#define PXPVDSDK_PXPROFILEDATAPARSING_H
|
||||
|
||||
#include "foundation/Px.h"
|
||||
|
||||
namespace physx { namespace profile {
|
||||
|
||||
//Converts datatypes without using type punning.
|
||||
struct BlockParserDataConverter
|
||||
{
|
||||
union
|
||||
{
|
||||
uint8_t mU8[8];
|
||||
uint16_t mU16[4];
|
||||
uint32_t mU32[2];
|
||||
uint64_t mU64[1];
|
||||
|
||||
int8_t mI8[8];
|
||||
int16_t mI16[4];
|
||||
int32_t mI32[2];
|
||||
int64_t mI64[1];
|
||||
|
||||
|
||||
float mF32[2];
|
||||
double mF64[1];
|
||||
};
|
||||
|
||||
template<typename TDataType> inline TDataType convert() { PX_ASSERT( false ); return TDataType(); }
|
||||
|
||||
template<typename TDataType>
|
||||
inline void convert( const TDataType& ) {}
|
||||
};
|
||||
|
||||
template<> inline uint8_t BlockParserDataConverter::convert<uint8_t>() { return mU8[0]; }
|
||||
template<> inline uint16_t BlockParserDataConverter::convert<uint16_t>() { return mU16[0]; }
|
||||
template<> inline uint32_t BlockParserDataConverter::convert<uint32_t>() { return mU32[0]; }
|
||||
template<> inline uint64_t BlockParserDataConverter::convert<uint64_t>() { return mU64[0]; }
|
||||
template<> inline int8_t BlockParserDataConverter::convert<int8_t>() { return mI8[0]; }
|
||||
template<> inline int16_t BlockParserDataConverter::convert<int16_t>() { return mI16[0]; }
|
||||
template<> inline int32_t BlockParserDataConverter::convert<int32_t>() { return mI32[0]; }
|
||||
template<> inline int64_t BlockParserDataConverter::convert<int64_t>() { return mI64[0]; }
|
||||
template<> inline float BlockParserDataConverter::convert<float>() { return mF32[0]; }
|
||||
template<> inline double BlockParserDataConverter::convert<double>() { return mF64[0]; }
|
||||
|
||||
template<> inline void BlockParserDataConverter::convert<uint8_t>( const uint8_t& inData ) { mU8[0] = inData; }
|
||||
template<> inline void BlockParserDataConverter::convert<uint16_t>( const uint16_t& inData ) { mU16[0] = inData; }
|
||||
template<> inline void BlockParserDataConverter::convert<uint32_t>( const uint32_t& inData ) { mU32[0] = inData; }
|
||||
template<> inline void BlockParserDataConverter::convert<uint64_t>( const uint64_t& inData ) { mU64[0] = inData; }
|
||||
template<> inline void BlockParserDataConverter::convert<int8_t>( const int8_t& inData ) { mI8[0] = inData; }
|
||||
template<> inline void BlockParserDataConverter::convert<int16_t>( const int16_t& inData ) { mI16[0] = inData; }
|
||||
template<> inline void BlockParserDataConverter::convert<int32_t>( const int32_t& inData ) { mI32[0] = inData; }
|
||||
template<> inline void BlockParserDataConverter::convert<int64_t>( const int64_t& inData ) { mI64[0] = inData; }
|
||||
template<> inline void BlockParserDataConverter::convert<float>( const float& inData ) { mF32[0] = inData; }
|
||||
template<> inline void BlockParserDataConverter::convert<double>( const double& inData ) { mF64[0] = inData; }
|
||||
|
||||
|
||||
//Handles various details around parsing blocks of uint8_t data.
|
||||
struct BlockParseFunctions
|
||||
{
|
||||
template<uint8_t ByteCount>
|
||||
static inline void swapBytes( uint8_t* inData )
|
||||
{
|
||||
for ( uint32_t idx = 0; idx < ByteCount/2; ++idx )
|
||||
{
|
||||
uint32_t endIdx = ByteCount-idx-1;
|
||||
uint8_t theTemp = inData[idx];
|
||||
inData[idx] = inData[endIdx];
|
||||
inData[endIdx] = theTemp;
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool checkLength( const uint8_t* inStart, const uint8_t* inStop, uint32_t inLength )
|
||||
{
|
||||
return static_cast<uint32_t>(inStop - inStart) >= inLength;
|
||||
}
|
||||
//warning work-around
|
||||
template<typename T>
|
||||
static inline T val(T v) {return v;}
|
||||
|
||||
template<bool DoSwapBytes, typename TDataType>
|
||||
static inline bool parse( const uint8_t*& inStart, const uint8_t* inStop, TDataType& outData )
|
||||
{
|
||||
if ( checkLength( inStart, inStop, sizeof( TDataType ) ) )
|
||||
{
|
||||
BlockParserDataConverter theConverter;
|
||||
for ( uint32_t idx =0; idx < sizeof( TDataType ); ++idx )
|
||||
theConverter.mU8[idx] = inStart[idx];
|
||||
if ( val(DoSwapBytes))
|
||||
swapBytes<sizeof(TDataType)>( theConverter.mU8 );
|
||||
outData = theConverter.convert<TDataType>();
|
||||
inStart += sizeof( TDataType );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<bool DoSwapBytes, typename TDataType>
|
||||
static inline bool parseBlock( const uint8_t*& inStart, const uint8_t* inStop, TDataType* outData, uint32_t inNumItems )
|
||||
{
|
||||
uint32_t desired = sizeof(TDataType)*inNumItems;
|
||||
if ( checkLength( inStart, inStop, desired ) )
|
||||
{
|
||||
if ( val(DoSwapBytes) )
|
||||
{
|
||||
for ( uint32_t item = 0; item < inNumItems; ++item )
|
||||
{
|
||||
BlockParserDataConverter theConverter;
|
||||
for ( uint32_t idx =0; idx < sizeof( TDataType ); ++idx )
|
||||
theConverter.mU8[idx] = inStart[idx];
|
||||
swapBytes<sizeof(TDataType)>( theConverter.mU8 );
|
||||
outData[item] = theConverter.convert<TDataType>();
|
||||
inStart += sizeof(TDataType);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t* target = reinterpret_cast<uint8_t*>(outData);
|
||||
memmove( target, inStart, desired );
|
||||
inStart += desired;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//In-place byte swapping block
|
||||
template<bool DoSwapBytes, typename TDataType>
|
||||
static inline bool parseBlock( uint8_t*& inStart, const uint8_t* inStop, uint32_t inNumItems )
|
||||
{
|
||||
uint32_t desired = sizeof(TDataType)*inNumItems;
|
||||
if ( checkLength( inStart, inStop, desired ) )
|
||||
{
|
||||
if ( val(DoSwapBytes) )
|
||||
{
|
||||
for ( uint32_t item = 0; item < inNumItems; ++item, inStart += sizeof( TDataType ) )
|
||||
swapBytes<sizeof(TDataType)>( inStart ); //In-place swap.
|
||||
}
|
||||
else
|
||||
inStart += sizeof( TDataType ) * inNumItems;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
//Wraps the begin/end keeping track of them.
|
||||
template<bool DoSwapBytes>
|
||||
struct BlockParser
|
||||
{
|
||||
const uint8_t* mBegin;
|
||||
const uint8_t* mEnd;
|
||||
BlockParser( const uint8_t* inBegin=NULL, const uint8_t* inEnd=NULL )
|
||||
: mBegin( inBegin )
|
||||
, mEnd( inEnd )
|
||||
{
|
||||
}
|
||||
inline bool hasMoreData() const { return mBegin != mEnd; }
|
||||
inline bool checkLength( uint32_t inLength ) { return BlockParseFunctions::checkLength( mBegin, mEnd, inLength ); }
|
||||
|
||||
template<typename TDataType>
|
||||
inline bool read( TDataType& outDatatype ) { return BlockParseFunctions::parse<DoSwapBytes>( mBegin, mEnd, outDatatype ); }
|
||||
|
||||
template<typename TDataType>
|
||||
inline bool readBlock( TDataType* outDataPtr, uint32_t inNumItems ) { return BlockParseFunctions::parseBlock<DoSwapBytes>( mBegin, mEnd, outDataPtr, inNumItems ); }
|
||||
|
||||
template<typename TDataType>
|
||||
inline bool readBlock( uint32_t inNumItems )
|
||||
{
|
||||
uint8_t* theTempPtr = const_cast<uint8_t*>(mBegin);
|
||||
bool retval = BlockParseFunctions::parseBlock<DoSwapBytes, TDataType>( theTempPtr, mEnd, inNumItems );
|
||||
mBegin = theTempPtr;
|
||||
return retval;
|
||||
}
|
||||
|
||||
uint32_t amountLeft() const { return static_cast<uint32_t>( mEnd - mBegin ); }
|
||||
};
|
||||
|
||||
//Reads the data without checking for error conditions
|
||||
template<typename TDataType, typename TBlockParserType>
|
||||
inline TDataType blockParserRead( TBlockParserType& inType )
|
||||
{
|
||||
TDataType retval;
|
||||
inType.read( retval );
|
||||
return retval;
|
||||
}
|
||||
}}
|
||||
|
||||
#endif // PXPVDSDK_PXPROFILEDATAPARSING_H
|
||||
267
physx/source/pvd/src/PxProfileEventBuffer.h
Normal file
267
physx/source/pvd/src/PxProfileEventBuffer.h
Normal file
@ -0,0 +1,267 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
|
||||
#ifndef PXPVDSDK_PXPROFILEEVENTBUFFER_H
|
||||
#define PXPVDSDK_PXPROFILEEVENTBUFFER_H
|
||||
|
||||
#include "PxProfileEvents.h"
|
||||
#include "PxProfileEventSerialization.h"
|
||||
#include "PxProfileDataBuffer.h"
|
||||
#include "PxProfileContextProvider.h"
|
||||
|
||||
#include "PsTime.h"
|
||||
|
||||
namespace physx { namespace profile {
|
||||
|
||||
/**
|
||||
* An event buffer maintains an in-memory buffer of events. When this buffer is full
|
||||
* it sends to buffer to all handlers registered and resets the buffer.
|
||||
*
|
||||
* It is parameterized in four ways. The first is a context provider that provides
|
||||
* both thread id and context id.
|
||||
*
|
||||
* The second is the mutex (which may be null) and a scoped locking mechanism. Thus the buffer
|
||||
* may be used in a multithreaded context but clients of the buffer don't pay for this if they
|
||||
* don't intend to use it this way.
|
||||
*
|
||||
* Finally the buffer may use an event filtering mechanism. This mechanism needs one function,
|
||||
* namely isEventEnabled( uint8_t subsystem, uint8_t eventId ).
|
||||
*
|
||||
* All of these systems can be parameterized at compile time leading to an event buffer
|
||||
* that should be as fast as possible given the constraints.
|
||||
*
|
||||
* Buffers may be chained together as this buffer has a handleBufferFlush method that
|
||||
* will grab the mutex and add the data to this event buffer.
|
||||
*
|
||||
* Overall, lets look at the PhysX SDK an how all the pieces fit together.
|
||||
* The SDK should have a mutex-protected event buffer where actual devs or users of PhysX
|
||||
* can register handlers. This buffer has slow but correct implementations of the
|
||||
* context provider interface.
|
||||
*
|
||||
* The SDK object should also have a concrete event filter which was used in the
|
||||
* construction of the event buffer and which it exposes through opaque interfaces.
|
||||
*
|
||||
* The SDK should protect its event buffer and its event filter from multithreaded
|
||||
* access and thus this provides the safest and slowest way to log events and to
|
||||
* enable/disable events.
|
||||
*
|
||||
* Each scene should also have a concrete event filter. This filter is updated from
|
||||
* the SDK event filter (in a mutex protected way) every frame. Thus scenes can change
|
||||
* their event filtering on a frame-by-frame basis. It means that tasks running
|
||||
* under the scene don't need a mutex when accessing the filter.
|
||||
*
|
||||
* Furthermore the scene should have an event buffer that always sets the context id
|
||||
* on each event to the scene. This allows PVD and other systems to correlate events
|
||||
* to scenes. Scenes should provide access only to a relative event sending system
|
||||
* that looks up thread id upon each event but uses the scene id.
|
||||
*
|
||||
* The SDK's event buffer should be setup as an EventBufferClient for each scene's
|
||||
* event buffer. Thus the SDK should expose an EventBufferClient interface that
|
||||
* any client can use.
|
||||
*
|
||||
* For extremely *extremely* performance sensitive areas we should create a specialized
|
||||
* per-scene, per-thread event buffer that is set on the task for these occasions. This buffer
|
||||
* uses a trivial event context setup with the scene's context id and the thread id. It should
|
||||
* share the scene's concrete event filter and it should have absolutely no locking. It should
|
||||
* empty into the scene's event buffer which in some cases should empty into the SDK's event buffer
|
||||
* which when full will push events all the way out of the system. The task should *always* flush
|
||||
* the event buffer (if it has one) when it is finished; nothing else will work reliably.
|
||||
*
|
||||
* If the per-scene,per-thread event buffer is correctly parameterized and fully defined adding
|
||||
* a new event should be an inline operation requiring no mutex grabs in the common case. I don't
|
||||
* believe you can get faster event production than this; the events are as small as possible (all
|
||||
* relative events) and they are all produced inline resulting in one 4 byte header and one
|
||||
* 8 byte timestamp per event. Reducing the memory pressure in this way reduces the communication
|
||||
* overhead, the mutex grabs, basically everything that makes profiling expensive at the cost
|
||||
* of a per-scene,per-thread event buffer (which could easily be reduced to a per-thread event
|
||||
* buffer.
|
||||
*/
|
||||
template<typename TContextProvider,
|
||||
typename TMutex,
|
||||
typename TScopedLock,
|
||||
typename TEventFilter>
|
||||
class EventBuffer : public DataBuffer<TMutex, TScopedLock>
|
||||
{
|
||||
public:
|
||||
typedef DataBuffer<TMutex, TScopedLock> TBaseType;
|
||||
typedef TContextProvider TContextProviderType;
|
||||
typedef TEventFilter TEventFilterType;
|
||||
typedef typename TBaseType::TMutexType TMutexType;
|
||||
typedef typename TBaseType::TScopedLockType TScopedLockType;
|
||||
typedef typename TBaseType::TU8AllocatorType TU8AllocatorType;
|
||||
typedef typename TBaseType::TMemoryBufferType TMemoryBufferType;
|
||||
typedef typename TBaseType::TBufferClientArray TBufferClientArray;
|
||||
|
||||
private:
|
||||
EventContextInformation mEventContextInformation;
|
||||
uint64_t mLastTimestamp;
|
||||
TContextProvider mContextProvider;
|
||||
TEventFilterType mEventFilter;
|
||||
|
||||
public:
|
||||
EventBuffer(PxAllocatorCallback* inFoundation
|
||||
, uint32_t inBufferFullAmount
|
||||
, const TContextProvider& inProvider
|
||||
, TMutexType* inBufferMutex
|
||||
, const TEventFilterType& inEventFilter )
|
||||
: TBaseType( inFoundation, inBufferFullAmount, inBufferMutex, "struct physx::profile::ProfileEvent" )
|
||||
, mLastTimestamp( 0 )
|
||||
, mContextProvider( inProvider )
|
||||
, mEventFilter( inEventFilter )
|
||||
{
|
||||
memset(&mEventContextInformation,0,sizeof(EventContextInformation));
|
||||
}
|
||||
|
||||
TContextProvider& getContextProvider() { return mContextProvider; }
|
||||
|
||||
PX_FORCE_INLINE void startEvent(uint16_t inId, uint32_t threadId, uint64_t contextId, uint8_t cpuId, uint8_t threadPriority, uint64_t inTimestamp)
|
||||
{
|
||||
TScopedLockType lock(TBaseType::mBufferMutex);
|
||||
if ( mEventFilter.isEventEnabled( inId ) )
|
||||
{
|
||||
StartEvent theEvent;
|
||||
theEvent.init( threadId, contextId, cpuId, threadPriority, inTimestamp );
|
||||
doAddProfileEvent( inId, theEvent );
|
||||
}
|
||||
}
|
||||
|
||||
PX_FORCE_INLINE void startEvent(uint16_t inId, uint64_t contextId)
|
||||
{
|
||||
PxProfileEventExecutionContext ctx( mContextProvider.getExecutionContext() );
|
||||
startEvent( inId, ctx.mThreadId, contextId, ctx.mCpuId, static_cast<uint8_t>(ctx.mThreadPriority), shdfnd::Time::getCurrentCounterValue() );
|
||||
}
|
||||
|
||||
PX_FORCE_INLINE void startEvent(uint16_t inId, uint64_t contextId, uint32_t threadId)
|
||||
{
|
||||
startEvent( inId, threadId, contextId, 0, 0, shdfnd::Time::getCurrentCounterValue() );
|
||||
}
|
||||
|
||||
PX_FORCE_INLINE void stopEvent(uint16_t inId, uint32_t threadId, uint64_t contextId, uint8_t cpuId, uint8_t threadPriority, uint64_t inTimestamp)
|
||||
{
|
||||
TScopedLockType lock(TBaseType::mBufferMutex);
|
||||
if ( mEventFilter.isEventEnabled( inId ) )
|
||||
{
|
||||
StopEvent theEvent;
|
||||
theEvent.init( threadId, contextId, cpuId, threadPriority, inTimestamp );
|
||||
doAddProfileEvent( inId, theEvent );
|
||||
}
|
||||
}
|
||||
|
||||
PX_FORCE_INLINE void stopEvent(uint16_t inId, uint64_t contextId)
|
||||
{
|
||||
PxProfileEventExecutionContext ctx( mContextProvider.getExecutionContext() );
|
||||
stopEvent( inId, ctx.mThreadId, contextId, ctx.mCpuId, static_cast<uint8_t>(ctx.mThreadPriority), shdfnd::Time::getCurrentCounterValue() );
|
||||
}
|
||||
|
||||
PX_FORCE_INLINE void stopEvent(uint16_t inId, uint64_t contextId, uint32_t threadId)
|
||||
{
|
||||
stopEvent( inId, threadId, contextId, 0, 0, shdfnd::Time::getCurrentCounterValue() );
|
||||
}
|
||||
|
||||
inline void eventValue( uint16_t inId, uint64_t contextId, int64_t inValue )
|
||||
{
|
||||
eventValue( inId, mContextProvider.getThreadId(), contextId, inValue );
|
||||
}
|
||||
|
||||
inline void eventValue( uint16_t inId, uint32_t threadId, uint64_t contextId, int64_t inValue )
|
||||
{
|
||||
TScopedLockType lock( TBaseType::mBufferMutex );
|
||||
EventValue theEvent;
|
||||
theEvent.init( inValue, contextId, threadId );
|
||||
EventHeader theHeader( static_cast<uint8_t>( getEventType<EventValue>() ), inId );
|
||||
//set the header relative timestamp;
|
||||
EventValue& theType( theEvent );
|
||||
theType.setupHeader( theHeader );
|
||||
sendEvent( theHeader, theType );
|
||||
}
|
||||
|
||||
void flushProfileEvents()
|
||||
{
|
||||
TBaseType::flushEvents();
|
||||
}
|
||||
|
||||
void release()
|
||||
{
|
||||
PX_PROFILE_DELETE( TBaseType::mWrapper.mUserFoundation, this );
|
||||
}
|
||||
protected:
|
||||
//Clears the cache meaning event compression
|
||||
//starts over again.
|
||||
//only called when the buffer mutex is held
|
||||
void clearCachedData()
|
||||
{
|
||||
mEventContextInformation.setToDefault();
|
||||
mLastTimestamp = 0;
|
||||
}
|
||||
|
||||
template<typename TProfileEventType>
|
||||
PX_FORCE_INLINE void doAddProfileEvent(uint16_t eventId, const TProfileEventType& inType)
|
||||
{
|
||||
TScopedLockType lock(TBaseType::mBufferMutex);
|
||||
if (mEventContextInformation == inType.mContextInformation)
|
||||
doAddEvent(static_cast<uint8_t>(inType.getRelativeEventType()), eventId, inType.getRelativeEvent());
|
||||
else
|
||||
{
|
||||
mEventContextInformation = inType.mContextInformation;
|
||||
doAddEvent( static_cast<uint8_t>( getEventType<TProfileEventType>() ), eventId, inType );
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TDataType>
|
||||
PX_FORCE_INLINE void doAddEvent(uint8_t inEventType, uint16_t eventId, const TDataType& inType)
|
||||
{
|
||||
EventHeader theHeader( inEventType, eventId );
|
||||
//set the header relative timestamp;
|
||||
TDataType& theType( const_cast<TDataType&>( inType ) );
|
||||
uint64_t currentTs = inType.getTimestamp();
|
||||
theType.setupHeader(theHeader, mLastTimestamp);
|
||||
mLastTimestamp = currentTs;
|
||||
sendEvent( theHeader, theType );
|
||||
}
|
||||
|
||||
template<typename TDataType>
|
||||
PX_FORCE_INLINE void sendEvent( EventHeader& inHeader, TDataType& inType )
|
||||
{
|
||||
uint32_t sizeToWrite = sizeof(inHeader) + inType.getEventSize(inHeader);
|
||||
PX_UNUSED(sizeToWrite);
|
||||
|
||||
uint32_t writtenSize = inHeader.streamify( TBaseType::mSerializer );
|
||||
writtenSize += inType.streamify(TBaseType::mSerializer, inHeader);
|
||||
|
||||
PX_ASSERT(writtenSize == sizeToWrite);
|
||||
|
||||
if ( TBaseType::mDataArray.size() >= TBaseType::mBufferFullAmount )
|
||||
flushProfileEvents();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
}}
|
||||
#endif // PXPVDSDK_PXPROFILEEVENTBUFFER_H
|
||||
318
physx/source/pvd/src/PxProfileEventBufferAtomic.h
Normal file
318
physx/source/pvd/src/PxProfileEventBufferAtomic.h
Normal file
@ -0,0 +1,318 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
|
||||
#ifndef PXPVDSDK_PXPROFILEEVENTBUFFERATOMIC_H
|
||||
#define PXPVDSDK_PXPROFILEEVENTBUFFERATOMIC_H
|
||||
|
||||
#include "PxProfileEvents.h"
|
||||
#include "PxProfileEventSerialization.h"
|
||||
#include "PxProfileDataBuffer.h"
|
||||
|
||||
#include "PsArray.h"
|
||||
#include "PsAlloca.h"
|
||||
#include "PsTime.h"
|
||||
#include "PsCpu.h"
|
||||
#include "PsAtomic.h"
|
||||
#include "PsAllocator.h"
|
||||
|
||||
|
||||
namespace physx {
|
||||
namespace profile {
|
||||
|
||||
static const uint32_t LOCAL_BUFFER_SIZE = 512;
|
||||
|
||||
/**
|
||||
* An event buffer maintains an in-memory buffer of events. When this buffer is full
|
||||
* it sends to buffer to all handlers registered and resets the buffer.
|
||||
*
|
||||
* It is parameterized in four ways. The first is a context provider that provides
|
||||
* both thread id and context id.
|
||||
*
|
||||
* The second is the mutex (which may be null) and a scoped locking mechanism. Thus the buffer
|
||||
* may be used in a multithreaded context but clients of the buffer don't pay for this if they
|
||||
* don't intend to use it this way.
|
||||
*
|
||||
* Finally the buffer may use an event filtering mechanism. This mechanism needs one function,
|
||||
* namely isEventEnabled( uint8_t subsystem, uint8_t eventId ).
|
||||
*
|
||||
* All of these systems can be parameterized at compile time leading to an event buffer
|
||||
* that should be as fast as possible given the constraints.
|
||||
*
|
||||
* Buffers may be chained together as this buffer has a handleBufferFlush method that
|
||||
* will grab the mutex and add the data to this event buffer.
|
||||
*
|
||||
* Overall, lets look at the PhysX SDK an how all the pieces fit together.
|
||||
* The SDK should have a mutex-protected event buffer where actual devs or users of PhysX
|
||||
* can register handlers. This buffer has slow but correct implementations of the
|
||||
* context provider interface.
|
||||
*
|
||||
* The SDK object should also have a concrete event filter which was used in the
|
||||
* construction of the event buffer and which it exposes through opaque interfaces.
|
||||
*
|
||||
* The SDK should protect its event buffer and its event filter from multithreaded
|
||||
* access and thus this provides the safest and slowest way to log events and to
|
||||
* enable/disable events.
|
||||
*
|
||||
* Each scene should also have a concrete event filter. This filter is updated from
|
||||
* the SDK event filter (in a mutex protected way) every frame. Thus scenes can change
|
||||
* their event filtering on a frame-by-frame basis. It means that tasks running
|
||||
* under the scene don't need a mutex when accessing the filter.
|
||||
*
|
||||
* Furthermore the scene should have an event buffer that always sets the context id
|
||||
* on each event to the scene. This allows PVD and other systems to correlate events
|
||||
* to scenes. Scenes should provide access only to a relative event sending system
|
||||
* that looks up thread id upon each event but uses the scene id.
|
||||
*
|
||||
* The SDK's event buffer should be setup as an EventBufferClient for each scene's
|
||||
* event buffer. Thus the SDK should expose an EventBufferClient interface that
|
||||
* any client can use.
|
||||
*
|
||||
* For extremely *extremely* performance sensitive areas we should create a specialized
|
||||
* per-scene, per-thread event buffer that is set on the task for these occasions. This buffer
|
||||
* uses a trivial event context setup with the scene's context id and the thread id. It should
|
||||
* share the scene's concrete event filter and it should have absolutely no locking. It should
|
||||
* empty into the scene's event buffer which in some cases should empty into the SDK's event buffer
|
||||
* which when full will push events all the way out of the system. The task should *always* flush
|
||||
* the event buffer (if it has one) when it is finished; nothing else will work reliably.
|
||||
*
|
||||
* If the per-scene,per-thread event buffer is correctly parameterized and fully defined adding
|
||||
* a new event should be an inline operation requiring no mutex grabs in the common case. I don't
|
||||
* believe you can get faster event production than this; the events are as small as possible (all
|
||||
* relative events) and they are all produced inline resulting in one 4 byte header and one
|
||||
* 8 byte timestamp per event. Reducing the memory pressure in this way reduces the communication
|
||||
* overhead, the mutex grabs, basically everything that makes profiling expensive at the cost
|
||||
* of a per-scene,per-thread event buffer (which could easily be reduced to a per-thread event
|
||||
* buffer.
|
||||
*/
|
||||
template<typename TContextProvider,
|
||||
typename TMutex,
|
||||
typename TScopedLock,
|
||||
typename TEventFilter>
|
||||
class EventBufferAtomic : public DataBuffer < TMutex, TScopedLock >
|
||||
{
|
||||
public:
|
||||
typedef DataBuffer<TMutex, TScopedLock> TBaseType;
|
||||
typedef TContextProvider TContextProviderType;
|
||||
typedef TEventFilter TEventFilterType;
|
||||
typedef typename TBaseType::TMutexType TMutexType;
|
||||
typedef typename TBaseType::TScopedLockType TScopedLockType;
|
||||
typedef typename TBaseType::TU8AllocatorType TU8AllocatorType;
|
||||
typedef typename TBaseType::TMemoryBufferType TMemoryBufferType;
|
||||
typedef typename TBaseType::TBufferClientArray TBufferClientArray;
|
||||
|
||||
private:
|
||||
TContextProvider mContextProvider;
|
||||
TEventFilterType mEventFilter;
|
||||
volatile int32_t mReserved;
|
||||
volatile int32_t mWritten;
|
||||
|
||||
public:
|
||||
EventBufferAtomic(PxAllocatorCallback* inFoundation
|
||||
, uint32_t inBufferFullAmount
|
||||
, const TContextProvider& inProvider
|
||||
, TMutexType* inBufferMutex
|
||||
, const TEventFilterType& inEventFilter)
|
||||
: TBaseType(inFoundation, inBufferFullAmount, inBufferMutex, "struct physx::profile::ProfileEvent")
|
||||
, mContextProvider(inProvider)
|
||||
, mEventFilter(inEventFilter)
|
||||
, mReserved(0)
|
||||
, mWritten(0)
|
||||
{
|
||||
}
|
||||
|
||||
TContextProvider& getContextProvider() { return mContextProvider; }
|
||||
|
||||
PX_FORCE_INLINE void startEvent(uint16_t inId, uint32_t threadId, uint64_t contextId, uint8_t cpuId, uint8_t threadPriority, uint64_t inTimestamp)
|
||||
{
|
||||
if (mEventFilter.isEventEnabled(inId))
|
||||
{
|
||||
StartEvent theEvent;
|
||||
theEvent.init(threadId, contextId, cpuId, threadPriority, inTimestamp);
|
||||
doAddProfileEvent(inId, theEvent);
|
||||
}
|
||||
}
|
||||
|
||||
PX_FORCE_INLINE void startEvent(uint16_t inId, uint64_t contextId)
|
||||
{
|
||||
PxProfileEventExecutionContext ctx(mContextProvider.getExecutionContext());
|
||||
startEvent(inId, ctx.mThreadId, contextId, ctx.mCpuId, static_cast<uint8_t>(ctx.mThreadPriority), shdfnd::Time::getCurrentCounterValue());
|
||||
}
|
||||
|
||||
PX_FORCE_INLINE void startEvent(uint16_t inId, uint64_t contextId, uint32_t threadId)
|
||||
{
|
||||
startEvent(inId, threadId, contextId, 0, 0, shdfnd::Time::getCurrentCounterValue());
|
||||
}
|
||||
|
||||
PX_FORCE_INLINE void stopEvent(uint16_t inId, uint32_t threadId, uint64_t contextId, uint8_t cpuId, uint8_t threadPriority, uint64_t inTimestamp)
|
||||
{
|
||||
if (mEventFilter.isEventEnabled(inId))
|
||||
{
|
||||
StopEvent theEvent;
|
||||
theEvent.init(threadId, contextId, cpuId, threadPriority, inTimestamp);
|
||||
doAddProfileEvent(inId, theEvent);
|
||||
}
|
||||
}
|
||||
|
||||
PX_FORCE_INLINE void stopEvent(uint16_t inId, uint64_t contextId)
|
||||
{
|
||||
PxProfileEventExecutionContext ctx(mContextProvider.getExecutionContext());
|
||||
stopEvent(inId, ctx.mThreadId, contextId, ctx.mCpuId, static_cast<uint8_t>(ctx.mThreadPriority), shdfnd::Time::getCurrentCounterValue());
|
||||
}
|
||||
|
||||
PX_FORCE_INLINE void stopEvent(uint16_t inId, uint64_t contextId, uint32_t threadId)
|
||||
{
|
||||
stopEvent(inId, threadId, contextId, 0, 0, shdfnd::Time::getCurrentCounterValue());
|
||||
}
|
||||
|
||||
inline void eventValue(uint16_t inId, uint64_t contextId, int64_t inValue)
|
||||
{
|
||||
eventValue(inId, mContextProvider.getThreadId(), contextId, inValue);
|
||||
}
|
||||
|
||||
inline void eventValue(uint16_t inId, uint32_t threadId, uint64_t contextId, int64_t inValue)
|
||||
{
|
||||
EventValue theEvent;
|
||||
theEvent.init(inValue, contextId, threadId);
|
||||
EventHeader theHeader(static_cast<uint8_t>(getEventType<EventValue>()), inId);
|
||||
//set the header relative timestamp;
|
||||
EventValue& theType(theEvent);
|
||||
theType.setupHeader(theHeader);
|
||||
|
||||
int32_t sizeToWrite = int32_t(sizeof(theHeader) + theType.getEventSize(theHeader));
|
||||
int32_t reserved = shdfnd::atomicAdd(&mReserved, sizeToWrite);
|
||||
sendEvent(theHeader, theType, reserved, sizeToWrite);
|
||||
}
|
||||
|
||||
void flushProfileEvents(int32_t reserved = -1)
|
||||
{
|
||||
TScopedLockType lock(TBaseType::mBufferMutex);
|
||||
|
||||
// set the buffer full to lock additional writes
|
||||
int32_t reservedOld = shdfnd::atomicExchange(&mReserved, int32_t(TBaseType::mBufferFullAmount + 1));
|
||||
if (reserved == -1)
|
||||
reserved = reservedOld;
|
||||
|
||||
// spin till we have written all the data
|
||||
while (reserved > mWritten)
|
||||
{
|
||||
}
|
||||
|
||||
// check if we have written all data
|
||||
PX_ASSERT(reserved == mWritten);
|
||||
|
||||
// set the correct size of the serialization data buffer
|
||||
TBaseType::mSerializer.mArray->setEnd(TBaseType::mSerializer.mArray->begin() + mWritten);
|
||||
|
||||
// flush events
|
||||
TBaseType::flushEvents();
|
||||
|
||||
// write master timestamp and set reserved/written to start writing to buffer again
|
||||
mWritten = 0;
|
||||
mReserved = 0;
|
||||
}
|
||||
|
||||
void release()
|
||||
{
|
||||
PX_PROFILE_DELETE(TBaseType::mWrapper.mUserFoundation, this);
|
||||
}
|
||||
protected:
|
||||
//Clears the cache meaning event compression
|
||||
//starts over again.
|
||||
//only called when the buffer mutex is held
|
||||
void clearCachedData()
|
||||
{
|
||||
}
|
||||
|
||||
template<typename TProfileEventType>
|
||||
PX_FORCE_INLINE void doAddProfileEvent(uint16_t eventId, const TProfileEventType& inType)
|
||||
{
|
||||
doAddEvent(static_cast<uint8_t>(getEventType<TProfileEventType>()), eventId, inType);
|
||||
}
|
||||
|
||||
template<typename TDataType>
|
||||
PX_FORCE_INLINE void doAddEvent(uint8_t inEventType, uint16_t eventId, const TDataType& inType)
|
||||
{
|
||||
EventHeader theHeader(inEventType, eventId);
|
||||
TDataType& theType(const_cast<TDataType&>(inType));
|
||||
theType.setupHeader(theHeader, 0);
|
||||
|
||||
const int32_t sizeToWrite = int32_t(sizeof(theHeader) + theType.getEventSize(theHeader));
|
||||
|
||||
int32_t reserved = shdfnd::atomicAdd(&mReserved, sizeToWrite);
|
||||
sendEvent(theHeader, theType, reserved, sizeToWrite);
|
||||
}
|
||||
|
||||
template<typename TDataType>
|
||||
PX_FORCE_INLINE void sendEvent(EventHeader& inHeader, TDataType& inType, int32_t reserved, int32_t sizeToWrite)
|
||||
{
|
||||
// if we don't fit to the buffer, we wait till it is flushed
|
||||
if (reserved - sizeToWrite >= int32_t(TBaseType::mBufferFullAmount))
|
||||
{
|
||||
while (reserved - sizeToWrite >= int32_t(TBaseType::mBufferFullAmount))
|
||||
{
|
||||
// I32 overflow
|
||||
if (mReserved < int32_t(TBaseType::mBufferFullAmount))
|
||||
{
|
||||
reserved = shdfnd::atomicAdd(&mReserved, sizeToWrite);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t writeIndex = reserved - sizeToWrite;
|
||||
uint32_t writtenSize = 0;
|
||||
|
||||
PX_ASSERT(writeIndex >= 0);
|
||||
|
||||
PX_ALLOCA(tempBuffer, uint8_t, sizeToWrite);
|
||||
TempMemoryBuffer memoryBuffer(tempBuffer, sizeToWrite);
|
||||
EventSerializer<TempMemoryBuffer> eventSerializer(&memoryBuffer);
|
||||
|
||||
writtenSize = inHeader.streamify(eventSerializer);
|
||||
writtenSize += inType.streamify(eventSerializer, inHeader);
|
||||
|
||||
TBaseType::mSerializer.mArray->reserve(writeIndex + writtenSize);
|
||||
TBaseType::mSerializer.mArray->write(&tempBuffer[0], writtenSize, writeIndex);
|
||||
|
||||
PX_ASSERT(writtenSize == uint32_t(sizeToWrite));
|
||||
shdfnd::atomicAdd(&mWritten, sizeToWrite);
|
||||
|
||||
if (reserved >= int32_t(TBaseType::mBufferFullAmount))
|
||||
{
|
||||
TScopedLockType lock(TBaseType::mBufferMutex);
|
||||
// we flush the buffer if its full and we did not flushed him in the meantime
|
||||
if(mReserved >= reserved)
|
||||
flushProfileEvents(reserved);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif // PXPVDSDK_PXPROFILEEVENTBUFFERATOMIC_H
|
||||
80
physx/source/pvd/src/PxProfileEventBufferClient.h
Normal file
80
physx/source/pvd/src/PxProfileEventBufferClient.h
Normal file
@ -0,0 +1,80 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef PXPVDSDK_PXPROFILEEVENTBUFFERCLIENT_H
|
||||
#define PXPVDSDK_PXPROFILEEVENTBUFFERCLIENT_H
|
||||
|
||||
#include "PxProfileEventNames.h"
|
||||
|
||||
namespace physx { namespace profile {
|
||||
|
||||
/**
|
||||
\brief Client handles the data when an event buffer flushes. This data
|
||||
can be parsed (PxProfileEventHandler.h) as a binary set of events.
|
||||
*/
|
||||
class PxProfileEventBufferClient
|
||||
{
|
||||
protected:
|
||||
virtual ~PxProfileEventBufferClient(){}
|
||||
public:
|
||||
/**
|
||||
\brief Callback when the event buffer is full. This data is serialized profile events
|
||||
and can be read back using: PxProfileEventHandler::parseEventBuffer.
|
||||
|
||||
\param inData Provided buffer data.
|
||||
\param inLength Data length.
|
||||
|
||||
@see PxProfileEventHandler::parseEventBuffer.
|
||||
*/
|
||||
virtual void handleBufferFlush( const uint8_t* inData, uint32_t inLength ) = 0;
|
||||
|
||||
/**
|
||||
\brief Happens if something removes all the clients from the manager.
|
||||
*/
|
||||
virtual void handleClientRemoved() = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Client handles new profile event add.
|
||||
*/
|
||||
class PxProfileZoneClient : public PxProfileEventBufferClient
|
||||
{
|
||||
protected:
|
||||
virtual ~PxProfileZoneClient(){}
|
||||
public:
|
||||
/**
|
||||
\brief Callback when new profile event is added.
|
||||
|
||||
\param inName Added profile event name.
|
||||
*/
|
||||
virtual void handleEventAdded( const PxProfileEventName& inName ) = 0;
|
||||
};
|
||||
|
||||
} }
|
||||
|
||||
|
||||
#endif // PXPVDSDK_PXPROFILEEVENTBUFFERCLIENT_H
|
||||
94
physx/source/pvd/src/PxProfileEventBufferClientManager.h
Normal file
94
physx/source/pvd/src/PxProfileEventBufferClientManager.h
Normal file
@ -0,0 +1,94 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef PXPVDSDK_PXPROFILEEVENTBUFFERCLIENTMANAGER_H
|
||||
#define PXPVDSDK_PXPROFILEEVENTBUFFERCLIENTMANAGER_H
|
||||
|
||||
#include "PxProfileEventBufferClient.h"
|
||||
|
||||
namespace physx { namespace profile {
|
||||
|
||||
/**
|
||||
\brief Manager keep collections of PxProfileEventBufferClient clients.
|
||||
|
||||
@see PxProfileEventBufferClient
|
||||
*/
|
||||
class PxProfileEventBufferClientManager
|
||||
{
|
||||
protected:
|
||||
virtual ~PxProfileEventBufferClientManager(){}
|
||||
public:
|
||||
/**
|
||||
\brief Adds new client.
|
||||
\param inClient Client to add.
|
||||
*/
|
||||
virtual void addClient( PxProfileEventBufferClient& inClient ) = 0;
|
||||
|
||||
/**
|
||||
\brief Removes a client.
|
||||
\param inClient Client to remove.
|
||||
*/
|
||||
virtual void removeClient( PxProfileEventBufferClient& inClient ) = 0;
|
||||
|
||||
/**
|
||||
\brief Check if manager has clients.
|
||||
\return True if manager has added clients.
|
||||
*/
|
||||
virtual bool hasClients() const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Manager keep collections of PxProfileZoneClient clients.
|
||||
|
||||
@see PxProfileZoneClient
|
||||
*/
|
||||
class PxProfileZoneClientManager
|
||||
{
|
||||
protected:
|
||||
virtual ~PxProfileZoneClientManager(){}
|
||||
public:
|
||||
/**
|
||||
\brief Adds new client.
|
||||
\param inClient Client to add.
|
||||
*/
|
||||
virtual void addClient( PxProfileZoneClient& inClient ) = 0;
|
||||
|
||||
/**
|
||||
\brief Removes a client.
|
||||
\param inClient Client to remove.
|
||||
*/
|
||||
virtual void removeClient( PxProfileZoneClient& inClient ) = 0;
|
||||
|
||||
/**
|
||||
\brief Check if manager has clients.
|
||||
\return True if manager has added clients.
|
||||
*/
|
||||
virtual bool hasClients() const = 0;
|
||||
};
|
||||
} }
|
||||
|
||||
#endif // PXPVDSDK_PXPROFILEEVENTBUFFERCLIENTMANAGER_H
|
||||
64
physx/source/pvd/src/PxProfileEventId.h
Normal file
64
physx/source/pvd/src/PxProfileEventId.h
Normal file
@ -0,0 +1,64 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef PXPVDSDK_PXPROFILEEVENTID_H
|
||||
#define PXPVDSDK_PXPROFILEEVENTID_H
|
||||
|
||||
#include "foundation/Px.h"
|
||||
|
||||
namespace physx { namespace profile {
|
||||
/**
|
||||
\brief A event id structure. Optionally includes information about
|
||||
if the event was enabled at compile time.
|
||||
*/
|
||||
struct PxProfileEventId
|
||||
{
|
||||
uint16_t eventId;
|
||||
mutable bool compileTimeEnabled;
|
||||
|
||||
/**
|
||||
\brief Profile event id constructor.
|
||||
\param inId Profile event id.
|
||||
\param inCompileTimeEnabled Compile time enabled.
|
||||
*/
|
||||
PxProfileEventId( uint16_t inId = 0, bool inCompileTimeEnabled = true )
|
||||
: eventId( inId )
|
||||
, compileTimeEnabled( inCompileTimeEnabled )
|
||||
{
|
||||
}
|
||||
|
||||
operator uint16_t () const { return eventId; }
|
||||
|
||||
bool operator==( const PxProfileEventId& inOther ) const
|
||||
{
|
||||
return eventId == inOther.eventId;
|
||||
}
|
||||
};
|
||||
|
||||
} }
|
||||
|
||||
#endif // PXPVDSDK_PXPROFILEEVENTID_H
|
||||
63
physx/source/pvd/src/PxProfileEventImpl.cpp
Normal file
63
physx/source/pvd/src/PxProfileEventImpl.cpp
Normal file
@ -0,0 +1,63 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "PxProfileEventBuffer.h"
|
||||
#include "PxProfileZoneImpl.h"
|
||||
#include "PxProfileZoneManagerImpl.h"
|
||||
#include "PxProfileMemoryEventBuffer.h"
|
||||
#include "PsUserAllocated.h"
|
||||
|
||||
namespace physx { namespace profile {
|
||||
|
||||
struct PxProfileNameProviderForward
|
||||
{
|
||||
PxProfileNames mNames;
|
||||
PxProfileNameProviderForward( PxProfileNames inNames )
|
||||
: mNames( inNames )
|
||||
{
|
||||
}
|
||||
PxProfileNames getProfileNames() const { return mNames; }
|
||||
};
|
||||
|
||||
PxProfileZone& PxProfileZone::createProfileZone( PxAllocatorCallback* inAllocator, const char* inSDKName, PxProfileNames inNames, uint32_t inEventBufferByteSize )
|
||||
{
|
||||
typedef ZoneImpl<PxProfileNameProviderForward> TSDKType;
|
||||
return *PX_PROFILE_NEW( inAllocator, TSDKType ) ( inAllocator, inSDKName, inEventBufferByteSize, PxProfileNameProviderForward( inNames ) );
|
||||
}
|
||||
|
||||
PxProfileZoneManager& PxProfileZoneManager::createProfileZoneManager(PxAllocatorCallback* inAllocator )
|
||||
{
|
||||
return *PX_PROFILE_NEW( inAllocator, ZoneManagerImpl ) ( inAllocator );
|
||||
}
|
||||
|
||||
PxProfileMemoryEventBuffer& PxProfileMemoryEventBuffer::createMemoryEventBuffer( PxAllocatorCallback& inAllocator, uint32_t inBufferSize )
|
||||
{
|
||||
return *PX_PROFILE_NEW( &inAllocator, PxProfileMemoryEventBufferImpl )( inAllocator, inBufferSize );
|
||||
}
|
||||
|
||||
} }
|
||||
|
||||
63
physx/source/pvd/src/PxProfileEventMutex.h
Normal file
63
physx/source/pvd/src/PxProfileEventMutex.h
Normal file
@ -0,0 +1,63 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
|
||||
#ifndef PXPVDSDK_PXPROFILEEVENTMUTEX_H
|
||||
#define PXPVDSDK_PXPROFILEEVENTMUTEX_H
|
||||
|
||||
#include "foundation/Px.h"
|
||||
|
||||
namespace physx { namespace profile {
|
||||
|
||||
/**
|
||||
* Mutex interface that hides implementation around lock and unlock.
|
||||
* The event system locks the mutex for every interaction.
|
||||
*/
|
||||
class PxProfileEventMutex
|
||||
{
|
||||
protected:
|
||||
virtual ~PxProfileEventMutex(){}
|
||||
public:
|
||||
virtual void lock() = 0;
|
||||
virtual void unlock() = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Take any mutex type that implements lock and unlock and make an EventMutex out of it.
|
||||
*/
|
||||
template<typename TMutexType>
|
||||
struct PxProfileEventMutexImpl : public PxProfileEventMutex
|
||||
{
|
||||
TMutexType* mMutex;
|
||||
PxProfileEventMutexImpl( TMutexType* inMtx ) : mMutex( inMtx ) {}
|
||||
virtual void lock() { mMutex->lock(); }
|
||||
virtual void unlock() { mMutex->unlock(); }
|
||||
};
|
||||
|
||||
} }
|
||||
|
||||
#endif // PXPVDSDK_PXPROFILEEVENTMUTEX_H
|
||||
89
physx/source/pvd/src/PxProfileEventNames.h
Normal file
89
physx/source/pvd/src/PxProfileEventNames.h
Normal file
@ -0,0 +1,89 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef PXPVDSDK_PXPROFILEEVENTNAMES_H
|
||||
#define PXPVDSDK_PXPROFILEEVENTNAMES_H
|
||||
|
||||
#include "PxProfileEventId.h"
|
||||
|
||||
namespace physx { namespace profile {
|
||||
|
||||
/**
|
||||
\brief Mapping from event id to name.
|
||||
*/
|
||||
struct PxProfileEventName
|
||||
{
|
||||
const char* name;
|
||||
PxProfileEventId eventId;
|
||||
|
||||
/**
|
||||
\brief Default constructor.
|
||||
\param inName Profile event name.
|
||||
\param inId Profile event id.
|
||||
*/
|
||||
PxProfileEventName( const char* inName, PxProfileEventId inId ) : name( inName ), eventId( inId ) {}
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Aggregator of event id -> name mappings
|
||||
*/
|
||||
struct PxProfileNames
|
||||
{
|
||||
/**
|
||||
\brief Default constructor that doesn't point to any names.
|
||||
\param inEventCount Number of provided events.
|
||||
\param inSubsystems Event names array.
|
||||
*/
|
||||
PxProfileNames( uint32_t inEventCount = 0, const PxProfileEventName* inSubsystems = NULL )
|
||||
: eventCount( inEventCount )
|
||||
, events( inSubsystems )
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t eventCount;
|
||||
const PxProfileEventName* events;
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Provides a mapping from event ID -> name.
|
||||
*/
|
||||
class PxProfileNameProvider
|
||||
{
|
||||
public:
|
||||
/**
|
||||
\brief Returns profile event names.
|
||||
\return Profile event names.
|
||||
*/
|
||||
virtual PxProfileNames getProfileNames() const = 0;
|
||||
|
||||
protected:
|
||||
virtual ~PxProfileNameProvider(){}
|
||||
PxProfileNameProvider& operator=(const PxProfileNameProvider&) { return *this; }
|
||||
};
|
||||
} }
|
||||
|
||||
#endif // PXPVDSDK_PXPROFILEEVENTNAMES_H
|
||||
111
physx/source/pvd/src/PxProfileEventSender.h
Normal file
111
physx/source/pvd/src/PxProfileEventSender.h
Normal file
@ -0,0 +1,111 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef PXPVDSDK_PXPROFILEEVENTSENDER_H
|
||||
#define PXPVDSDK_PXPROFILEEVENTSENDER_H
|
||||
|
||||
#include "foundation/Px.h"
|
||||
|
||||
namespace physx { namespace profile {
|
||||
|
||||
/**
|
||||
\brief Tagging interface to indicate an object that is capable of flushing a profile
|
||||
event stream at a certain point.
|
||||
*/
|
||||
class PxProfileEventFlusher
|
||||
{
|
||||
protected:
|
||||
virtual ~PxProfileEventFlusher(){}
|
||||
public:
|
||||
/**
|
||||
\brief Flush profile events. Sends the profile event buffer to hooked clients.
|
||||
*/
|
||||
virtual void flushProfileEvents() = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Sends the full events where the caller must provide the context and thread id.
|
||||
*/
|
||||
class PxProfileEventSender
|
||||
{
|
||||
protected:
|
||||
virtual ~PxProfileEventSender(){}
|
||||
public:
|
||||
|
||||
/**
|
||||
\brief Use this as a thread id for events that start on one thread and end on another
|
||||
*/
|
||||
static const uint32_t CrossThreadId = 99999789;
|
||||
|
||||
/**
|
||||
\brief Send a start profile event, optionally with a context. Events are sorted by thread
|
||||
and context in the client side.
|
||||
\param inId Profile event id.
|
||||
\param contextId Context id.
|
||||
*/
|
||||
virtual void startEvent( uint16_t inId, uint64_t contextId) = 0;
|
||||
/**
|
||||
\brief Send a stop profile event, optionally with a context. Events are sorted by thread
|
||||
and context in the client side.
|
||||
\param inId Profile event id.
|
||||
\param contextId Context id.
|
||||
*/
|
||||
virtual void stopEvent( uint16_t inId, uint64_t contextId) = 0;
|
||||
|
||||
/**
|
||||
\brief Send a start profile event, optionally with a context. Events are sorted by thread
|
||||
and context in the client side.
|
||||
\param inId Profile event id.
|
||||
\param contextId Context id.
|
||||
\param threadId Thread id.
|
||||
*/
|
||||
virtual void startEvent( uint16_t inId, uint64_t contextId, uint32_t threadId) = 0;
|
||||
/**
|
||||
\brief Send a stop profile event, optionally with a context. Events are sorted by thread
|
||||
and context in the client side.
|
||||
\param inId Profile event id.
|
||||
\param contextId Context id.
|
||||
\param threadId Thread id.
|
||||
*/
|
||||
virtual void stopEvent( uint16_t inId, uint64_t contextId, uint32_t threadId ) = 0;
|
||||
|
||||
virtual void atEvent(uint16_t inId, uint64_t contextId, uint32_t threadId, uint64_t start, uint64_t stop) = 0;
|
||||
|
||||
/**
|
||||
\brief Set an specific events value. This is different than the profiling value
|
||||
for the event; it is a value recorded and kept around without a timestamp associated
|
||||
with it. This value is displayed when the event itself is processed.
|
||||
\param inId Profile event id.
|
||||
\param contextId Context id.
|
||||
\param inValue Value to set for the event.
|
||||
*/
|
||||
virtual void eventValue( uint16_t inId, uint64_t contextId, int64_t inValue ) = 0;
|
||||
};
|
||||
|
||||
} }
|
||||
|
||||
#endif // PXPVDSDK_PXPROFILEEVENTSENDER_H
|
||||
257
physx/source/pvd/src/PxProfileEventSerialization.h
Normal file
257
physx/source/pvd/src/PxProfileEventSerialization.h
Normal file
@ -0,0 +1,257 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
|
||||
#ifndef PXPVDSDK_PXPROFILEEVENTSERIALIZATION_H
|
||||
#define PXPVDSDK_PXPROFILEEVENTSERIALIZATION_H
|
||||
|
||||
#include "PxProfileDataParsing.h"
|
||||
#include "PxProfileEvents.h"
|
||||
|
||||
namespace physx { namespace profile {
|
||||
|
||||
/**
|
||||
* Array type must be a pxu8 container. Templated so that this object can write
|
||||
* to different collections.
|
||||
*/
|
||||
|
||||
template<typename TArrayType>
|
||||
struct EventSerializer
|
||||
{
|
||||
TArrayType* mArray;
|
||||
EventSerializer( TArrayType* inA ) : mArray( inA ) {}
|
||||
|
||||
template<typename TDataType>
|
||||
uint32_t streamify( const char*, const TDataType& inType )
|
||||
{
|
||||
return mArray->write( inType );
|
||||
}
|
||||
|
||||
uint32_t streamify( const char*, const char*& inType )
|
||||
{
|
||||
PX_ASSERT( inType != NULL );
|
||||
uint32_t len( static_cast<uint32_t>( strlen( inType ) ) );
|
||||
++len; //include the null terminator
|
||||
uint32_t writtenSize = 0;
|
||||
writtenSize = mArray->write(len);
|
||||
writtenSize += mArray->write(inType, len);
|
||||
return writtenSize;
|
||||
}
|
||||
|
||||
uint32_t streamify( const char*, const uint8_t* inData, uint32_t len )
|
||||
{
|
||||
uint32_t writtenSize = mArray->write(len);
|
||||
if ( len )
|
||||
writtenSize += mArray->write(inData, len);
|
||||
return writtenSize;
|
||||
}
|
||||
|
||||
uint32_t streamify( const char* nm, const uint64_t& inType, EventStreamCompressionFlags::Enum inFlags )
|
||||
{
|
||||
uint32_t writtenSize = 0;
|
||||
switch( inFlags )
|
||||
{
|
||||
case EventStreamCompressionFlags::U8:
|
||||
writtenSize = streamify(nm, static_cast<uint8_t>(inType));
|
||||
break;
|
||||
case EventStreamCompressionFlags::U16:
|
||||
writtenSize = streamify(nm, static_cast<uint16_t>(inType));
|
||||
break;
|
||||
case EventStreamCompressionFlags::U32:
|
||||
writtenSize = streamify(nm, static_cast<uint32_t>(inType));
|
||||
break;
|
||||
case EventStreamCompressionFlags::U64:
|
||||
writtenSize = streamify(nm, inType);
|
||||
break;
|
||||
}
|
||||
return writtenSize;
|
||||
}
|
||||
|
||||
uint32_t streamify( const char* nm, const uint32_t& inType, EventStreamCompressionFlags::Enum inFlags )
|
||||
{
|
||||
uint32_t writtenSize = 0;
|
||||
switch( inFlags )
|
||||
{
|
||||
case EventStreamCompressionFlags::U8:
|
||||
writtenSize = streamify(nm, static_cast<uint8_t>(inType));
|
||||
break;
|
||||
case EventStreamCompressionFlags::U16:
|
||||
writtenSize = streamify(nm, static_cast<uint16_t>(inType));
|
||||
break;
|
||||
case EventStreamCompressionFlags::U32:
|
||||
case EventStreamCompressionFlags::U64:
|
||||
writtenSize = streamify(nm, inType);
|
||||
break;
|
||||
}
|
||||
return writtenSize;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The event deserializes takes a buffer implements the streamify functions
|
||||
* by setting the passed in data to the data in the buffer.
|
||||
*/
|
||||
template<bool TSwapBytes>
|
||||
struct EventDeserializer
|
||||
{
|
||||
const uint8_t* mData;
|
||||
uint32_t mLength;
|
||||
bool mFail;
|
||||
|
||||
EventDeserializer( const uint8_t* inData, uint32_t inLength )
|
||||
: mData( inData )
|
||||
, mLength( inLength )
|
||||
, mFail( false )
|
||||
{
|
||||
if ( mData == NULL )
|
||||
mLength = 0;
|
||||
}
|
||||
|
||||
bool val() { return TSwapBytes; }
|
||||
|
||||
uint32_t streamify( const char* , uint8_t& inType )
|
||||
{
|
||||
uint8_t* theData = reinterpret_cast<uint8_t*>( &inType ); //type punned pointer...
|
||||
if ( mFail || sizeof( inType ) > mLength )
|
||||
{
|
||||
PX_ASSERT( false );
|
||||
mFail = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
for( uint32_t idx = 0; idx < sizeof( uint8_t ); ++idx, ++mData, --mLength )
|
||||
theData[idx] = *mData;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//default streamify reads things natively as bytes.
|
||||
template<typename TDataType>
|
||||
uint32_t streamify( const char* , TDataType& inType )
|
||||
{
|
||||
uint8_t* theData = reinterpret_cast<uint8_t*>( &inType ); //type punned pointer...
|
||||
if ( mFail || sizeof( inType ) > mLength )
|
||||
{
|
||||
PX_ASSERT( false );
|
||||
mFail = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
for( uint32_t idx = 0; idx < sizeof( TDataType ); ++idx, ++mData, --mLength )
|
||||
theData[idx] = *mData;
|
||||
bool temp = val();
|
||||
if ( temp )
|
||||
BlockParseFunctions::swapBytes<sizeof(TDataType)>( theData );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t streamify( const char*, const char*& inType )
|
||||
{
|
||||
uint32_t theLen;
|
||||
streamify( "", theLen );
|
||||
theLen = PxMin( theLen, mLength );
|
||||
inType = reinterpret_cast<const char*>( mData );
|
||||
mData += theLen;
|
||||
mLength -= theLen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t streamify( const char*, const uint8_t*& inData, uint32_t& len )
|
||||
{
|
||||
uint32_t theLen;
|
||||
streamify( "", theLen );
|
||||
theLen = PxMin( theLen, mLength );
|
||||
len = theLen;
|
||||
inData = reinterpret_cast<const uint8_t*>( mData );
|
||||
mData += theLen;
|
||||
mLength -= theLen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t streamify( const char* nm, uint64_t& inType, EventStreamCompressionFlags::Enum inFlags )
|
||||
{
|
||||
switch( inFlags )
|
||||
{
|
||||
case EventStreamCompressionFlags::U8:
|
||||
{
|
||||
uint8_t val=0;
|
||||
streamify( nm, val );
|
||||
inType = val;
|
||||
}
|
||||
break;
|
||||
case EventStreamCompressionFlags::U16:
|
||||
{
|
||||
uint16_t val;
|
||||
streamify( nm, val );
|
||||
inType = val;
|
||||
}
|
||||
break;
|
||||
case EventStreamCompressionFlags::U32:
|
||||
{
|
||||
uint32_t val;
|
||||
streamify( nm, val );
|
||||
inType = val;
|
||||
}
|
||||
break;
|
||||
case EventStreamCompressionFlags::U64:
|
||||
streamify( nm, inType );
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t streamify( const char* nm, uint32_t& inType, EventStreamCompressionFlags::Enum inFlags )
|
||||
{
|
||||
switch( inFlags )
|
||||
{
|
||||
case EventStreamCompressionFlags::U8:
|
||||
{
|
||||
uint8_t val=0;
|
||||
streamify( nm, val );
|
||||
inType = val;
|
||||
}
|
||||
break;
|
||||
case EventStreamCompressionFlags::U16:
|
||||
{
|
||||
uint16_t val=0;
|
||||
streamify( nm, val );
|
||||
inType = val;
|
||||
}
|
||||
break;
|
||||
case EventStreamCompressionFlags::U32:
|
||||
case EventStreamCompressionFlags::U64:
|
||||
streamify( nm, inType );
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}}
|
||||
#endif // PXPVDSDK_PXPROFILEEVENTSERIALIZATION_H
|
||||
705
physx/source/pvd/src/PxProfileEvents.h
Normal file
705
physx/source/pvd/src/PxProfileEvents.h
Normal file
@ -0,0 +1,705 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef PXPVDSDK_PXPROFILEEVENTS_H
|
||||
#define PXPVDSDK_PXPROFILEEVENTS_H
|
||||
|
||||
#include "foundation/PxMath.h"
|
||||
#include "foundation/PxAssert.h"
|
||||
|
||||
#include "PxProfileEventId.h"
|
||||
|
||||
|
||||
#define PX_PROFILE_UNION_1(a) physx::profile::TUnion<a, physx::profile::Empty>
|
||||
#define PX_PROFILE_UNION_2(a,b) physx::profile::TUnion<a, PX_PROFILE_UNION_1(b)>
|
||||
#define PX_PROFILE_UNION_3(a,b,c) physx::profile::TUnion<a, PX_PROFILE_UNION_2(b,c)>
|
||||
#define PX_PROFILE_UNION_4(a,b,c,d) physx::profile::TUnion<a, PX_PROFILE_UNION_3(b,c,d)>
|
||||
#define PX_PROFILE_UNION_5(a,b,c,d,e) physx::profile::TUnion<a, PX_PROFILE_UNION_4(b,c,d,e)>
|
||||
#define PX_PROFILE_UNION_6(a,b,c,d,e,f) physx::profile::TUnion<a, PX_PROFILE_UNION_5(b,c,d,e,f)>
|
||||
#define PX_PROFILE_UNION_7(a,b,c,d,e,f,g) physx::profile::TUnion<a, PX_PROFILE_UNION_6(b,c,d,e,f,g)>
|
||||
#define PX_PROFILE_UNION_8(a,b,c,d,e,f,g,h) physx::profile::TUnion<a, PX_PROFILE_UNION_7(b,c,d,e,f,g,h)>
|
||||
#define PX_PROFILE_UNION_9(a,b,c,d,e,f,g,h,i) physx::profile::TUnion<a, PX_PROFILE_UNION_8(b,c,d,e,f,g,h,i)>
|
||||
|
||||
namespace physx { namespace profile {
|
||||
|
||||
struct Empty {};
|
||||
|
||||
template <typename T> struct Type2Type {};
|
||||
|
||||
template <typename U, typename V>
|
||||
union TUnion
|
||||
{
|
||||
typedef U Head;
|
||||
typedef V Tail;
|
||||
|
||||
Head head;
|
||||
Tail tail;
|
||||
|
||||
template <typename TDataType>
|
||||
void init(const TDataType& inData)
|
||||
{
|
||||
toType(Type2Type<TDataType>()).init(inData);
|
||||
}
|
||||
|
||||
template <typename TDataType>
|
||||
PX_FORCE_INLINE TDataType& toType(const Type2Type<TDataType>& outData) { return tail.toType(outData); }
|
||||
|
||||
PX_FORCE_INLINE Head& toType(const Type2Type<Head>&) { return head; }
|
||||
|
||||
template <typename TDataType>
|
||||
PX_FORCE_INLINE const TDataType& toType(const Type2Type<TDataType>& outData) const { return tail.toType(outData); }
|
||||
|
||||
PX_FORCE_INLINE const Head& toType(const Type2Type<Head>&) const { return head; }
|
||||
};
|
||||
|
||||
struct EventTypes
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Unknown = 0,
|
||||
StartEvent,
|
||||
StopEvent,
|
||||
RelativeStartEvent, //reuses context,id from the earlier event.
|
||||
RelativeStopEvent, //reuses context,id from the earlier event.
|
||||
EventValue,
|
||||
CUDAProfileBuffer //obsolete, placeholder to skip data from PhysX SDKs < 3.4
|
||||
};
|
||||
};
|
||||
|
||||
struct EventStreamCompressionFlags
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
U8 = 0,
|
||||
U16 = 1,
|
||||
U32 = 2,
|
||||
U64 = 3,
|
||||
CompressionMask = 3
|
||||
};
|
||||
};
|
||||
|
||||
#if (PX_PS4) || (PX_APPLE_FAMILY)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wimplicit-fallthrough"
|
||||
#endif
|
||||
|
||||
//Find the smallest value that will represent the incoming value without loss.
|
||||
//We can enlarge the current compression value, but we can't make is smaller.
|
||||
//In this way, we can use this function to find the smallest compression setting
|
||||
//that will work for a set of values.
|
||||
inline EventStreamCompressionFlags::Enum findCompressionValue( uint64_t inValue, EventStreamCompressionFlags::Enum inCurrentCompressionValue = EventStreamCompressionFlags::U8 )
|
||||
{
|
||||
PX_ASSERT_WITH_MESSAGE( (inCurrentCompressionValue >= EventStreamCompressionFlags::U8) &&
|
||||
(inCurrentCompressionValue <= EventStreamCompressionFlags::U64),
|
||||
"Invalid inCurrentCompressionValue in profile::findCompressionValue");
|
||||
|
||||
//Fallthrough is intentional
|
||||
switch( inCurrentCompressionValue )
|
||||
{
|
||||
case EventStreamCompressionFlags::U8:
|
||||
if ( inValue <= UINT8_MAX )
|
||||
return EventStreamCompressionFlags::U8;
|
||||
case EventStreamCompressionFlags::U16:
|
||||
if ( inValue <= UINT16_MAX )
|
||||
return EventStreamCompressionFlags::U16;
|
||||
case EventStreamCompressionFlags::U32:
|
||||
if ( inValue <= UINT32_MAX )
|
||||
return EventStreamCompressionFlags::U32;
|
||||
case EventStreamCompressionFlags::U64:
|
||||
break;
|
||||
}
|
||||
return EventStreamCompressionFlags::U64;
|
||||
}
|
||||
|
||||
//Find the smallest value that will represent the incoming value without loss.
|
||||
//We can enlarge the current compression value, but we can't make is smaller.
|
||||
//In this way, we can use this function to find the smallest compression setting
|
||||
//that will work for a set of values.
|
||||
inline EventStreamCompressionFlags::Enum findCompressionValue( uint32_t inValue, EventStreamCompressionFlags::Enum inCurrentCompressionValue = EventStreamCompressionFlags::U8 )
|
||||
{
|
||||
PX_ASSERT_WITH_MESSAGE( (inCurrentCompressionValue >= EventStreamCompressionFlags::U8) &&
|
||||
(inCurrentCompressionValue <= EventStreamCompressionFlags::U64),
|
||||
"Invalid inCurrentCompressionValue in profile::findCompressionValue");
|
||||
|
||||
//Fallthrough is intentional
|
||||
switch( inCurrentCompressionValue )
|
||||
{
|
||||
case EventStreamCompressionFlags::U8:
|
||||
if ( inValue <= UINT8_MAX )
|
||||
return EventStreamCompressionFlags::U8;
|
||||
case EventStreamCompressionFlags::U16:
|
||||
if ( inValue <= UINT16_MAX )
|
||||
return EventStreamCompressionFlags::U16;
|
||||
case EventStreamCompressionFlags::U32:
|
||||
case EventStreamCompressionFlags::U64:
|
||||
break;
|
||||
}
|
||||
return EventStreamCompressionFlags::U32;
|
||||
}
|
||||
|
||||
#if (PX_PS4) || (PX_APPLE_FAMILY)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
//Event header is 32 bytes and precedes all events.
|
||||
struct EventHeader
|
||||
{
|
||||
uint8_t mEventType; //Used to parse the correct event out of the stream
|
||||
uint8_t mStreamOptions; //Timestamp compression, etc.
|
||||
uint16_t mEventId; //16 bit per-event-system event id
|
||||
EventHeader( uint8_t type = 0, uint16_t id = 0 )
|
||||
: mEventType( type )
|
||||
, mStreamOptions( uint8_t(-1) )
|
||||
, mEventId( id )
|
||||
{
|
||||
}
|
||||
|
||||
EventHeader( EventTypes::Enum type, uint16_t id )
|
||||
: mEventType( static_cast<uint8_t>( type ) )
|
||||
, mStreamOptions( uint8_t(-1) )
|
||||
, mEventId( id )
|
||||
{
|
||||
}
|
||||
|
||||
EventStreamCompressionFlags::Enum getTimestampCompressionFlags() const
|
||||
{
|
||||
return static_cast<EventStreamCompressionFlags::Enum> ( mStreamOptions & EventStreamCompressionFlags::CompressionMask );
|
||||
}
|
||||
|
||||
uint64_t compressTimestamp( uint64_t inLastTimestamp, uint64_t inCurrentTimestamp )
|
||||
{
|
||||
mStreamOptions = EventStreamCompressionFlags::U64;
|
||||
uint64_t retval = inCurrentTimestamp;
|
||||
if ( inLastTimestamp )
|
||||
{
|
||||
retval = inCurrentTimestamp - inLastTimestamp;
|
||||
EventStreamCompressionFlags::Enum compressionValue = findCompressionValue( retval );
|
||||
mStreamOptions = static_cast<uint8_t>( compressionValue );
|
||||
if ( compressionValue == EventStreamCompressionFlags::U64 )
|
||||
retval = inCurrentTimestamp; //just send the timestamp as is.
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
uint64_t uncompressTimestamp( uint64_t inLastTimestamp, uint64_t inCurrentTimestamp ) const
|
||||
{
|
||||
if ( getTimestampCompressionFlags() != EventStreamCompressionFlags::U64 )
|
||||
return inLastTimestamp + inCurrentTimestamp;
|
||||
return inCurrentTimestamp;
|
||||
}
|
||||
|
||||
void setContextIdCompressionFlags( uint64_t inContextId )
|
||||
{
|
||||
uint8_t options = static_cast<uint8_t>( findCompressionValue( inContextId ) );
|
||||
mStreamOptions = uint8_t(mStreamOptions | options << 2);
|
||||
}
|
||||
|
||||
EventStreamCompressionFlags::Enum getContextIdCompressionFlags() const
|
||||
{
|
||||
return static_cast< EventStreamCompressionFlags::Enum >( ( mStreamOptions >> 2 ) & EventStreamCompressionFlags::CompressionMask );
|
||||
}
|
||||
|
||||
bool operator==( const EventHeader& inOther ) const
|
||||
{
|
||||
return mEventType == inOther.mEventType
|
||||
&& mStreamOptions == inOther.mStreamOptions
|
||||
&& mEventId == inOther.mEventId;
|
||||
}
|
||||
|
||||
template<typename TStreamType>
|
||||
inline uint32_t streamify( TStreamType& inStream )
|
||||
{
|
||||
uint32_t writtenSize = inStream.streamify( "EventType", mEventType );
|
||||
writtenSize += inStream.streamify("StreamOptions", mStreamOptions); //Timestamp compression, etc.
|
||||
writtenSize += inStream.streamify("EventId", mEventId); //16 bit per-event-system event id
|
||||
return writtenSize;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
//Declaration of type level getEventType function that maps enumeration event types to datatypes
|
||||
template<typename TDataType>
|
||||
inline EventTypes::Enum getEventType() { PX_ASSERT( false ); return EventTypes::Unknown; }
|
||||
|
||||
//Relative profile event means this event is sharing the context and thread id
|
||||
//with the event before it.
|
||||
struct RelativeProfileEvent
|
||||
{
|
||||
uint64_t mTensOfNanoSeconds; //timestamp is in tensOfNanonseconds
|
||||
void init( uint64_t inTs ) { mTensOfNanoSeconds = inTs; }
|
||||
void init( const RelativeProfileEvent& inData ) { mTensOfNanoSeconds = inData.mTensOfNanoSeconds; }
|
||||
bool operator==( const RelativeProfileEvent& other ) const
|
||||
{
|
||||
return mTensOfNanoSeconds == other.mTensOfNanoSeconds;
|
||||
}
|
||||
template<typename TStreamType>
|
||||
uint32_t streamify( TStreamType& inStream, const EventHeader& inHeader )
|
||||
{
|
||||
return inStream.streamify( "TensOfNanoSeconds", mTensOfNanoSeconds, inHeader.getTimestampCompressionFlags() );
|
||||
}
|
||||
uint64_t getTimestamp() const { return mTensOfNanoSeconds; }
|
||||
void setTimestamp( uint64_t inTs ) { mTensOfNanoSeconds = inTs; }
|
||||
void setupHeader( EventHeader& inHeader, uint64_t inLastTimestamp )
|
||||
{
|
||||
mTensOfNanoSeconds = inHeader.compressTimestamp( inLastTimestamp, mTensOfNanoSeconds );
|
||||
}
|
||||
|
||||
uint32_t getEventSize(const EventHeader& inHeader)
|
||||
{
|
||||
uint32_t size = 0;
|
||||
switch (inHeader.getTimestampCompressionFlags())
|
||||
{
|
||||
case EventStreamCompressionFlags::U8:
|
||||
size = 1;
|
||||
break;
|
||||
case EventStreamCompressionFlags::U16:
|
||||
size = 2;
|
||||
break;
|
||||
case EventStreamCompressionFlags::U32:
|
||||
size = 4;
|
||||
break;
|
||||
case EventStreamCompressionFlags::U64:
|
||||
size = 8;
|
||||
break;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
};
|
||||
|
||||
//Start version of the relative event.
|
||||
struct RelativeStartEvent : public RelativeProfileEvent
|
||||
{
|
||||
void init( uint64_t inTs = 0 ) { RelativeProfileEvent::init( inTs ); }
|
||||
void init( const RelativeStartEvent& inData ) { RelativeProfileEvent::init( inData ); }
|
||||
template<typename THandlerType>
|
||||
void handle( THandlerType* inHdlr, uint16_t eventId, uint32_t thread, uint64_t context, uint8_t inCpuId, uint8_t threadPriority ) const
|
||||
{
|
||||
inHdlr->onStartEvent( PxProfileEventId( eventId ), thread, context, inCpuId, threadPriority, mTensOfNanoSeconds );
|
||||
}
|
||||
};
|
||||
|
||||
template<> inline EventTypes::Enum getEventType<RelativeStartEvent>() { return EventTypes::RelativeStartEvent; }
|
||||
|
||||
//Stop version of relative event.
|
||||
struct RelativeStopEvent : public RelativeProfileEvent
|
||||
{
|
||||
void init( uint64_t inTs = 0 ) { RelativeProfileEvent::init( inTs ); }
|
||||
void init( const RelativeStopEvent& inData ) { RelativeProfileEvent::init( inData ); }
|
||||
template<typename THandlerType>
|
||||
void handle( THandlerType* inHdlr, uint16_t eventId, uint32_t thread, uint64_t context, uint8_t inCpuId, uint8_t threadPriority ) const
|
||||
{
|
||||
inHdlr->onStopEvent( PxProfileEventId( eventId ), thread, context, inCpuId, threadPriority, mTensOfNanoSeconds );
|
||||
}
|
||||
};
|
||||
|
||||
template<> inline EventTypes::Enum getEventType<RelativeStopEvent>() { return EventTypes::RelativeStopEvent; }
|
||||
|
||||
struct EventContextInformation
|
||||
{
|
||||
uint64_t mContextId;
|
||||
uint32_t mThreadId; //Thread this event was taken from
|
||||
uint8_t mThreadPriority;
|
||||
uint8_t mCpuId;
|
||||
|
||||
void init( uint32_t inThreadId = UINT32_MAX
|
||||
, uint64_t inContextId = (uint64_t(-1))
|
||||
, uint8_t inPriority = UINT8_MAX
|
||||
, uint8_t inCpuId = UINT8_MAX )
|
||||
{
|
||||
mContextId = inContextId;
|
||||
mThreadId = inThreadId;
|
||||
mThreadPriority = inPriority;
|
||||
mCpuId = inCpuId;
|
||||
}
|
||||
|
||||
void init( const EventContextInformation& inData )
|
||||
{
|
||||
mContextId = inData.mContextId;
|
||||
mThreadId = inData.mThreadId;
|
||||
mThreadPriority = inData.mThreadPriority;
|
||||
mCpuId = inData.mCpuId;
|
||||
}
|
||||
|
||||
template<typename TStreamType>
|
||||
uint32_t streamify( TStreamType& inStream, EventStreamCompressionFlags::Enum inContextIdFlags )
|
||||
{
|
||||
uint32_t writtenSize = inStream.streamify( "ThreadId", mThreadId );
|
||||
writtenSize += inStream.streamify("ContextId", mContextId, inContextIdFlags);
|
||||
writtenSize += inStream.streamify("ThreadPriority", mThreadPriority);
|
||||
writtenSize += inStream.streamify("CpuId", mCpuId);
|
||||
return writtenSize;
|
||||
}
|
||||
|
||||
bool operator==( const EventContextInformation& other ) const
|
||||
{
|
||||
return mThreadId == other.mThreadId
|
||||
&& mContextId == other.mContextId
|
||||
&& mThreadPriority == other.mThreadPriority
|
||||
&& mCpuId == other.mCpuId;
|
||||
}
|
||||
|
||||
void setToDefault()
|
||||
{
|
||||
*this = EventContextInformation();
|
||||
}
|
||||
};
|
||||
|
||||
//Profile event contains all the data required to tell the profile what is going
|
||||
//on.
|
||||
struct ProfileEvent
|
||||
{
|
||||
EventContextInformation mContextInformation;
|
||||
RelativeProfileEvent mTimeData; //timestamp in seconds.
|
||||
void init( uint32_t inThreadId, uint64_t inContextId, uint8_t inCpuId, uint8_t inPriority, uint64_t inTs )
|
||||
{
|
||||
mContextInformation.init( inThreadId, inContextId, inPriority, inCpuId );
|
||||
mTimeData.init( inTs );
|
||||
}
|
||||
|
||||
void init( const ProfileEvent& inData )
|
||||
{
|
||||
mContextInformation.init( inData.mContextInformation );
|
||||
mTimeData.init( inData.mTimeData );
|
||||
}
|
||||
|
||||
bool operator==( const ProfileEvent& other ) const
|
||||
{
|
||||
return mContextInformation == other.mContextInformation
|
||||
&& mTimeData == other.mTimeData;
|
||||
}
|
||||
|
||||
template<typename TStreamType>
|
||||
uint32_t streamify( TStreamType& inStream, const EventHeader& inHeader )
|
||||
{
|
||||
uint32_t writtenSize = mContextInformation.streamify(inStream, inHeader.getContextIdCompressionFlags());
|
||||
writtenSize += mTimeData.streamify(inStream, inHeader);
|
||||
return writtenSize;
|
||||
}
|
||||
|
||||
uint32_t getEventSize(const EventHeader& inHeader)
|
||||
{
|
||||
uint32_t eventSize = 0;
|
||||
// time is stored depending on the conpress flag mTimeData.streamify(inStream, inHeader);
|
||||
switch (inHeader.getTimestampCompressionFlags())
|
||||
{
|
||||
case EventStreamCompressionFlags::U8:
|
||||
eventSize++;
|
||||
break;
|
||||
case EventStreamCompressionFlags::U16:
|
||||
eventSize += 2;
|
||||
break;
|
||||
case EventStreamCompressionFlags::U32:
|
||||
eventSize += 4;
|
||||
break;
|
||||
case EventStreamCompressionFlags::U64:
|
||||
eventSize += 8;
|
||||
break;
|
||||
}
|
||||
|
||||
// context information
|
||||
// mContextInformation.streamify( inStream, inHeader.getContextIdCompressionFlags() );
|
||||
eventSize += 6; // uint32_t mThreadId; uint8_t mThreadPriority; uint8_t mCpuId;
|
||||
switch (inHeader.getContextIdCompressionFlags())
|
||||
{
|
||||
case EventStreamCompressionFlags::U8:
|
||||
eventSize++;
|
||||
break;
|
||||
case EventStreamCompressionFlags::U16:
|
||||
eventSize += 2;
|
||||
break;
|
||||
case EventStreamCompressionFlags::U32:
|
||||
eventSize += 4;
|
||||
break;
|
||||
case EventStreamCompressionFlags::U64:
|
||||
eventSize += 8;
|
||||
break;
|
||||
}
|
||||
|
||||
return eventSize;
|
||||
}
|
||||
|
||||
uint64_t getTimestamp() const { return mTimeData.getTimestamp(); }
|
||||
void setTimestamp( uint64_t inTs ) { mTimeData.setTimestamp( inTs ); }
|
||||
|
||||
void setupHeader( EventHeader& inHeader, uint64_t inLastTimestamp )
|
||||
{
|
||||
mTimeData.setupHeader( inHeader, inLastTimestamp );
|
||||
inHeader.setContextIdCompressionFlags( mContextInformation.mContextId );
|
||||
}
|
||||
};
|
||||
|
||||
//profile start event starts the profile session.
|
||||
struct StartEvent : public ProfileEvent
|
||||
{
|
||||
void init( uint32_t inThreadId = 0, uint64_t inContextId = 0, uint8_t inCpuId = 0, uint8_t inPriority = 0, uint64_t inTensOfNanoSeconds = 0 )
|
||||
{
|
||||
ProfileEvent::init( inThreadId, inContextId, inCpuId, inPriority, inTensOfNanoSeconds );
|
||||
}
|
||||
void init( const StartEvent& inData )
|
||||
{
|
||||
ProfileEvent::init( inData );
|
||||
}
|
||||
|
||||
RelativeStartEvent getRelativeEvent() const { RelativeStartEvent theEvent; theEvent.init( mTimeData.mTensOfNanoSeconds ); return theEvent; }
|
||||
EventTypes::Enum getRelativeEventType() const { return getEventType<RelativeStartEvent>(); }
|
||||
};
|
||||
|
||||
template<> inline EventTypes::Enum getEventType<StartEvent>() { return EventTypes::StartEvent; }
|
||||
|
||||
//Profile stop event stops the profile session.
|
||||
struct StopEvent : public ProfileEvent
|
||||
{
|
||||
void init( uint32_t inThreadId = 0, uint64_t inContextId = 0, uint8_t inCpuId = 0, uint8_t inPriority = 0, uint64_t inTensOfNanoSeconds = 0 )
|
||||
{
|
||||
ProfileEvent::init( inThreadId, inContextId, inCpuId, inPriority, inTensOfNanoSeconds );
|
||||
}
|
||||
void init( const StopEvent& inData )
|
||||
{
|
||||
ProfileEvent::init( inData );
|
||||
}
|
||||
RelativeStopEvent getRelativeEvent() const { RelativeStopEvent theEvent; theEvent.init( mTimeData.mTensOfNanoSeconds ); return theEvent; }
|
||||
EventTypes::Enum getRelativeEventType() const { return getEventType<RelativeStopEvent>(); }
|
||||
};
|
||||
|
||||
template<> inline EventTypes::Enum getEventType<StopEvent>() { return EventTypes::StopEvent; }
|
||||
|
||||
struct EventValue
|
||||
{
|
||||
uint64_t mValue;
|
||||
uint64_t mContextId;
|
||||
uint32_t mThreadId;
|
||||
void init( int64_t inValue = 0, uint64_t inContextId = 0, uint32_t inThreadId = 0 )
|
||||
{
|
||||
mValue = static_cast<uint64_t>( inValue );
|
||||
mContextId = inContextId;
|
||||
mThreadId = inThreadId;
|
||||
}
|
||||
|
||||
void init( const EventValue& inData )
|
||||
{
|
||||
mValue = inData.mValue;
|
||||
mContextId = inData.mContextId;
|
||||
mThreadId = inData.mThreadId;
|
||||
}
|
||||
|
||||
int64_t getValue() const { return static_cast<int16_t>( mValue ); }
|
||||
|
||||
void setupHeader( EventHeader& inHeader )
|
||||
{
|
||||
mValue = inHeader.compressTimestamp( 0, mValue );
|
||||
inHeader.setContextIdCompressionFlags( mContextId );
|
||||
}
|
||||
|
||||
template<typename TStreamType>
|
||||
uint32_t streamify( TStreamType& inStream, const EventHeader& inHeader )
|
||||
{
|
||||
uint32_t writtenSize = inStream.streamify("Value", mValue, inHeader.getTimestampCompressionFlags());
|
||||
writtenSize += inStream.streamify("ContextId", mContextId, inHeader.getContextIdCompressionFlags());
|
||||
writtenSize += inStream.streamify("ThreadId", mThreadId);
|
||||
return writtenSize;
|
||||
}
|
||||
|
||||
uint32_t getEventSize(const EventHeader& inHeader)
|
||||
{
|
||||
uint32_t eventSize = 0;
|
||||
// value
|
||||
switch (inHeader.getTimestampCompressionFlags())
|
||||
{
|
||||
case EventStreamCompressionFlags::U8:
|
||||
eventSize++;
|
||||
break;
|
||||
case EventStreamCompressionFlags::U16:
|
||||
eventSize += 2;
|
||||
break;
|
||||
case EventStreamCompressionFlags::U32:
|
||||
eventSize += 4;
|
||||
break;
|
||||
case EventStreamCompressionFlags::U64:
|
||||
eventSize += 8;
|
||||
break;
|
||||
}
|
||||
|
||||
// context information
|
||||
switch (inHeader.getContextIdCompressionFlags())
|
||||
{
|
||||
case EventStreamCompressionFlags::U8:
|
||||
eventSize++;
|
||||
break;
|
||||
case EventStreamCompressionFlags::U16:
|
||||
eventSize += 2;
|
||||
break;
|
||||
case EventStreamCompressionFlags::U32:
|
||||
eventSize += 4;
|
||||
break;
|
||||
case EventStreamCompressionFlags::U64:
|
||||
eventSize += 8;
|
||||
break;
|
||||
}
|
||||
|
||||
eventSize += 4; // uint32_t mThreadId;
|
||||
|
||||
return eventSize;
|
||||
}
|
||||
|
||||
bool operator==( const EventValue& other ) const
|
||||
{
|
||||
return mValue == other.mValue
|
||||
&& mContextId == other.mContextId
|
||||
&& mThreadId == other.mThreadId;
|
||||
}
|
||||
|
||||
template<typename THandlerType>
|
||||
void handle( THandlerType* inHdlr, uint16_t eventId ) const
|
||||
{
|
||||
inHdlr->onEventValue( PxProfileEventId( eventId ), mThreadId, mContextId, getValue() );
|
||||
}
|
||||
|
||||
};
|
||||
template<> inline EventTypes::Enum getEventType<EventValue>() { return EventTypes::EventValue; }
|
||||
|
||||
//obsolete, placeholder to skip data from PhysX SDKs < 3.4
|
||||
struct CUDAProfileBuffer
|
||||
{
|
||||
uint64_t mTimestamp;
|
||||
float mTimespan;
|
||||
const uint8_t* mCudaData;
|
||||
uint32_t mBufLen;
|
||||
uint32_t mVersion;
|
||||
|
||||
template<typename TStreamType>
|
||||
uint32_t streamify( TStreamType& inStream, const EventHeader& )
|
||||
{
|
||||
uint32_t writtenSize = inStream.streamify("Timestamp", mTimestamp);
|
||||
writtenSize += inStream.streamify("Timespan", mTimespan);
|
||||
writtenSize += inStream.streamify("CudaData", mCudaData, mBufLen);
|
||||
writtenSize += inStream.streamify("BufLen", mBufLen);
|
||||
writtenSize += inStream.streamify("Version", mVersion);
|
||||
return writtenSize;
|
||||
}
|
||||
|
||||
bool operator==( const CUDAProfileBuffer& other ) const
|
||||
{
|
||||
return mTimestamp == other.mTimestamp
|
||||
&& mTimespan == other.mTimespan
|
||||
&& mBufLen == other.mBufLen
|
||||
&& memcmp( mCudaData, other.mCudaData, mBufLen ) == 0
|
||||
&& mVersion == other.mVersion;
|
||||
}
|
||||
};
|
||||
|
||||
template<> inline EventTypes::Enum getEventType<CUDAProfileBuffer>() { return EventTypes::CUDAProfileBuffer; }
|
||||
|
||||
//Provides a generic equal operation for event data objects.
|
||||
template <typename TEventData>
|
||||
struct EventDataEqualOperator
|
||||
{
|
||||
TEventData mData;
|
||||
EventDataEqualOperator( const TEventData& inD ) : mData( inD ) {}
|
||||
template<typename TDataType> bool operator()( const TDataType& inRhs ) const { return mData.toType( Type2Type<TDataType>() ) == inRhs; }
|
||||
bool operator()() const { return false; }
|
||||
};
|
||||
|
||||
/**
|
||||
* Generic event container that combines and even header with the generic event data type.
|
||||
* Provides unsafe and typesafe access to the event data.
|
||||
*/
|
||||
class Event
|
||||
{
|
||||
public:
|
||||
typedef PX_PROFILE_UNION_7(StartEvent, StopEvent, RelativeStartEvent, RelativeStopEvent, EventValue, CUDAProfileBuffer, uint8_t) EventData;
|
||||
|
||||
private:
|
||||
EventHeader mHeader;
|
||||
EventData mData;
|
||||
public:
|
||||
Event() {}
|
||||
|
||||
template <typename TDataType>
|
||||
Event( EventHeader inHeader, const TDataType& inData )
|
||||
: mHeader( inHeader )
|
||||
{
|
||||
mData.init<TDataType>(inData);
|
||||
}
|
||||
|
||||
template<typename TDataType>
|
||||
Event( uint16_t eventId, const TDataType& inData )
|
||||
: mHeader( getEventType<TDataType>(), eventId )
|
||||
{
|
||||
mData.init<TDataType>(inData);
|
||||
}
|
||||
const EventHeader& getHeader() const { return mHeader; }
|
||||
const EventData& getData() const { return mData; }
|
||||
|
||||
template<typename TDataType>
|
||||
const TDataType& getValue() const { PX_ASSERT( mHeader.mEventType == getEventType<TDataType>() ); return mData.toType<TDataType>(); }
|
||||
|
||||
template<typename TDataType>
|
||||
TDataType& getValue() { PX_ASSERT( mHeader.mEventType == getEventType<TDataType>() ); return mData.toType<TDataType>(); }
|
||||
|
||||
template<typename TRetVal, typename TOperator>
|
||||
inline TRetVal visit( TOperator inOp ) const;
|
||||
|
||||
bool operator==( const Event& inOther ) const
|
||||
{
|
||||
if ( !(mHeader == inOther.mHeader ) ) return false;
|
||||
if ( mHeader.mEventType )
|
||||
return inOther.visit<bool>( EventDataEqualOperator<EventData>( mData ) );
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
//Combining the above union type with an event type means that an object can get the exact
|
||||
//data out of the union. Using this function means that all callsites will be forced to
|
||||
//deal with the newer datatypes and that the switch statement only exists in once place.
|
||||
//Implements conversion from enum -> datatype
|
||||
template<typename TRetVal, typename TOperator>
|
||||
TRetVal visit( EventTypes::Enum inEventType, const Event::EventData& inData, TOperator inOperator )
|
||||
{
|
||||
switch( inEventType )
|
||||
{
|
||||
case EventTypes::StartEvent: return inOperator( inData.toType( Type2Type<StartEvent>() ) );
|
||||
case EventTypes::StopEvent: return inOperator( inData.toType( Type2Type<StopEvent>() ) );
|
||||
case EventTypes::RelativeStartEvent: return inOperator( inData.toType( Type2Type<RelativeStartEvent>() ) );
|
||||
case EventTypes::RelativeStopEvent: return inOperator( inData.toType( Type2Type<RelativeStopEvent>() ) );
|
||||
case EventTypes::EventValue: return inOperator( inData.toType( Type2Type<EventValue>() ) );
|
||||
//obsolete, placeholder to skip data from PhysX SDKs < 3.4
|
||||
case EventTypes::CUDAProfileBuffer: return inOperator( inData.toType( Type2Type<CUDAProfileBuffer>() ) );
|
||||
case EventTypes::Unknown: break;
|
||||
}
|
||||
uint8_t type = static_cast<uint8_t>( inEventType );
|
||||
return inOperator( type );
|
||||
}
|
||||
|
||||
template<typename TRetVal, typename TOperator>
|
||||
inline TRetVal Event::visit( TOperator inOp ) const
|
||||
{
|
||||
return physx::profile::visit<TRetVal>( static_cast<EventTypes::Enum>(mHeader.mEventType), mData, inOp );
|
||||
}
|
||||
} }
|
||||
|
||||
#endif // PXPVDSDK_PXPROFILEEVENTS_H
|
||||
92
physx/source/pvd/src/PxProfileMemory.h
Normal file
92
physx/source/pvd/src/PxProfileMemory.h
Normal file
@ -0,0 +1,92 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
|
||||
#ifndef PXPVDSDK_PXPROFILEMEMORY_H
|
||||
#define PXPVDSDK_PXPROFILEMEMORY_H
|
||||
|
||||
#include "PxProfileEventBufferClientManager.h"
|
||||
#include "PxProfileEventSender.h"
|
||||
#include "PsBroadcast.h"
|
||||
|
||||
namespace physx { namespace profile {
|
||||
|
||||
/**
|
||||
\brief Record events so a late-connecting client knows about
|
||||
all outstanding allocations
|
||||
*/
|
||||
class PxProfileMemoryEventRecorder : public shdfnd::AllocationListener
|
||||
{
|
||||
protected:
|
||||
virtual ~PxProfileMemoryEventRecorder(){}
|
||||
public:
|
||||
/**
|
||||
\brief Set the allocation listener
|
||||
\param inListener Allocation listener.
|
||||
*/
|
||||
virtual void setListener(AllocationListener* inListener) = 0;
|
||||
/**
|
||||
\brief Release the instance.
|
||||
*/
|
||||
virtual void release() = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Stores memory events into the memory buffer.
|
||||
*/
|
||||
class PxProfileMemoryEventBuffer
|
||||
: public shdfnd::AllocationListener //add a new event to the buffer
|
||||
, public PxProfileEventBufferClientManager //add clients to handle the serialized memory events
|
||||
, public PxProfileEventFlusher //flush the buffer
|
||||
{
|
||||
protected:
|
||||
virtual ~PxProfileMemoryEventBuffer(){}
|
||||
public:
|
||||
|
||||
/**
|
||||
\brief Release the instance.
|
||||
*/
|
||||
virtual void release() = 0;
|
||||
|
||||
/**
|
||||
\brief Create a non-mutex-protected event buffer.
|
||||
\param inAllocator Allocation callback.
|
||||
\param inBufferSize Internal buffer size.
|
||||
*/
|
||||
static PxProfileMemoryEventBuffer& createMemoryEventBuffer(PxAllocatorCallback& inAllocator, uint32_t inBufferSize = 0x1000);
|
||||
};
|
||||
|
||||
|
||||
|
||||
} } // namespace physx
|
||||
|
||||
|
||||
#endif // PXPVDSDK_PXPROFILEMEMORY_H
|
||||
|
||||
|
||||
192
physx/source/pvd/src/PxProfileMemoryBuffer.h
Normal file
192
physx/source/pvd/src/PxProfileMemoryBuffer.h
Normal file
@ -0,0 +1,192 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
|
||||
#ifndef PXPVDSDK_PXPROFILEMEMORYBUFFER_H
|
||||
#define PXPVDSDK_PXPROFILEMEMORYBUFFER_H
|
||||
|
||||
#include "PsAllocator.h"
|
||||
#include "foundation/PxMemory.h"
|
||||
|
||||
namespace physx { namespace profile {
|
||||
|
||||
template<typename TAllocator = typename shdfnd::AllocatorTraits<uint8_t>::Type >
|
||||
class MemoryBuffer : public TAllocator
|
||||
{
|
||||
uint8_t* mBegin;
|
||||
uint8_t* mEnd;
|
||||
uint8_t* mCapacityEnd;
|
||||
|
||||
public:
|
||||
MemoryBuffer( const TAllocator& inAlloc = TAllocator() ) : TAllocator( inAlloc ), mBegin( 0 ), mEnd( 0 ), mCapacityEnd( 0 ) {}
|
||||
~MemoryBuffer()
|
||||
{
|
||||
if ( mBegin ) TAllocator::deallocate( mBegin );
|
||||
}
|
||||
uint32_t size() const { return static_cast<uint32_t>( mEnd - mBegin ); }
|
||||
uint32_t capacity() const { return static_cast<uint32_t>( mCapacityEnd - mBegin ); }
|
||||
uint8_t* begin() { return mBegin; }
|
||||
uint8_t* end() { return mEnd; }
|
||||
void setEnd(uint8_t* nEnd) { mEnd = nEnd; }
|
||||
const uint8_t* begin() const { return mBegin; }
|
||||
const uint8_t* end() const { return mEnd; }
|
||||
void clear() { mEnd = mBegin; }
|
||||
uint32_t write( uint8_t inValue )
|
||||
{
|
||||
growBuf( 1 );
|
||||
*mEnd = inValue;
|
||||
++mEnd;
|
||||
return 1;
|
||||
}
|
||||
|
||||
template<typename TDataType>
|
||||
uint32_t write( const TDataType& inValue )
|
||||
{
|
||||
uint32_t writtenSize = sizeof(TDataType);
|
||||
growBuf(writtenSize);
|
||||
const uint8_t* __restrict readPtr = reinterpret_cast< const uint8_t* >( &inValue );
|
||||
uint8_t* __restrict writePtr = mEnd;
|
||||
for ( uint32_t idx = 0; idx < sizeof(TDataType); ++idx ) writePtr[idx] = readPtr[idx];
|
||||
mEnd += writtenSize;
|
||||
return writtenSize;
|
||||
}
|
||||
|
||||
template<typename TDataType>
|
||||
uint32_t write( const TDataType* inValue, uint32_t inLength )
|
||||
{
|
||||
if ( inValue && inLength )
|
||||
{
|
||||
uint32_t writeSize = inLength * sizeof( TDataType );
|
||||
growBuf( writeSize );
|
||||
PxMemCopy( mBegin + size(), inValue, writeSize );
|
||||
mEnd += writeSize;
|
||||
return writeSize;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// used by atomic write. Store the data and write the end afterwards
|
||||
// we dont check the buffer size, it should not resize on the fly
|
||||
template<typename TDataType>
|
||||
uint32_t write(const TDataType* inValue, uint32_t inLength, int32_t index)
|
||||
{
|
||||
if (inValue && inLength)
|
||||
{
|
||||
uint32_t writeSize = inLength * sizeof(TDataType);
|
||||
PX_ASSERT(mBegin + index + writeSize < mCapacityEnd);
|
||||
PxMemCopy(mBegin + index, inValue, writeSize);
|
||||
return writeSize;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void growBuf( uint32_t inAmount )
|
||||
{
|
||||
uint32_t newSize = size() + inAmount;
|
||||
reserve( newSize );
|
||||
}
|
||||
void resize( uint32_t inAmount )
|
||||
{
|
||||
reserve( inAmount );
|
||||
mEnd = mBegin + inAmount;
|
||||
}
|
||||
void reserve( uint32_t newSize )
|
||||
{
|
||||
uint32_t currentSize = size();
|
||||
if ( newSize >= capacity() )
|
||||
{
|
||||
const uint32_t allocSize = mBegin ? newSize * 2 : newSize;
|
||||
|
||||
uint8_t* newData = static_cast<uint8_t*>(TAllocator::allocate(allocSize, __FILE__, __LINE__));
|
||||
memset(newData, 0xf,allocSize);
|
||||
if ( mBegin )
|
||||
{
|
||||
PxMemCopy( newData, mBegin, currentSize );
|
||||
TAllocator::deallocate( mBegin );
|
||||
}
|
||||
mBegin = newData;
|
||||
mEnd = mBegin + currentSize;
|
||||
mCapacityEnd = mBegin + allocSize;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class TempMemoryBuffer
|
||||
{
|
||||
uint8_t* mBegin;
|
||||
uint8_t* mEnd;
|
||||
uint8_t* mCapacityEnd;
|
||||
|
||||
public:
|
||||
TempMemoryBuffer(uint8_t* data, int32_t size) : mBegin(data), mEnd(data), mCapacityEnd(data + size) {}
|
||||
~TempMemoryBuffer()
|
||||
{
|
||||
}
|
||||
uint32_t size() const { return static_cast<uint32_t>(mEnd - mBegin); }
|
||||
uint32_t capacity() const { return static_cast<uint32_t>(mCapacityEnd - mBegin); }
|
||||
const uint8_t* begin() { return mBegin; }
|
||||
uint8_t* end() { return mEnd; }
|
||||
const uint8_t* begin() const { return mBegin; }
|
||||
const uint8_t* end() const { return mEnd; }
|
||||
uint32_t write(uint8_t inValue)
|
||||
{
|
||||
*mEnd = inValue;
|
||||
++mEnd;
|
||||
return 1;
|
||||
}
|
||||
|
||||
template<typename TDataType>
|
||||
uint32_t write(const TDataType& inValue)
|
||||
{
|
||||
uint32_t writtenSize = sizeof(TDataType);
|
||||
const uint8_t* __restrict readPtr = reinterpret_cast<const uint8_t*>(&inValue);
|
||||
uint8_t* __restrict writePtr = mEnd;
|
||||
for (uint32_t idx = 0; idx < sizeof(TDataType); ++idx) writePtr[idx] = readPtr[idx];
|
||||
mEnd += writtenSize;
|
||||
return writtenSize;
|
||||
}
|
||||
|
||||
template<typename TDataType>
|
||||
uint32_t write(const TDataType* inValue, uint32_t inLength)
|
||||
{
|
||||
if (inValue && inLength)
|
||||
{
|
||||
uint32_t writeSize = inLength * sizeof(TDataType);
|
||||
PxMemCopy(mBegin + size(), inValue, writeSize);
|
||||
mEnd += writeSize;
|
||||
return writeSize;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif // PXPVDSDK_PXPROFILEMEMORYBUFFER_H
|
||||
157
physx/source/pvd/src/PxProfileMemoryEventBuffer.h
Normal file
157
physx/source/pvd/src/PxProfileMemoryEventBuffer.h
Normal file
@ -0,0 +1,157 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
|
||||
#ifndef PXPVDSDK_PXPROFILEMEMORYEVENTBUFFER_H
|
||||
#define PXPVDSDK_PXPROFILEMEMORYEVENTBUFFER_H
|
||||
|
||||
#include "PxProfileDataBuffer.h"
|
||||
#include "PxProfileMemoryEvents.h"
|
||||
#include "PxProfileMemory.h"
|
||||
#include "PxProfileScopedMutexLock.h"
|
||||
#include "PxProfileAllocatorWrapper.h"
|
||||
#include "PxProfileEventMutex.h"
|
||||
|
||||
#include "PsHash.h"
|
||||
#include "PsHashMap.h"
|
||||
#include "PsUserAllocated.h"
|
||||
|
||||
namespace physx { namespace profile {
|
||||
|
||||
template<typename TMutex,
|
||||
typename TScopedLock>
|
||||
class MemoryEventBuffer : public DataBuffer<TMutex, TScopedLock>
|
||||
{
|
||||
public:
|
||||
typedef DataBuffer<TMutex, TScopedLock> TBaseType;
|
||||
typedef typename TBaseType::TMutexType TMutexType;
|
||||
typedef typename TBaseType::TScopedLockType TScopedLockType;
|
||||
typedef typename TBaseType::TU8AllocatorType TU8AllocatorType;
|
||||
typedef typename TBaseType::TMemoryBufferType TMemoryBufferType;
|
||||
typedef typename TBaseType::TBufferClientArray TBufferClientArray;
|
||||
typedef shdfnd::HashMap<const char*, uint32_t, shdfnd::Hash<const char*>, TU8AllocatorType> TCharPtrToHandleMap;
|
||||
|
||||
protected:
|
||||
TCharPtrToHandleMap mStringTable;
|
||||
|
||||
public:
|
||||
|
||||
MemoryEventBuffer( PxAllocatorCallback& cback
|
||||
, uint32_t inBufferFullAmount
|
||||
, TMutexType* inBufferMutex )
|
||||
: TBaseType( &cback, inBufferFullAmount, inBufferMutex, "struct physx::profile::MemoryEvent" )
|
||||
, mStringTable( TU8AllocatorType( TBaseType::getWrapper(), "MemoryEventStringBuffer" ) )
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t getHandle( const char* inData )
|
||||
{
|
||||
if ( inData == NULL ) inData = "";
|
||||
const typename TCharPtrToHandleMap::Entry* result( mStringTable.find( inData ) );
|
||||
if ( result )
|
||||
return result->second;
|
||||
uint32_t hdl = mStringTable.size() + 1;
|
||||
mStringTable.insert( inData, hdl );
|
||||
StringTableEvent theEvent;
|
||||
theEvent.init( inData, hdl );
|
||||
sendEvent( theEvent );
|
||||
return hdl;
|
||||
}
|
||||
|
||||
void onAllocation( size_t inSize, const char* inType, const char* inFile, uint32_t inLine, uint64_t addr )
|
||||
{
|
||||
if ( addr == 0 )
|
||||
return;
|
||||
uint32_t typeHdl( getHandle( inType ) );
|
||||
uint32_t fileHdl( getHandle( inFile ) );
|
||||
AllocationEvent theEvent;
|
||||
theEvent.init( inSize, typeHdl, fileHdl, inLine, addr );
|
||||
sendEvent( theEvent );
|
||||
}
|
||||
|
||||
void onDeallocation( uint64_t addr )
|
||||
{
|
||||
if ( addr == 0 )
|
||||
return;
|
||||
DeallocationEvent theEvent;
|
||||
theEvent.init( addr );
|
||||
sendEvent( theEvent );
|
||||
}
|
||||
|
||||
void flushProfileEvents()
|
||||
{
|
||||
TBaseType::flushEvents();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
template<typename TDataType>
|
||||
void sendEvent( TDataType inType )
|
||||
{
|
||||
MemoryEventHeader theHeader( getMemoryEventType<TDataType>() );
|
||||
inType.setup( theHeader );
|
||||
theHeader.streamify( TBaseType::mSerializer );
|
||||
inType.streamify( TBaseType::mSerializer, theHeader );
|
||||
if ( TBaseType::mDataArray.size() >= TBaseType::mBufferFullAmount )
|
||||
flushProfileEvents();
|
||||
}
|
||||
};
|
||||
|
||||
class PxProfileMemoryEventBufferImpl : public shdfnd::UserAllocated
|
||||
, public PxProfileMemoryEventBuffer
|
||||
{
|
||||
typedef MemoryEventBuffer<PxProfileEventMutex, NullLock> TMemoryBufferType;
|
||||
TMemoryBufferType mBuffer;
|
||||
|
||||
public:
|
||||
PxProfileMemoryEventBufferImpl( PxAllocatorCallback& alloc, uint32_t inBufferFullAmount )
|
||||
: mBuffer( alloc, inBufferFullAmount, NULL )
|
||||
{
|
||||
}
|
||||
|
||||
virtual void onAllocation( size_t size, const char* typeName, const char* filename, int line, void* allocatedMemory )
|
||||
{
|
||||
mBuffer.onAllocation( size, typeName, filename, uint32_t(line), static_cast<uint64_t>(reinterpret_cast<size_t>(allocatedMemory)) );
|
||||
}
|
||||
virtual void onDeallocation( void* allocatedMemory )
|
||||
{
|
||||
mBuffer.onDeallocation(static_cast<uint64_t>(reinterpret_cast<size_t>(allocatedMemory)) );
|
||||
}
|
||||
|
||||
virtual void addClient( PxProfileEventBufferClient& inClient ) { mBuffer.addClient( inClient ); }
|
||||
virtual void removeClient( PxProfileEventBufferClient& inClient ) { mBuffer.removeClient( inClient ); }
|
||||
virtual bool hasClients() const { return mBuffer.hasClients(); }
|
||||
|
||||
virtual void flushProfileEvents() { mBuffer.flushProfileEvents(); }
|
||||
|
||||
virtual void release(){ PX_PROFILE_DELETE( mBuffer.getWrapper().getAllocator(), this ); }
|
||||
};
|
||||
}}
|
||||
|
||||
#endif // PXPVDSDK_PXPROFILEMEMORYEVENTBUFFER_H
|
||||
411
physx/source/pvd/src/PxProfileMemoryEvents.h
Normal file
411
physx/source/pvd/src/PxProfileMemoryEvents.h
Normal file
@ -0,0 +1,411 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
|
||||
#ifndef PXPVDSDK_PXPROFILEMEMORYEVENTS_H
|
||||
#define PXPVDSDK_PXPROFILEMEMORYEVENTS_H
|
||||
|
||||
#include "PxProfileEvents.h"
|
||||
|
||||
//Memory events define their own event stream
|
||||
|
||||
namespace physx { namespace profile {
|
||||
struct MemoryEventTypes
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Unknown = 0,
|
||||
StringTableEvent, //introduce a new mapping of const char* -> integer
|
||||
AllocationEvent,
|
||||
DeallocationEvent,
|
||||
FullAllocationEvent
|
||||
};
|
||||
};
|
||||
|
||||
template<unsigned numBits, typename TDataType>
|
||||
inline unsigned char convertToNBits( TDataType inType )
|
||||
{
|
||||
uint8_t conversion = static_cast<uint8_t>( inType );
|
||||
PX_ASSERT( conversion < (1 << numBits) );
|
||||
return conversion;
|
||||
}
|
||||
|
||||
template<typename TDataType>
|
||||
inline unsigned char convertToTwoBits( TDataType inType )
|
||||
{
|
||||
return convertToNBits<2>( inType );
|
||||
}
|
||||
|
||||
template<typename TDataType>
|
||||
inline unsigned char convertToFourBits( TDataType inType )
|
||||
{
|
||||
return convertToNBits<4>( inType );
|
||||
}
|
||||
|
||||
inline EventStreamCompressionFlags::Enum fromNumber( uint8_t inNum ) { return static_cast<EventStreamCompressionFlags::Enum>( inNum ); }
|
||||
|
||||
template<unsigned lhs, unsigned rhs>
|
||||
inline void compileCheckSize()
|
||||
{
|
||||
PX_COMPILE_TIME_ASSERT( lhs <= rhs );
|
||||
}
|
||||
|
||||
//Used for predictable bit fields.
|
||||
template<typename TDataType
|
||||
, uint8_t TNumBits
|
||||
, uint8_t TOffset
|
||||
, typename TInputType>
|
||||
struct BitMaskSetter
|
||||
{
|
||||
//Create a mask that masks out the orginal value shift into place
|
||||
static TDataType createOffsetMask() { return TDataType(createMask() << TOffset); }
|
||||
//Create a mask of TNumBits number of tis
|
||||
static TDataType createMask() { return static_cast<TDataType>((1 << TNumBits) - 1); }
|
||||
void setValue( TDataType& inCurrent, TInputType inData )
|
||||
{
|
||||
PX_ASSERT( inData < ( 1 << TNumBits ) );
|
||||
|
||||
//Create a mask to remove the current value.
|
||||
TDataType theMask = TDataType(~(createOffsetMask()));
|
||||
//Clear out current value.
|
||||
inCurrent = TDataType(inCurrent & theMask);
|
||||
//Create the new value.
|
||||
TDataType theAddition = static_cast<TDataType>( inData << TOffset );
|
||||
//or it into the existing value.
|
||||
inCurrent = TDataType(inCurrent | theAddition);
|
||||
}
|
||||
|
||||
TInputType getValue( TDataType inCurrent )
|
||||
{
|
||||
return static_cast<TInputType>( ( inCurrent >> TOffset ) & createMask() );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct MemoryEventHeader
|
||||
{
|
||||
uint16_t mValue;
|
||||
|
||||
typedef BitMaskSetter<uint16_t, 4, 0, uint8_t> TTypeBitmask;
|
||||
typedef BitMaskSetter<uint16_t, 2, 4, uint8_t> TAddrCompressBitmask;
|
||||
typedef BitMaskSetter<uint16_t, 2, 6, uint8_t> TTypeCompressBitmask;
|
||||
typedef BitMaskSetter<uint16_t, 2, 8, uint8_t> TFnameCompressBitmask;
|
||||
typedef BitMaskSetter<uint16_t, 2, 10, uint8_t> TSizeCompressBitmask;
|
||||
typedef BitMaskSetter<uint16_t, 2, 12, uint8_t> TLineCompressBitmask;
|
||||
|
||||
//That leaves size as the only thing not compressed usually.
|
||||
|
||||
MemoryEventHeader( MemoryEventTypes::Enum inType = MemoryEventTypes::Unknown )
|
||||
: mValue( 0 )
|
||||
{
|
||||
uint8_t defaultCompression( convertToTwoBits( EventStreamCompressionFlags::U64 ) );
|
||||
TTypeBitmask().setValue( mValue, convertToFourBits( inType ) );
|
||||
TAddrCompressBitmask().setValue( mValue, defaultCompression );
|
||||
TTypeCompressBitmask().setValue( mValue, defaultCompression );
|
||||
TFnameCompressBitmask().setValue( mValue, defaultCompression );
|
||||
TSizeCompressBitmask().setValue( mValue, defaultCompression );
|
||||
TLineCompressBitmask().setValue( mValue, defaultCompression );
|
||||
}
|
||||
|
||||
MemoryEventTypes::Enum getType() const { return static_cast<MemoryEventTypes::Enum>( TTypeBitmask().getValue( mValue ) ); }
|
||||
|
||||
#define DEFINE_MEMORY_HEADER_COMPRESSION_ACCESSOR( name ) \
|
||||
void set##name( EventStreamCompressionFlags::Enum inEnum ) { T##name##Bitmask().setValue( mValue, convertToTwoBits( inEnum ) ); } \
|
||||
EventStreamCompressionFlags::Enum get##name() const { return fromNumber( T##name##Bitmask().getValue( mValue ) ); }
|
||||
|
||||
DEFINE_MEMORY_HEADER_COMPRESSION_ACCESSOR( AddrCompress )
|
||||
DEFINE_MEMORY_HEADER_COMPRESSION_ACCESSOR( TypeCompress )
|
||||
DEFINE_MEMORY_HEADER_COMPRESSION_ACCESSOR( FnameCompress )
|
||||
DEFINE_MEMORY_HEADER_COMPRESSION_ACCESSOR( SizeCompress )
|
||||
DEFINE_MEMORY_HEADER_COMPRESSION_ACCESSOR( LineCompress )
|
||||
|
||||
#undef DEFINE_MEMORY_HEADER_COMPRESSION_ACCESSOR
|
||||
|
||||
bool operator==( const MemoryEventHeader& inOther ) const
|
||||
{
|
||||
return mValue == inOther.mValue;
|
||||
}
|
||||
template<typename TStreamType>
|
||||
void streamify( TStreamType& inStream )
|
||||
{
|
||||
inStream.streamify( "Header", mValue );
|
||||
}
|
||||
};
|
||||
|
||||
//Declaration of type level getMemoryEventType function that maps enumeration event types to datatypes
|
||||
template<typename TDataType>
|
||||
inline MemoryEventTypes::Enum getMemoryEventType() { PX_ASSERT( false ); return MemoryEventTypes::Unknown; }
|
||||
|
||||
inline bool safeStrEq( const char* lhs, const char* rhs )
|
||||
{
|
||||
if ( lhs == rhs )
|
||||
return true;
|
||||
//If they aren't equal, and one of them is null,
|
||||
//then they can't be equal.
|
||||
//This is assuming that the null char* is not equal to
|
||||
//the empty "" char*.
|
||||
if ( !lhs || !rhs )
|
||||
return false;
|
||||
|
||||
return ::strcmp( lhs, rhs ) == 0;
|
||||
}
|
||||
|
||||
struct StringTableEvent
|
||||
{
|
||||
const char* mString;
|
||||
uint32_t mHandle;
|
||||
|
||||
void init( const char* inStr = "", uint32_t inHdl = 0 )
|
||||
{
|
||||
mString = inStr;
|
||||
mHandle = inHdl;
|
||||
}
|
||||
|
||||
void init( const StringTableEvent& inData )
|
||||
{
|
||||
mString = inData.mString;
|
||||
mHandle = inData.mHandle;
|
||||
}
|
||||
|
||||
bool operator==( const StringTableEvent& inOther ) const
|
||||
{
|
||||
return mHandle == inOther.mHandle
|
||||
&& safeStrEq( mString, inOther.mString );
|
||||
}
|
||||
|
||||
void setup( MemoryEventHeader& ) const {}
|
||||
|
||||
template<typename TStreamType>
|
||||
void streamify( TStreamType& inStream, const MemoryEventHeader& )
|
||||
{
|
||||
inStream.streamify( "String", mString );
|
||||
inStream.streamify( "Handle", mHandle );
|
||||
}
|
||||
};
|
||||
template<> inline MemoryEventTypes::Enum getMemoryEventType<StringTableEvent>() { return MemoryEventTypes::StringTableEvent; }
|
||||
|
||||
struct MemoryEventData
|
||||
{
|
||||
uint64_t mAddress;
|
||||
void init( uint64_t addr )
|
||||
{
|
||||
mAddress = addr;
|
||||
}
|
||||
|
||||
void init( const MemoryEventData& inData)
|
||||
{
|
||||
mAddress = inData.mAddress;
|
||||
}
|
||||
|
||||
bool operator==( const MemoryEventData& inOther ) const
|
||||
{
|
||||
return mAddress == inOther.mAddress;
|
||||
}
|
||||
|
||||
void setup( MemoryEventHeader& inHeader ) const
|
||||
{
|
||||
inHeader.setAddrCompress( findCompressionValue( mAddress ) );
|
||||
}
|
||||
|
||||
template<typename TStreamType>
|
||||
void streamify( TStreamType& inStream, const MemoryEventHeader& inHeader )
|
||||
{
|
||||
inStream.streamify( "Address", mAddress, inHeader.getAddrCompress() );
|
||||
}
|
||||
};
|
||||
|
||||
struct AllocationEvent : public MemoryEventData
|
||||
{
|
||||
uint32_t mSize;
|
||||
uint32_t mType;
|
||||
uint32_t mFile;
|
||||
uint32_t mLine;
|
||||
void init( size_t size = 0, uint32_t type = 0, uint32_t file = 0, uint32_t line = 0, uint64_t addr = 0 )
|
||||
{
|
||||
MemoryEventData::init( addr );
|
||||
mSize = static_cast<uint32_t>( size );
|
||||
mType = type;
|
||||
mFile = file;
|
||||
mLine = line;
|
||||
}
|
||||
|
||||
void init( const AllocationEvent& inData )
|
||||
{
|
||||
MemoryEventData::init( inData );
|
||||
mSize = inData.mSize;
|
||||
mType = inData.mType;
|
||||
mFile = inData.mFile;
|
||||
mLine = inData.mLine;
|
||||
}
|
||||
|
||||
bool operator==( const AllocationEvent& inOther ) const
|
||||
{
|
||||
return MemoryEventData::operator==( inOther )
|
||||
&& mSize == inOther.mSize
|
||||
&& mType == inOther.mType
|
||||
&& mFile == inOther.mFile
|
||||
&& mLine == inOther.mLine;
|
||||
}
|
||||
|
||||
void setup( MemoryEventHeader& inHeader ) const
|
||||
{
|
||||
inHeader.setTypeCompress( findCompressionValue( mType ) );
|
||||
inHeader.setFnameCompress( findCompressionValue( mFile ) );
|
||||
inHeader.setSizeCompress( findCompressionValue( mSize ) );
|
||||
inHeader.setLineCompress( findCompressionValue( mLine ) );
|
||||
MemoryEventData::setup( inHeader );
|
||||
}
|
||||
|
||||
template<typename TStreamType>
|
||||
void streamify( TStreamType& inStream, const MemoryEventHeader& inHeader )
|
||||
{
|
||||
inStream.streamify( "Size", mSize, inHeader.getSizeCompress() );
|
||||
inStream.streamify( "Type", mType, inHeader.getTypeCompress() );
|
||||
inStream.streamify( "File", mFile, inHeader.getFnameCompress() );
|
||||
inStream.streamify( "Line", mLine, inHeader.getLineCompress() );
|
||||
MemoryEventData::streamify( inStream, inHeader );
|
||||
}
|
||||
};
|
||||
template<> inline MemoryEventTypes::Enum getMemoryEventType<AllocationEvent>() { return MemoryEventTypes::AllocationEvent; }
|
||||
|
||||
|
||||
struct FullAllocationEvent : public MemoryEventData
|
||||
{
|
||||
size_t mSize;
|
||||
const char* mType;
|
||||
const char* mFile;
|
||||
uint32_t mLine;
|
||||
void init( size_t size, const char* type, const char* file, uint32_t line, uint64_t addr )
|
||||
{
|
||||
MemoryEventData::init( addr );
|
||||
mSize = size;
|
||||
mType = type;
|
||||
mFile = file;
|
||||
mLine = line;
|
||||
}
|
||||
|
||||
void init( const FullAllocationEvent& inData )
|
||||
{
|
||||
MemoryEventData::init( inData );
|
||||
mSize = inData.mSize;
|
||||
mType = inData.mType;
|
||||
mFile = inData.mFile;
|
||||
mLine = inData.mLine;
|
||||
}
|
||||
|
||||
bool operator==( const FullAllocationEvent& inOther ) const
|
||||
{
|
||||
return MemoryEventData::operator==( inOther )
|
||||
&& mSize == inOther.mSize
|
||||
&& safeStrEq( mType, inOther.mType )
|
||||
&& safeStrEq( mFile, inOther.mFile )
|
||||
&& mLine == inOther.mLine;
|
||||
}
|
||||
|
||||
void setup( MemoryEventHeader& ) const {}
|
||||
};
|
||||
|
||||
template<> inline MemoryEventTypes::Enum getMemoryEventType<FullAllocationEvent>() { return MemoryEventTypes::FullAllocationEvent; }
|
||||
|
||||
struct DeallocationEvent : public MemoryEventData
|
||||
{
|
||||
void init( uint64_t addr = 0 ) { MemoryEventData::init( addr ); }
|
||||
void init( const DeallocationEvent& inData ) { MemoryEventData::init( inData ); }
|
||||
};
|
||||
|
||||
template<> inline MemoryEventTypes::Enum getMemoryEventType<DeallocationEvent>() { return MemoryEventTypes::DeallocationEvent; }
|
||||
|
||||
class MemoryEvent
|
||||
{
|
||||
public:
|
||||
typedef PX_PROFILE_UNION_5(StringTableEvent, AllocationEvent, DeallocationEvent, FullAllocationEvent, uint8_t) EventData;
|
||||
|
||||
private:
|
||||
MemoryEventHeader mHeader;
|
||||
EventData mData;
|
||||
public:
|
||||
|
||||
MemoryEvent() {}
|
||||
MemoryEvent( MemoryEventHeader inHeader, const EventData& inData = EventData() )
|
||||
: mHeader( inHeader )
|
||||
, mData( inData )
|
||||
{
|
||||
}
|
||||
|
||||
template<typename TDataType>
|
||||
MemoryEvent( const TDataType& inType )
|
||||
: mHeader( getMemoryEventType<TDataType>() )
|
||||
, mData( inType )
|
||||
{
|
||||
//set the appropriate compression bits.
|
||||
inType.setup( mHeader );
|
||||
}
|
||||
const MemoryEventHeader& getHeader() const { return mHeader; }
|
||||
const EventData& getData() const { return mData; }
|
||||
|
||||
template<typename TDataType>
|
||||
const TDataType& getValue() const { PX_ASSERT( mHeader.getType() == getMemoryEventType<TDataType>() ); return mData.toType<TDataType>(); }
|
||||
|
||||
template<typename TDataType>
|
||||
TDataType& getValue() { PX_ASSERT( mHeader.getType() == getMemoryEventType<TDataType>() ); return mData.toType<TDataType>(); }
|
||||
|
||||
template<typename TRetVal, typename TOperator>
|
||||
inline TRetVal visit( TOperator inOp ) const;
|
||||
|
||||
bool operator==( const MemoryEvent& inOther ) const
|
||||
{
|
||||
if ( !(mHeader == inOther.mHeader ) ) return false;
|
||||
if ( mHeader.getType() )
|
||||
return inOther.visit<bool>( EventDataEqualOperator<EventData>( mData ) );
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename TRetVal, typename TOperator>
|
||||
inline TRetVal visit( MemoryEventTypes::Enum inEventType, const MemoryEvent::EventData& inData, TOperator inOperator )
|
||||
{
|
||||
switch( inEventType )
|
||||
{
|
||||
case MemoryEventTypes::StringTableEvent: return inOperator( inData.toType( Type2Type<StringTableEvent>() ) );
|
||||
case MemoryEventTypes::AllocationEvent: return inOperator( inData.toType( Type2Type<AllocationEvent>() ) );
|
||||
case MemoryEventTypes::DeallocationEvent: return inOperator( inData.toType( Type2Type<DeallocationEvent>() ) );
|
||||
case MemoryEventTypes::FullAllocationEvent: return inOperator( inData.toType( Type2Type<FullAllocationEvent>() ) );
|
||||
case MemoryEventTypes::Unknown: return inOperator( static_cast<uint8_t>( inEventType ) );
|
||||
}
|
||||
return TRetVal();
|
||||
}
|
||||
|
||||
template<typename TRetVal, typename TOperator>
|
||||
inline TRetVal MemoryEvent::visit( TOperator inOp ) const
|
||||
{
|
||||
return physx::profile::visit<TRetVal>( mHeader.getType(), mData, inOp );
|
||||
}
|
||||
}}
|
||||
|
||||
#endif // PXPVDSDK_PXPROFILEMEMORYEVENTS_H
|
||||
107
physx/source/pvd/src/PxProfileScopedEvent.h
Normal file
107
physx/source/pvd/src/PxProfileScopedEvent.h
Normal file
@ -0,0 +1,107 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef PXPVDSDK_PXPROFILESCOPEDEVENT_H
|
||||
#define PXPVDSDK_PXPROFILESCOPEDEVENT_H
|
||||
|
||||
#include "PxProfileEventId.h"
|
||||
#include "PxProfileCompileTimeEventFilter.h"
|
||||
|
||||
namespace physx { namespace profile {
|
||||
|
||||
/**
|
||||
\brief Template version of startEvent, called directly on provided profile buffer.
|
||||
|
||||
\param inBuffer Profile event buffer.
|
||||
\param inId Profile event id.
|
||||
\param inContext Profile event context.
|
||||
*/
|
||||
template<bool TEnabled, typename TBufferType>
|
||||
inline void startEvent( TBufferType* inBuffer, const PxProfileEventId& inId, uint64_t inContext )
|
||||
{
|
||||
if ( TEnabled && inBuffer ) inBuffer->startEvent( inId, inContext );
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Template version of stopEvent, called directly on provided profile buffer.
|
||||
|
||||
\param inBuffer Profile event buffer.
|
||||
\param inId Profile event id.
|
||||
\param inContext Profile event context.
|
||||
*/
|
||||
template<bool TEnabled, typename TBufferType>
|
||||
inline void stopEvent( TBufferType* inBuffer, const PxProfileEventId& inId, uint64_t inContext )
|
||||
{
|
||||
if ( TEnabled && inBuffer ) inBuffer->stopEvent( inId, inContext );
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Template version of startEvent, called directly on provided profile buffer.
|
||||
|
||||
\param inEnabled If profile event is enabled.
|
||||
\param inBuffer Profile event buffer.
|
||||
\param inId Profile event id.
|
||||
\param inContext Profile event context.
|
||||
*/
|
||||
template<typename TBufferType>
|
||||
inline void startEvent( bool inEnabled, TBufferType* inBuffer, const PxProfileEventId& inId, uint64_t inContext )
|
||||
{
|
||||
if ( inEnabled && inBuffer ) inBuffer->startEvent( inId, inContext );
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Template version of stopEvent, called directly on provided profile buffer.
|
||||
|
||||
\param inEnabled If profile event is enabled.
|
||||
\param inBuffer Profile event buffer.
|
||||
\param inId Profile event id.
|
||||
\param inContext Profile event context.
|
||||
*/
|
||||
template<typename TBufferType>
|
||||
inline void stopEvent( bool inEnabled, TBufferType* inBuffer, const PxProfileEventId& inId, uint64_t inContext )
|
||||
{
|
||||
if ( inEnabled && inBuffer ) inBuffer->stopEvent( inId, inContext );
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Template version of eventValue, called directly on provided profile buffer.
|
||||
|
||||
\param inEnabled If profile event is enabled.
|
||||
\param inBuffer Profile event buffer.
|
||||
\param inId Profile event id.
|
||||
\param inContext Profile event context.
|
||||
\param inValue Event value.
|
||||
*/
|
||||
template<typename TBufferType>
|
||||
inline void eventValue( bool inEnabled, TBufferType* inBuffer, const PxProfileEventId& inId, uint64_t inContext, int64_t inValue )
|
||||
{
|
||||
if ( inEnabled && inBuffer ) inBuffer->eventValue( inId, inContext, inValue );
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif // PXPVDSDK_PXPROFILESCOPEDEVENT_H
|
||||
64
physx/source/pvd/src/PxProfileScopedMutexLock.h
Normal file
64
physx/source/pvd/src/PxProfileScopedMutexLock.h
Normal file
@ -0,0 +1,64 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
|
||||
#ifndef PXPVDSDK_PXPROFILESCOPEDMUTEXLOCK_H
|
||||
#define PXPVDSDK_PXPROFILESCOPEDMUTEXLOCK_H
|
||||
|
||||
#include "foundation/Px.h"
|
||||
|
||||
namespace physx { namespace profile {
|
||||
|
||||
/**
|
||||
* Generic class to wrap any mutex type that has lock and unlock methods
|
||||
*/
|
||||
template<typename TMutexType>
|
||||
struct ScopedLockImpl
|
||||
{
|
||||
TMutexType* mMutex;
|
||||
ScopedLockImpl( TMutexType* inM ) : mMutex( inM )
|
||||
{
|
||||
if ( mMutex ) mMutex->lock();
|
||||
}
|
||||
~ScopedLockImpl()
|
||||
{
|
||||
if ( mMutex ) mMutex->unlock();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Null locking system that does nothing.
|
||||
*/
|
||||
struct NullLock
|
||||
{
|
||||
template<typename TDataType> NullLock( TDataType*) {}
|
||||
};
|
||||
}}
|
||||
|
||||
#endif // PXPVDSDK_PXPROFILESCOPEDMUTEXLOCK_H
|
||||
315
physx/source/pvd/src/PxProfileZoneImpl.h
Normal file
315
physx/source/pvd/src/PxProfileZoneImpl.h
Normal file
@ -0,0 +1,315 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
|
||||
#ifndef PXPVDSDK_PXPROFILEZONEIMPL_H
|
||||
#define PXPVDSDK_PXPROFILEZONEIMPL_H
|
||||
|
||||
#include "PxPvdProfileZone.h"
|
||||
#include "PxProfileZoneManager.h"
|
||||
#include "PxProfileContextProviderImpl.h"
|
||||
#include "PxProfileScopedMutexLock.h"
|
||||
#include "PxProfileEventBufferAtomic.h"
|
||||
#include "PsMutex.h"
|
||||
|
||||
namespace physx { namespace profile {
|
||||
|
||||
/**
|
||||
\brief Simple event filter that enables all events.
|
||||
*/
|
||||
struct PxProfileNullEventFilter
|
||||
{
|
||||
void setEventEnabled( const PxProfileEventId&, bool) { PX_ASSERT(false); }
|
||||
bool isEventEnabled( const PxProfileEventId&) const { return true; }
|
||||
};
|
||||
|
||||
typedef shdfnd::MutexT<PxProfileWrapperReflectionAllocator<uint8_t> > TZoneMutexType;
|
||||
typedef ScopedLockImpl<TZoneMutexType> TZoneLockType;
|
||||
typedef EventBuffer< PxDefaultContextProvider, TZoneMutexType, TZoneLockType, PxProfileNullEventFilter > TZoneEventBufferType;
|
||||
//typedef EventBufferAtomic< PxDefaultContextProvider, TZoneMutexType, TZoneLockType, PxProfileNullEventFilter > TZoneEventBufferType;
|
||||
|
||||
template<typename TNameProvider>
|
||||
class ZoneImpl : TZoneEventBufferType //private inheritance intended
|
||||
, public PxProfileZone
|
||||
, public PxProfileEventBufferClient
|
||||
{
|
||||
typedef shdfnd::MutexT<PxProfileWrapperReflectionAllocator<uint8_t> > TMutexType;
|
||||
typedef PxProfileHashMap<const char*, uint32_t> TNameToEvtIndexMap;
|
||||
//ensure we don't reuse event ids.
|
||||
typedef PxProfileHashMap<uint16_t, const char*> TEvtIdToNameMap;
|
||||
typedef TMutexType::ScopedLock TLockType;
|
||||
|
||||
|
||||
const char* mName;
|
||||
mutable TMutexType mMutex;
|
||||
PxProfileArray<PxProfileEventName> mEventNames;
|
||||
// to avoid locking, read-only and read-write map exist
|
||||
TNameToEvtIndexMap mNameToEvtIndexMapR;
|
||||
TNameToEvtIndexMap mNameToEvtIndexMapRW;
|
||||
//ensure we don't reuse event ids.
|
||||
TEvtIdToNameMap mEvtIdToNameMap;
|
||||
|
||||
PxProfileZoneManager* mProfileZoneManager;
|
||||
|
||||
PxProfileArray<PxProfileZoneClient*> mZoneClients;
|
||||
volatile bool mEventsActive;
|
||||
|
||||
PX_NOCOPY(ZoneImpl<TNameProvider>)
|
||||
public:
|
||||
ZoneImpl( PxAllocatorCallback* inAllocator, const char* inName, uint32_t bufferSize = 0x10000 /*64k*/, const TNameProvider& inProvider = TNameProvider() )
|
||||
: TZoneEventBufferType( inAllocator, bufferSize, PxDefaultContextProvider(), NULL, PxProfileNullEventFilter() )
|
||||
, mName( inName )
|
||||
, mMutex( PxProfileWrapperReflectionAllocator<uint8_t>( mWrapper ) )
|
||||
, mEventNames( mWrapper )
|
||||
, mNameToEvtIndexMapR( mWrapper )
|
||||
, mNameToEvtIndexMapRW( mWrapper )
|
||||
, mEvtIdToNameMap( mWrapper )
|
||||
, mProfileZoneManager( NULL )
|
||||
, mZoneClients( mWrapper )
|
||||
, mEventsActive( false )
|
||||
{
|
||||
TZoneEventBufferType::setBufferMutex( &mMutex );
|
||||
//Initialize the event name structure with existing names from the name provider.
|
||||
PxProfileNames theNames( inProvider.getProfileNames() );
|
||||
for ( uint32_t idx = 0; idx < theNames.eventCount; ++idx )
|
||||
{
|
||||
const PxProfileEventName& theName (theNames.events[idx]);
|
||||
doAddName( theName.name, theName.eventId.eventId, theName.eventId.compileTimeEnabled );
|
||||
}
|
||||
TZoneEventBufferType::addClient( *this );
|
||||
}
|
||||
|
||||
virtual ~ZoneImpl() {
|
||||
if ( mProfileZoneManager != NULL )
|
||||
mProfileZoneManager->removeProfileZone( *this );
|
||||
mProfileZoneManager = NULL;
|
||||
TZoneEventBufferType::removeClient( *this );
|
||||
}
|
||||
|
||||
void doAddName( const char* inName, uint16_t inEventId, bool inCompileTimeEnabled )
|
||||
{
|
||||
TLockType theLocker( mMutex );
|
||||
mEvtIdToNameMap.insert( inEventId, inName );
|
||||
uint32_t idx = static_cast<uint32_t>( mEventNames.size() );
|
||||
mNameToEvtIndexMapRW.insert( inName, idx );
|
||||
mEventNames.pushBack( PxProfileEventName( inName, PxProfileEventId( inEventId, inCompileTimeEnabled ) ) );
|
||||
}
|
||||
|
||||
virtual void flushEventIdNameMap()
|
||||
{
|
||||
// copy the RW map into R map
|
||||
if (mNameToEvtIndexMapRW.size())
|
||||
{
|
||||
for (TNameToEvtIndexMap::Iterator iter = mNameToEvtIndexMapRW.getIterator(); !iter.done(); ++iter)
|
||||
{
|
||||
mNameToEvtIndexMapR.insert(iter->first, iter->second);
|
||||
}
|
||||
mNameToEvtIndexMapRW.clear();
|
||||
}
|
||||
}
|
||||
|
||||
virtual uint16_t getEventIdForName( const char* inName )
|
||||
{
|
||||
return getEventIdsForNames( &inName, 1 );
|
||||
}
|
||||
|
||||
virtual uint16_t getEventIdsForNames( const char** inNames, uint32_t inLen )
|
||||
{
|
||||
if ( inLen == 0 )
|
||||
return 0;
|
||||
|
||||
// search the read-only map first
|
||||
const TNameToEvtIndexMap::Entry* theEntry( mNameToEvtIndexMapR.find( inNames[0] ) );
|
||||
if ( theEntry )
|
||||
return mEventNames[theEntry->second].eventId;
|
||||
|
||||
TLockType theLocker(mMutex);
|
||||
|
||||
const TNameToEvtIndexMap::Entry* theReEntry(mNameToEvtIndexMapRW.find(inNames[0]));
|
||||
if (theReEntry)
|
||||
return mEventNames[theReEntry->second].eventId;
|
||||
|
||||
//Else git R dun.
|
||||
uint16_t nameSize = static_cast<uint16_t>( mEventNames.size() );
|
||||
//We don't allow 0 as an event id.
|
||||
uint16_t eventId = nameSize;
|
||||
//Find a contiguous set of unique event ids
|
||||
bool foundAnEventId = false;
|
||||
do
|
||||
{
|
||||
foundAnEventId = false;
|
||||
++eventId;
|
||||
for ( uint16_t idx = 0; idx < inLen && foundAnEventId == false; ++idx )
|
||||
foundAnEventId = mEvtIdToNameMap.find( uint16_t(eventId + idx) ) != NULL;
|
||||
}
|
||||
while( foundAnEventId );
|
||||
|
||||
uint32_t clientCount = mZoneClients.size();
|
||||
for ( uint16_t nameIdx = 0; nameIdx < inLen; ++nameIdx )
|
||||
{
|
||||
uint16_t newId = uint16_t(eventId + nameIdx);
|
||||
doAddName( inNames[nameIdx], newId, true );
|
||||
for( uint32_t clientIdx =0; clientIdx < clientCount; ++clientIdx )
|
||||
mZoneClients[clientIdx]->handleEventAdded( PxProfileEventName( inNames[nameIdx], PxProfileEventId( newId ) ) );
|
||||
}
|
||||
|
||||
return eventId;
|
||||
}
|
||||
|
||||
virtual void setProfileZoneManager(PxProfileZoneManager* inMgr)
|
||||
{
|
||||
mProfileZoneManager = inMgr;
|
||||
}
|
||||
|
||||
virtual PxProfileZoneManager* getProfileZoneManager()
|
||||
{
|
||||
return mProfileZoneManager;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char* getName() { return mName; }
|
||||
|
||||
PxProfileEventBufferClient* getEventBufferClient() { return this; }
|
||||
|
||||
//SDK implementation
|
||||
|
||||
void addClient( PxProfileZoneClient& inClient )
|
||||
{
|
||||
TLockType lock( mMutex );
|
||||
mZoneClients.pushBack( &inClient );
|
||||
mEventsActive = true;
|
||||
}
|
||||
|
||||
void removeClient( PxProfileZoneClient& inClient )
|
||||
{
|
||||
TLockType lock( mMutex );
|
||||
for ( uint32_t idx =0; idx < mZoneClients.size(); ++idx )
|
||||
{
|
||||
if (mZoneClients[idx] == &inClient )
|
||||
{
|
||||
inClient.handleClientRemoved();
|
||||
mZoneClients.replaceWithLast( idx );
|
||||
break;
|
||||
}
|
||||
}
|
||||
mEventsActive = mZoneClients.size() != 0;
|
||||
}
|
||||
|
||||
virtual bool hasClients() const
|
||||
{
|
||||
return mEventsActive;
|
||||
}
|
||||
|
||||
virtual PxProfileNames getProfileNames() const
|
||||
{
|
||||
TLockType theLocker( mMutex );
|
||||
const PxProfileEventName* theNames = mEventNames.begin();
|
||||
uint32_t theEventCount = uint32_t(mEventNames.size());
|
||||
return PxProfileNames( theEventCount, theNames );
|
||||
}
|
||||
|
||||
virtual void release()
|
||||
{
|
||||
PX_PROFILE_DELETE( mWrapper.getAllocator(), this );
|
||||
}
|
||||
|
||||
//Implementation chaining the buffer flush to our clients
|
||||
virtual void handleBufferFlush( const uint8_t* inData, uint32_t inLength )
|
||||
{
|
||||
TLockType theLocker( mMutex );
|
||||
|
||||
uint32_t clientCount = mZoneClients.size();
|
||||
for( uint32_t idx =0; idx < clientCount; ++idx )
|
||||
mZoneClients[idx]->handleBufferFlush( inData, inLength );
|
||||
}
|
||||
//Happens if something removes all the clients from the manager.
|
||||
virtual void handleClientRemoved() {}
|
||||
|
||||
//Send a profile event, optionally with a context. Events are sorted by thread
|
||||
//and context in the client side.
|
||||
virtual void startEvent( uint16_t inId, uint64_t contextId)
|
||||
{
|
||||
if( mEventsActive )
|
||||
{
|
||||
TZoneEventBufferType::startEvent( inId, contextId );
|
||||
}
|
||||
}
|
||||
virtual void stopEvent( uint16_t inId, uint64_t contextId)
|
||||
{
|
||||
if( mEventsActive )
|
||||
{
|
||||
TZoneEventBufferType::stopEvent( inId, contextId );
|
||||
}
|
||||
}
|
||||
|
||||
virtual void startEvent( uint16_t inId, uint64_t contextId, uint32_t threadId)
|
||||
{
|
||||
if( mEventsActive )
|
||||
{
|
||||
TZoneEventBufferType::startEvent( inId, contextId, threadId );
|
||||
}
|
||||
}
|
||||
virtual void stopEvent( uint16_t inId, uint64_t contextId, uint32_t threadId )
|
||||
{
|
||||
if( mEventsActive )
|
||||
{
|
||||
TZoneEventBufferType::stopEvent( inId, contextId, threadId );
|
||||
}
|
||||
}
|
||||
|
||||
virtual void atEvent(uint16_t inId, uint64_t contextId, uint32_t threadId, uint64_t start, uint64_t stop)
|
||||
{
|
||||
if (mEventsActive)
|
||||
{
|
||||
TZoneEventBufferType::startEvent(inId, threadId, contextId, 0, 0, start);
|
||||
TZoneEventBufferType::stopEvent(inId, threadId, contextId, 0, 0, stop);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an specific events value. This is different than the profiling value
|
||||
* for the event; it is a value recorded and kept around without a timestamp associated
|
||||
* with it. This value is displayed when the event itself is processed.
|
||||
*/
|
||||
virtual void eventValue( uint16_t inId, uint64_t contextId, int64_t inValue )
|
||||
{
|
||||
if( mEventsActive )
|
||||
{
|
||||
TZoneEventBufferType::eventValue( inId, contextId, inValue );
|
||||
}
|
||||
}
|
||||
virtual void flushProfileEvents()
|
||||
{
|
||||
TZoneEventBufferType::flushProfileEvents();
|
||||
}
|
||||
};
|
||||
|
||||
}}
|
||||
#endif // PXPVDSDK_PXPROFILEZONEIMPL_H
|
||||
155
physx/source/pvd/src/PxProfileZoneManager.h
Normal file
155
physx/source/pvd/src/PxProfileZoneManager.h
Normal file
@ -0,0 +1,155 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef PXPVDSDK_PXPROFILEZONEMANAGER_H
|
||||
#define PXPVDSDK_PXPROFILEZONEMANAGER_H
|
||||
|
||||
#include "PxProfileEventSender.h"
|
||||
#include "PxProfileEventNames.h"
|
||||
|
||||
namespace physx {
|
||||
|
||||
class PxAllocatorCallback;
|
||||
|
||||
namespace profile {
|
||||
|
||||
class PxProfileZone;
|
||||
class PxProfileNameProvider;
|
||||
|
||||
/**
|
||||
\brief Profile zone handler for zone add/remove notification.
|
||||
*/
|
||||
class PxProfileZoneHandler
|
||||
{
|
||||
protected:
|
||||
virtual ~PxProfileZoneHandler(){}
|
||||
public:
|
||||
/**
|
||||
\brief On zone added notification
|
||||
|
||||
\note Not a threadsafe call; handlers are expected to be able to handle
|
||||
this from any thread.
|
||||
|
||||
\param inSDK Added zone.
|
||||
*/
|
||||
virtual void onZoneAdded( PxProfileZone& inSDK ) = 0;
|
||||
/**
|
||||
\brief On zone removed notification
|
||||
|
||||
\note Not a threadsafe call; handlers are expected to be able to handle
|
||||
this from any thread.
|
||||
|
||||
\param inSDK removed zone.
|
||||
*/
|
||||
virtual void onZoneRemoved( PxProfileZone& inSDK ) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
\brief The profiling system was setup in the expectation that there would be several
|
||||
systems that each had its own island of profile information. PhysX, client code,
|
||||
and APEX would be the first examples of these. Each one of these islands is represented
|
||||
by a profile zone.
|
||||
|
||||
The Manager is a singleton-like object where all these different systems can be registered
|
||||
so that clients of the profiling system can have one point to capture *all* profiling events.
|
||||
|
||||
Flushing the manager implies that you want to loop through all the profile zones and flush
|
||||
each one.
|
||||
|
||||
@see PxProfileEventFlusher
|
||||
*/
|
||||
class PxProfileZoneManager
|
||||
: public PxProfileEventFlusher //Tell all SDK's to flush their queue of profile events.
|
||||
{
|
||||
protected:
|
||||
virtual ~PxProfileZoneManager(){}
|
||||
public:
|
||||
/**
|
||||
\brief Add new profile zone for the manager.
|
||||
\note Threadsafe call, can be done from any thread. Handlers that are already connected
|
||||
will get a new callback on the current thread.
|
||||
|
||||
\param inSDK Profile zone to add.
|
||||
*/
|
||||
virtual void addProfileZone( PxProfileZone& inSDK ) = 0;
|
||||
/**
|
||||
\brief Removes profile zone from the manager.
|
||||
\note Threadsafe call, can be done from any thread. Handlers that are already connected
|
||||
will get a new callback on the current thread.
|
||||
|
||||
\param inSDK Profile zone to remove.
|
||||
*/
|
||||
virtual void removeProfileZone( PxProfileZone& inSDK ) = 0;
|
||||
|
||||
/**
|
||||
\brief Add profile zone handler callback for the profile zone notifications.
|
||||
|
||||
\note Threadsafe call. The new handler will immediately be notified about all
|
||||
known SDKs.
|
||||
|
||||
\param inHandler Profile zone handler to add.
|
||||
*/
|
||||
virtual void addProfileZoneHandler( PxProfileZoneHandler& inHandler ) = 0;
|
||||
/**
|
||||
\brief Removes profile zone handler callback for the profile zone notifications.
|
||||
|
||||
\note Threadsafe call. The new handler will immediately be notified about all
|
||||
known SDKs.
|
||||
|
||||
\param inHandler Profile zone handler to remove.
|
||||
*/
|
||||
virtual void removeProfileZoneHandler( PxProfileZoneHandler& inHandler ) = 0;
|
||||
|
||||
|
||||
/**
|
||||
\brief Create a new profile zone. This means you don't need access to a PxFoundation to
|
||||
create your profile zone object, and your object is automatically registered with
|
||||
the profile zone manager.
|
||||
|
||||
You still need to release your object when you are finished with it.
|
||||
\param inSDKName Name of the SDK object.
|
||||
\param inNames Option set of event id to name mappings.
|
||||
\param inEventBufferByteSize rough maximum size of the event buffer. May exceed this size
|
||||
by sizeof one event. When full an immediate call to all listeners is made.
|
||||
*/
|
||||
virtual PxProfileZone& createProfileZone( const char* inSDKName, PxProfileNames inNames = PxProfileNames(), uint32_t inEventBufferByteSize = 0x4000 /*16k*/ ) = 0;
|
||||
|
||||
/**
|
||||
\brief Releases the profile manager instance.
|
||||
*/
|
||||
virtual void release() = 0;
|
||||
|
||||
/**
|
||||
\brief Create the profile zone manager.
|
||||
\param inAllocatorCallback Allocator callback.
|
||||
*/
|
||||
static PxProfileZoneManager& createProfileZoneManager(PxAllocatorCallback* inAllocatorCallback );
|
||||
};
|
||||
|
||||
} }
|
||||
|
||||
#endif // PXPVDSDK_PXPROFILEZONEMANAGER_H
|
||||
173
physx/source/pvd/src/PxProfileZoneManagerImpl.h
Normal file
173
physx/source/pvd/src/PxProfileZoneManagerImpl.h
Normal file
@ -0,0 +1,173 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
|
||||
#ifndef PXPVDSDK_PXPROFILEZONEMANAGERIMPL_H
|
||||
#define PXPVDSDK_PXPROFILEZONEMANAGERIMPL_H
|
||||
|
||||
#include "PxProfileZoneManager.h"
|
||||
#include "PxProfileScopedMutexLock.h"
|
||||
#include "PxPvdProfileZone.h"
|
||||
#include "PxProfileAllocatorWrapper.h"
|
||||
|
||||
#include "PsArray.h"
|
||||
#include "PsMutex.h"
|
||||
|
||||
namespace physx { namespace profile {
|
||||
|
||||
struct NullEventNameProvider : public PxProfileNameProvider
|
||||
{
|
||||
virtual PxProfileNames getProfileNames() const { return PxProfileNames( 0, 0 ); }
|
||||
};
|
||||
|
||||
class ZoneManagerImpl : public PxProfileZoneManager
|
||||
{
|
||||
typedef ScopedLockImpl<shdfnd::Mutex> TScopedLockType;
|
||||
PxProfileAllocatorWrapper mWrapper;
|
||||
PxProfileArray<PxProfileZone*> mZones;
|
||||
PxProfileArray<PxProfileZoneHandler*> mHandlers;
|
||||
shdfnd::Mutex mMutex;
|
||||
|
||||
ZoneManagerImpl( const ZoneManagerImpl& inOther );
|
||||
ZoneManagerImpl& operator=( const ZoneManagerImpl& inOther );
|
||||
|
||||
public:
|
||||
|
||||
ZoneManagerImpl(PxAllocatorCallback* inFoundation)
|
||||
: mWrapper( inFoundation )
|
||||
, mZones( mWrapper )
|
||||
, mHandlers( mWrapper )
|
||||
{}
|
||||
|
||||
virtual ~ZoneManagerImpl()
|
||||
{
|
||||
//This assert would mean that a profile zone is outliving us.
|
||||
//This will cause a crash when the profile zone is released.
|
||||
PX_ASSERT( mZones.size() == 0 );
|
||||
while( mZones.size() )
|
||||
removeProfileZone( *mZones.back() );
|
||||
}
|
||||
|
||||
virtual void addProfileZone( PxProfileZone& inSDK )
|
||||
{
|
||||
TScopedLockType lock( &mMutex );
|
||||
|
||||
if ( inSDK.getProfileZoneManager() != NULL )
|
||||
{
|
||||
if ( inSDK.getProfileZoneManager() == this )
|
||||
return;
|
||||
else //there must be two managers in the system somehow.
|
||||
{
|
||||
PX_ASSERT( false );
|
||||
inSDK.getProfileZoneManager()->removeProfileZone( inSDK );
|
||||
}
|
||||
}
|
||||
mZones.pushBack( &inSDK );
|
||||
inSDK.setProfileZoneManager( this );
|
||||
for ( uint32_t idx =0; idx < mHandlers.size(); ++idx )
|
||||
mHandlers[idx]->onZoneAdded( inSDK );
|
||||
}
|
||||
|
||||
virtual void removeProfileZone( PxProfileZone& inSDK )
|
||||
{
|
||||
TScopedLockType lock( &mMutex );
|
||||
if ( inSDK.getProfileZoneManager() == NULL )
|
||||
return;
|
||||
|
||||
else if ( inSDK.getProfileZoneManager() != this )
|
||||
{
|
||||
PX_ASSERT( false );
|
||||
inSDK.getProfileZoneManager()->removeProfileZone( inSDK );
|
||||
return;
|
||||
}
|
||||
|
||||
inSDK.setProfileZoneManager( NULL );
|
||||
for ( uint32_t idx = 0; idx < mZones.size(); ++idx )
|
||||
{
|
||||
if ( mZones[idx] == &inSDK )
|
||||
{
|
||||
for ( uint32_t handler =0; handler < mHandlers.size(); ++handler )
|
||||
mHandlers[handler]->onZoneRemoved( inSDK );
|
||||
mZones.replaceWithLast( idx );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void flushProfileEvents()
|
||||
{
|
||||
uint32_t sdkCount = mZones.size();
|
||||
for ( uint32_t idx = 0; idx < sdkCount; ++idx )
|
||||
mZones[idx]->flushProfileEvents();
|
||||
}
|
||||
|
||||
virtual void addProfileZoneHandler( PxProfileZoneHandler& inHandler )
|
||||
{
|
||||
TScopedLockType lock( &mMutex );
|
||||
mHandlers.pushBack( &inHandler );
|
||||
for ( uint32_t idx = 0; idx < mZones.size(); ++idx )
|
||||
inHandler.onZoneAdded( *mZones[idx] );
|
||||
}
|
||||
|
||||
virtual void removeProfileZoneHandler( PxProfileZoneHandler& inHandler )
|
||||
{
|
||||
TScopedLockType lock( &mMutex );
|
||||
for( uint32_t idx = 0; idx < mZones.size(); ++idx )
|
||||
inHandler.onZoneRemoved( *mZones[idx] );
|
||||
for( uint32_t idx = 0; idx < mHandlers.size(); ++idx )
|
||||
{
|
||||
if ( mHandlers[idx] == &inHandler )
|
||||
mHandlers.replaceWithLast( idx );
|
||||
}
|
||||
}
|
||||
|
||||
virtual PxProfileZone& createProfileZone( const char* inSDKName, PxProfileNameProvider* inProvider, uint32_t inEventBufferByteSize )
|
||||
{
|
||||
NullEventNameProvider nullProvider;
|
||||
if ( inProvider == NULL )
|
||||
inProvider = &nullProvider;
|
||||
return createProfileZone( inSDKName, inProvider->getProfileNames(), inEventBufferByteSize );
|
||||
}
|
||||
|
||||
|
||||
virtual PxProfileZone& createProfileZone( const char* inSDKName, PxProfileNames inNames, uint32_t inEventBufferByteSize )
|
||||
{
|
||||
PxProfileZone& retval( PxProfileZone::createProfileZone( &mWrapper.getAllocator(), inSDKName, inNames, inEventBufferByteSize ) );
|
||||
addProfileZone( retval );
|
||||
return retval;
|
||||
}
|
||||
|
||||
virtual void release()
|
||||
{
|
||||
PX_PROFILE_DELETE( mWrapper.getAllocator(), this );
|
||||
}
|
||||
};
|
||||
} }
|
||||
|
||||
|
||||
#endif // PXPVDSDK_PXPROFILEZONEMANAGERIMPL_H
|
||||
46
physx/source/pvd/src/PxPvd.cpp
Normal file
46
physx/source/pvd/src/PxPvd.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#include "PxPvdImpl.h"
|
||||
namespace physx
|
||||
{
|
||||
namespace pvdsdk
|
||||
{
|
||||
ForwardingAllocator gForwardingAllocator;
|
||||
PxAllocatorCallback* gPvdAllocatorCallback = &gForwardingAllocator;
|
||||
} // namespace pvdsdk
|
||||
|
||||
PxPvd* PxCreatePvd(PxFoundation& foundation)
|
||||
{
|
||||
pvdsdk::gPvdAllocatorCallback = &foundation.getAllocatorCallback();
|
||||
pvdsdk::PvdImpl::initialize();
|
||||
return pvdsdk::PvdImpl::getInstance();
|
||||
}
|
||||
|
||||
} // namespace physx
|
||||
132
physx/source/pvd/src/PxPvdBits.h
Normal file
132
physx/source/pvd/src/PxPvdBits.h
Normal file
@ -0,0 +1,132 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef PXPVDSDK_PXPVDBITS_H
|
||||
#define PXPVDSDK_PXPVDBITS_H
|
||||
|
||||
#include "PxPvdObjectModelBaseTypes.h"
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace pvdsdk
|
||||
{
|
||||
|
||||
// Marshallers cannot assume src is aligned, but they can assume dest is aligned.
|
||||
typedef void (*TSingleMarshaller)(const uint8_t* src, uint8_t* dest);
|
||||
typedef void (*TBlockMarshaller)(const uint8_t* src, uint8_t* dest, uint32_t numItems);
|
||||
|
||||
template <uint8_t ByteCount>
|
||||
static inline void doSwapBytes(uint8_t* __restrict inData)
|
||||
{
|
||||
for(uint32_t idx = 0; idx < ByteCount / 2; ++idx)
|
||||
{
|
||||
uint32_t endIdx = ByteCount - idx - 1;
|
||||
uint8_t theTemp = inData[idx];
|
||||
inData[idx] = inData[endIdx];
|
||||
inData[endIdx] = theTemp;
|
||||
}
|
||||
}
|
||||
|
||||
template <uint8_t ByteCount>
|
||||
static inline void doSwapBytes(uint8_t* __restrict inData, uint32_t itemCount)
|
||||
{
|
||||
uint8_t* end = inData + itemCount * ByteCount;
|
||||
for(; inData < end; inData += ByteCount)
|
||||
doSwapBytes<ByteCount>(inData);
|
||||
}
|
||||
|
||||
static inline void swapBytes(uint8_t* __restrict dataPtr, uint32_t numBytes, uint32_t itemWidth)
|
||||
{
|
||||
uint32_t numItems = numBytes / itemWidth;
|
||||
switch(itemWidth)
|
||||
{
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
doSwapBytes<2>(dataPtr, numItems);
|
||||
break;
|
||||
case 4:
|
||||
doSwapBytes<4>(dataPtr, numItems);
|
||||
break;
|
||||
case 8:
|
||||
doSwapBytes<8>(dataPtr, numItems);
|
||||
break;
|
||||
case 16:
|
||||
doSwapBytes<16>(dataPtr, numItems);
|
||||
break;
|
||||
default:
|
||||
PX_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void swapBytes(uint8_t&)
|
||||
{
|
||||
}
|
||||
static inline void swapBytes(int8_t&)
|
||||
{
|
||||
}
|
||||
static inline void swapBytes(uint16_t& inData)
|
||||
{
|
||||
doSwapBytes<2>(reinterpret_cast<uint8_t*>(&inData));
|
||||
}
|
||||
static inline void swapBytes(int16_t& inData)
|
||||
{
|
||||
doSwapBytes<2>(reinterpret_cast<uint8_t*>(&inData));
|
||||
}
|
||||
static inline void swapBytes(uint32_t& inData)
|
||||
{
|
||||
doSwapBytes<4>(reinterpret_cast<uint8_t*>(&inData));
|
||||
}
|
||||
static inline void swapBytes(int32_t& inData)
|
||||
{
|
||||
doSwapBytes<4>(reinterpret_cast<uint8_t*>(&inData));
|
||||
}
|
||||
static inline void swapBytes(float& inData)
|
||||
{
|
||||
doSwapBytes<4>(reinterpret_cast<uint8_t*>(&inData));
|
||||
}
|
||||
static inline void swapBytes(uint64_t& inData)
|
||||
{
|
||||
doSwapBytes<8>(reinterpret_cast<uint8_t*>(&inData));
|
||||
}
|
||||
static inline void swapBytes(int64_t& inData)
|
||||
{
|
||||
doSwapBytes<8>(reinterpret_cast<uint8_t*>(&inData));
|
||||
}
|
||||
static inline void swapBytes(double& inData)
|
||||
{
|
||||
doSwapBytes<8>(reinterpret_cast<uint8_t*>(&inData));
|
||||
}
|
||||
|
||||
static inline bool checkLength(const uint8_t* inStart, const uint8_t* inStop, uint32_t inLength)
|
||||
{
|
||||
return static_cast<uint32_t>(inStop - inStart) >= inLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // PXPVDSDK_PXPVDBITS_H
|
||||
126
physx/source/pvd/src/PxPvdByteStreams.h
Normal file
126
physx/source/pvd/src/PxPvdByteStreams.h
Normal file
@ -0,0 +1,126 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef PXPVDSDK_PXPVDBYTESTREAMS_H
|
||||
#define PXPVDSDK_PXPVDBYTESTREAMS_H
|
||||
#include "PxPvdObjectModelBaseTypes.h"
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace pvdsdk
|
||||
{
|
||||
|
||||
static inline uint32_t strLen(const char* inStr)
|
||||
{
|
||||
uint32_t len = 0;
|
||||
if(inStr)
|
||||
{
|
||||
while(*inStr)
|
||||
{
|
||||
++len;
|
||||
++inStr;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
class PvdInputStream
|
||||
{
|
||||
protected:
|
||||
virtual ~PvdInputStream()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
// Return false if you can't write the number of bytes requested
|
||||
// But make an absolute best effort to read the data...
|
||||
virtual bool read(uint8_t* buffer, uint32_t& len) = 0;
|
||||
|
||||
template <typename TDataType>
|
||||
bool read(TDataType* buffer, uint32_t numItems)
|
||||
{
|
||||
uint32_t expected = numItems;
|
||||
uint32_t amountToRead = numItems * sizeof(TDataType);
|
||||
read(reinterpret_cast<uint8_t*>(buffer), amountToRead);
|
||||
numItems = amountToRead / sizeof(TDataType);
|
||||
PX_ASSERT(numItems == expected);
|
||||
return expected == numItems;
|
||||
}
|
||||
|
||||
template <typename TDataType>
|
||||
PvdInputStream& operator>>(TDataType& data)
|
||||
{
|
||||
uint32_t dataSize = static_cast<uint32_t>(sizeof(TDataType));
|
||||
bool success = read(reinterpret_cast<uint8_t*>(&data), dataSize);
|
||||
// PX_ASSERT( success );
|
||||
// PX_ASSERT( dataSize == sizeof( data ) );
|
||||
(void)success;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
class PvdOutputStream
|
||||
{
|
||||
protected:
|
||||
virtual ~PvdOutputStream()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
// Return false if you can't write the number of bytes requested
|
||||
// But make an absolute best effort to write the data...
|
||||
virtual bool write(const uint8_t* buffer, uint32_t len) = 0;
|
||||
virtual bool directCopy(PvdInputStream& inStream, uint32_t len) = 0;
|
||||
|
||||
template <typename TDataType>
|
||||
bool write(const TDataType* buffer, uint32_t numItems)
|
||||
{
|
||||
return write(reinterpret_cast<const uint8_t*>(buffer), numItems * sizeof(TDataType));
|
||||
}
|
||||
|
||||
template <typename TDataType>
|
||||
PvdOutputStream& operator<<(const TDataType& data)
|
||||
{
|
||||
bool success = write(reinterpret_cast<const uint8_t*>(&data), sizeof(data));
|
||||
PX_ASSERT(success);
|
||||
(void)success;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PvdOutputStream& operator<<(const char* inString)
|
||||
{
|
||||
if(inString && *inString)
|
||||
{
|
||||
uint32_t len(strLen(inString));
|
||||
write(inString, len);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif // PXPVDSDK_PXPVDBYTESTREAMS_H
|
||||
55
physx/source/pvd/src/PxPvdCommStreamEventSink.h
Normal file
55
physx/source/pvd/src/PxPvdCommStreamEventSink.h
Normal file
@ -0,0 +1,55 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef PXPVDSDK_PXPVDCOMMSTREAMEVENTSINK_H
|
||||
#define PXPVDSDK_PXPVDCOMMSTREAMEVENTSINK_H
|
||||
|
||||
#include "PxPvdObjectModelBaseTypes.h"
|
||||
#include "PxPvdCommStreamEvents.h"
|
||||
#include "PxPvdCommStreamTypes.h"
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace pvdsdk
|
||||
{
|
||||
|
||||
class PvdCommStreamEventSink
|
||||
{
|
||||
public:
|
||||
template <typename TStreamType>
|
||||
static void writeStreamEvent(const EventSerializeable& evt, PvdCommStreamEventTypes::Enum evtType, TStreamType& stream)
|
||||
{
|
||||
EventStreamifier<TStreamType> streamifier_concrete(stream);
|
||||
PvdEventSerializer& streamifier(streamifier_concrete);
|
||||
streamifier.streamify(evtType);
|
||||
const_cast<EventSerializeable&>(evt).serialize(streamifier);
|
||||
}
|
||||
};
|
||||
|
||||
} // pvd
|
||||
} // physx
|
||||
#endif // PXPVDSDK_PXPVDCOMMSTREAMEVENTSINK_H
|
||||
987
physx/source/pvd/src/PxPvdCommStreamEvents.h
Normal file
987
physx/source/pvd/src/PxPvdCommStreamEvents.h
Normal file
@ -0,0 +1,987 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef PXPVDSDK_PXPVDCOMMSTREAMEVENTS_H
|
||||
#define PXPVDSDK_PXPVDCOMMSTREAMEVENTS_H
|
||||
|
||||
#include "foundation/PxVec3.h"
|
||||
#include "foundation/PxFlags.h"
|
||||
|
||||
#include "PxPvdObjectModelBaseTypes.h"
|
||||
#include "PsTime.h"
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace pvdsdk
|
||||
{
|
||||
|
||||
struct CommStreamFlagTypes
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Is64BitPtr = 1
|
||||
};
|
||||
};
|
||||
|
||||
typedef PxFlags<CommStreamFlagTypes::Enum, uint32_t> CommStreamFlags;
|
||||
|
||||
template <typename TDataType>
|
||||
struct PvdCommVariableSizedEventCheck
|
||||
{
|
||||
bool variable_size_check;
|
||||
};
|
||||
|
||||
// Pick out the events that are possibly very large.
|
||||
// This helps us keep our buffers close to the size the user requested.
|
||||
#define DECLARE_TYPE_VARIABLE_SIZED(type) \
|
||||
template <> \
|
||||
struct PvdCommVariableSizedEventCheck<type> \
|
||||
{ \
|
||||
uint32_t variable_size_check; \
|
||||
};
|
||||
|
||||
struct NameHandleValue;
|
||||
struct StreamPropMessageArg;
|
||||
struct StringHandleEvent;
|
||||
struct CreateClass;
|
||||
struct DeriveClass;
|
||||
struct CreateProperty;
|
||||
struct CreatePropertyMessage;
|
||||
struct CreateInstance;
|
||||
struct SetPropertyValue;
|
||||
struct BeginSetPropertyValue;
|
||||
struct AppendPropertyValueData;
|
||||
struct EndSetPropertyValue;
|
||||
struct SetPropertyMessage;
|
||||
struct BeginPropertyMessageGroup;
|
||||
struct SendPropertyMessageFromGroup;
|
||||
struct EndPropertyMessageGroup;
|
||||
struct CreateDestroyInstanceProperty;
|
||||
struct PushBackObjectRef;
|
||||
struct RemoveObjectRef;
|
||||
struct BeginSection;
|
||||
struct EndSection;
|
||||
struct SetPickable;
|
||||
struct SetColor;
|
||||
struct SetIsTopLevel;
|
||||
struct SetCamera;
|
||||
struct AddProfileZone;
|
||||
struct AddProfileZoneEvent;
|
||||
struct StreamEndEvent;
|
||||
struct ErrorMessage;
|
||||
struct OriginShift;
|
||||
struct DestroyInstance;
|
||||
|
||||
#define DECLARE_COMM_STREAM_EVENTS \
|
||||
\
|
||||
DECLARE_PVD_COMM_STREAM_EVENT(StringHandleEvent) \
|
||||
DECLARE_PVD_COMM_STREAM_EVENT(CreateClass) \
|
||||
DECLARE_PVD_COMM_STREAM_EVENT(DeriveClass) \
|
||||
DECLARE_PVD_COMM_STREAM_EVENT(CreateProperty) \
|
||||
DECLARE_PVD_COMM_STREAM_EVENT(CreatePropertyMessage) \
|
||||
DECLARE_PVD_COMM_STREAM_EVENT(CreateInstance) \
|
||||
DECLARE_PVD_COMM_STREAM_EVENT(SetPropertyValue) \
|
||||
DECLARE_PVD_COMM_STREAM_EVENT(BeginSetPropertyValue) \
|
||||
DECLARE_PVD_COMM_STREAM_EVENT(AppendPropertyValueData) \
|
||||
DECLARE_PVD_COMM_STREAM_EVENT(EndSetPropertyValue) \
|
||||
DECLARE_PVD_COMM_STREAM_EVENT(SetPropertyMessage) \
|
||||
DECLARE_PVD_COMM_STREAM_EVENT(BeginPropertyMessageGroup) \
|
||||
DECLARE_PVD_COMM_STREAM_EVENT(SendPropertyMessageFromGroup) \
|
||||
DECLARE_PVD_COMM_STREAM_EVENT(EndPropertyMessageGroup) \
|
||||
DECLARE_PVD_COMM_STREAM_EVENT(DestroyInstance) \
|
||||
DECLARE_PVD_COMM_STREAM_EVENT(PushBackObjectRef) \
|
||||
DECLARE_PVD_COMM_STREAM_EVENT(RemoveObjectRef) \
|
||||
DECLARE_PVD_COMM_STREAM_EVENT(BeginSection) \
|
||||
DECLARE_PVD_COMM_STREAM_EVENT(EndSection) \
|
||||
DECLARE_PVD_COMM_STREAM_EVENT(SetPickable) \
|
||||
DECLARE_PVD_COMM_STREAM_EVENT(SetColor) \
|
||||
DECLARE_PVD_COMM_STREAM_EVENT(SetIsTopLevel) \
|
||||
DECLARE_PVD_COMM_STREAM_EVENT(SetCamera) \
|
||||
DECLARE_PVD_COMM_STREAM_EVENT(AddProfileZone) \
|
||||
DECLARE_PVD_COMM_STREAM_EVENT(AddProfileZoneEvent) \
|
||||
DECLARE_PVD_COMM_STREAM_EVENT(StreamEndEvent) \
|
||||
DECLARE_PVD_COMM_STREAM_EVENT(ErrorMessage) \
|
||||
DECLARE_PVD_COMM_STREAM_EVENT_NO_COMMA(OriginShift)
|
||||
|
||||
struct PvdCommStreamEventTypes
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Unknown = 0,
|
||||
#define DECLARE_PVD_COMM_STREAM_EVENT(x) x,
|
||||
#define DECLARE_PVD_COMM_STREAM_EVENT_NO_COMMA(x) x
|
||||
DECLARE_COMM_STREAM_EVENTS
|
||||
#undef DECLARE_PVD_COMM_STREAM_EVENT_NO_COMMA
|
||||
#undef DECLARE_PVD_COMM_STREAM_EVENT
|
||||
, Last
|
||||
};
|
||||
};
|
||||
|
||||
template <typename TDataType>
|
||||
struct DatatypeToCommEventType
|
||||
{
|
||||
bool compile_error;
|
||||
};
|
||||
template <PvdCommStreamEventTypes::Enum TEnumType>
|
||||
struct CommEventTypeToDatatype
|
||||
{
|
||||
bool compile_error;
|
||||
};
|
||||
|
||||
#define DECLARE_PVD_COMM_STREAM_EVENT(x) \
|
||||
template <> \
|
||||
struct DatatypeToCommEventType<x> \
|
||||
{ \
|
||||
enum Enum \
|
||||
{ \
|
||||
EEventTypeMap = PvdCommStreamEventTypes::x \
|
||||
}; \
|
||||
}; \
|
||||
template <> \
|
||||
struct CommEventTypeToDatatype<PvdCommStreamEventTypes::x> \
|
||||
{ \
|
||||
typedef x TEventType; \
|
||||
};
|
||||
#define DECLARE_PVD_COMM_STREAM_EVENT_NO_COMMA(x) \
|
||||
\
|
||||
template<> struct DatatypeToCommEventType<x> \
|
||||
{ \
|
||||
enum Enum \
|
||||
{ \
|
||||
EEventTypeMap = PvdCommStreamEventTypes::x \
|
||||
}; \
|
||||
}; \
|
||||
\
|
||||
template<> struct CommEventTypeToDatatype<PvdCommStreamEventTypes::x> \
|
||||
{ \
|
||||
typedef x TEventType; \
|
||||
};
|
||||
|
||||
DECLARE_COMM_STREAM_EVENTS
|
||||
#undef DECLARE_PVD_COMM_STREAM_EVENT_NO_COMMA
|
||||
#undef DECLARE_PVD_COMM_STREAM_EVENT
|
||||
|
||||
template <typename TDataType>
|
||||
PvdCommStreamEventTypes::Enum getCommStreamEventType()
|
||||
{
|
||||
return static_cast<PvdCommStreamEventTypes::Enum>(DatatypeToCommEventType<TDataType>::EEventTypeMap);
|
||||
}
|
||||
|
||||
struct StreamNamespacedName
|
||||
{
|
||||
StringHandle mNamespace; // StringHandle handles
|
||||
StringHandle mName;
|
||||
StreamNamespacedName(StringHandle ns = 0, StringHandle nm = 0) : mNamespace(ns), mName(nm)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class EventSerializeable;
|
||||
|
||||
class PvdEventSerializer
|
||||
{
|
||||
protected:
|
||||
virtual ~PvdEventSerializer()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
virtual void streamify(uint8_t& val) = 0;
|
||||
virtual void streamify(uint16_t& val) = 0;
|
||||
virtual void streamify(uint32_t& val) = 0;
|
||||
virtual void streamify(float& val) = 0;
|
||||
virtual void streamify(uint64_t& val) = 0;
|
||||
virtual void streamify(String& val) = 0;
|
||||
virtual void streamify(DataRef<const uint8_t>& data) = 0;
|
||||
virtual void streamify(DataRef<NameHandleValue>& data) = 0;
|
||||
virtual void streamify(DataRef<StreamPropMessageArg>& data) = 0;
|
||||
virtual void streamify(DataRef<StringHandle>& data) = 0;
|
||||
|
||||
void streamify(StringHandle& hdl)
|
||||
{
|
||||
streamify(hdl.mHandle);
|
||||
}
|
||||
void streamify(CommStreamFlags& flags)
|
||||
{
|
||||
uint32_t val(flags);
|
||||
streamify(val);
|
||||
flags = CommStreamFlags(val);
|
||||
}
|
||||
|
||||
void streamify(PvdCommStreamEventTypes::Enum& val)
|
||||
{
|
||||
uint8_t detyped = static_cast<uint8_t>(val);
|
||||
streamify(detyped);
|
||||
val = static_cast<PvdCommStreamEventTypes::Enum>(detyped);
|
||||
}
|
||||
void streamify(PropertyType::Enum& val)
|
||||
{
|
||||
uint8_t detyped = static_cast<uint8_t>(val);
|
||||
streamify(detyped);
|
||||
val = static_cast<PropertyType::Enum>(detyped);
|
||||
}
|
||||
|
||||
void streamify(bool& val)
|
||||
{
|
||||
uint8_t detyped = uint8_t(val ? 1 : 0);
|
||||
streamify(detyped);
|
||||
val = detyped ? true : false;
|
||||
}
|
||||
|
||||
void streamify(StreamNamespacedName& name)
|
||||
{
|
||||
streamify(name.mNamespace);
|
||||
streamify(name.mName);
|
||||
}
|
||||
|
||||
void streamify(PvdColor& color)
|
||||
{
|
||||
streamify(color.r);
|
||||
streamify(color.g);
|
||||
streamify(color.b);
|
||||
streamify(color.a);
|
||||
}
|
||||
|
||||
void streamify(PxVec3& vec)
|
||||
{
|
||||
streamify(vec.x);
|
||||
streamify(vec.y);
|
||||
streamify(vec.z);
|
||||
}
|
||||
|
||||
static uint32_t measure(const EventSerializeable& evt);
|
||||
};
|
||||
|
||||
class EventSerializeable
|
||||
{
|
||||
protected:
|
||||
virtual ~EventSerializeable()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
virtual void serialize(PvdEventSerializer& serializer) = 0;
|
||||
};
|
||||
|
||||
/** Numbers generated from random.org
|
||||
129919156 17973702 401496246 144984007 336950759
|
||||
907025328 837150850 679717896 601529147 269478202
|
||||
*/
|
||||
struct StreamInitialization : public EventSerializeable
|
||||
{
|
||||
static uint32_t getStreamId()
|
||||
{
|
||||
return 837150850;
|
||||
}
|
||||
static uint32_t getStreamVersion()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t mStreamId;
|
||||
uint32_t mStreamVersion;
|
||||
uint64_t mTimestampNumerator;
|
||||
uint64_t mTimestampDenominator;
|
||||
CommStreamFlags mStreamFlags;
|
||||
StreamInitialization()
|
||||
: mStreamId(getStreamId())
|
||||
, mStreamVersion(getStreamVersion())
|
||||
, mTimestampNumerator(physx::shdfnd::Time::getCounterFrequency().mNumerator * 10)
|
||||
, mTimestampDenominator(physx::shdfnd::Time::getCounterFrequency().mDenominator)
|
||||
, mStreamFlags(sizeof(void*) == 4 ? 0 : 1)
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer& s)
|
||||
{
|
||||
s.streamify(mStreamId);
|
||||
s.streamify(mStreamVersion);
|
||||
s.streamify(mTimestampNumerator);
|
||||
s.streamify(mTimestampDenominator);
|
||||
s.streamify(mStreamFlags);
|
||||
}
|
||||
};
|
||||
|
||||
struct EventGroup : public EventSerializeable
|
||||
{
|
||||
uint32_t mDataSize; // in bytes, data directly follows this header
|
||||
uint32_t mNumEvents;
|
||||
uint64_t mStreamId;
|
||||
uint64_t mTimestamp;
|
||||
|
||||
EventGroup(uint32_t dataSize = 0, uint32_t numEvents = 0, uint64_t streamId = 0, uint64_t ts = 0)
|
||||
: mDataSize(dataSize), mNumEvents(numEvents), mStreamId(streamId), mTimestamp(ts)
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer& s)
|
||||
{
|
||||
s.streamify(mDataSize);
|
||||
s.streamify(mNumEvents);
|
||||
s.streamify(mStreamId);
|
||||
s.streamify(mTimestamp);
|
||||
}
|
||||
};
|
||||
|
||||
struct StringHandleEvent : public EventSerializeable
|
||||
{
|
||||
String mString;
|
||||
uint32_t mHandle;
|
||||
StringHandleEvent(String str, uint32_t hdl) : mString(str), mHandle(hdl)
|
||||
{
|
||||
}
|
||||
StringHandleEvent()
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer& s)
|
||||
{
|
||||
s.streamify(mString);
|
||||
s.streamify(mHandle);
|
||||
}
|
||||
};
|
||||
|
||||
DECLARE_TYPE_VARIABLE_SIZED(StringHandleEvent)
|
||||
|
||||
typedef uint64_t Timestamp;
|
||||
|
||||
struct CreateClass : public EventSerializeable
|
||||
{
|
||||
StreamNamespacedName mName;
|
||||
CreateClass(StreamNamespacedName nm) : mName(nm)
|
||||
{
|
||||
}
|
||||
CreateClass()
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer& s)
|
||||
{
|
||||
s.streamify(mName);
|
||||
}
|
||||
};
|
||||
|
||||
struct DeriveClass : public EventSerializeable
|
||||
{
|
||||
StreamNamespacedName mParent;
|
||||
StreamNamespacedName mChild;
|
||||
|
||||
DeriveClass(StreamNamespacedName p, StreamNamespacedName c) : mParent(p), mChild(c)
|
||||
{
|
||||
}
|
||||
DeriveClass()
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer& s)
|
||||
{
|
||||
s.streamify(mParent);
|
||||
s.streamify(mChild);
|
||||
}
|
||||
};
|
||||
|
||||
struct NameHandleValue : public EventSerializeable
|
||||
{
|
||||
StringHandle mName;
|
||||
uint32_t mValue;
|
||||
NameHandleValue(StringHandle name, uint32_t val) : mName(name), mValue(val)
|
||||
{
|
||||
}
|
||||
NameHandleValue()
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer& s)
|
||||
{
|
||||
s.streamify(mName);
|
||||
s.streamify(mValue);
|
||||
}
|
||||
};
|
||||
/*virtual PvdError createProperty( StreamNamespacedName clsName, StringHandle name, StringHandle semantic
|
||||
, StreamNamespacedName dtypeName, PropertyType::Enum propertyType
|
||||
, DataRef<NamedValue> values = DataRef<NamedValue>() ) = 0; */
|
||||
struct CreateProperty : public EventSerializeable
|
||||
{
|
||||
StreamNamespacedName mClass;
|
||||
StringHandle mName;
|
||||
StringHandle mSemantic;
|
||||
StreamNamespacedName mDatatypeName;
|
||||
PropertyType::Enum mPropertyType;
|
||||
DataRef<NameHandleValue> mValues;
|
||||
|
||||
CreateProperty(StreamNamespacedName cls, StringHandle name, StringHandle semantic, StreamNamespacedName dtypeName,
|
||||
PropertyType::Enum ptype, DataRef<NameHandleValue> values)
|
||||
: mClass(cls), mName(name), mSemantic(semantic), mDatatypeName(dtypeName), mPropertyType(ptype), mValues(values)
|
||||
{
|
||||
}
|
||||
CreateProperty()
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer& s)
|
||||
{
|
||||
s.streamify(mClass);
|
||||
s.streamify(mName);
|
||||
s.streamify(mSemantic);
|
||||
s.streamify(mDatatypeName);
|
||||
s.streamify(mPropertyType);
|
||||
s.streamify(mValues);
|
||||
}
|
||||
};
|
||||
|
||||
struct StreamPropMessageArg : public EventSerializeable
|
||||
{
|
||||
StringHandle mPropertyName;
|
||||
StreamNamespacedName mDatatypeName;
|
||||
uint32_t mMessageOffset;
|
||||
uint32_t mByteSize;
|
||||
StreamPropMessageArg(StringHandle pname, StreamNamespacedName dtypeName, uint32_t offset, uint32_t byteSize)
|
||||
: mPropertyName(pname), mDatatypeName(dtypeName), mMessageOffset(offset), mByteSize(byteSize)
|
||||
{
|
||||
}
|
||||
|
||||
StreamPropMessageArg()
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer& s)
|
||||
{
|
||||
s.streamify(mPropertyName);
|
||||
s.streamify(mDatatypeName);
|
||||
s.streamify(mMessageOffset);
|
||||
s.streamify(mByteSize);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
virtual PvdError createPropertyMessage( StreamNamespacedName cls, StreamNamespacedName msgName
|
||||
, DataRef<PropertyMessageArg> entries, uint32_t messageSizeInBytes ) =
|
||||
0;*/
|
||||
struct CreatePropertyMessage : public EventSerializeable
|
||||
{
|
||||
StreamNamespacedName mClass;
|
||||
StreamNamespacedName mMessageName;
|
||||
DataRef<StreamPropMessageArg> mMessageEntries;
|
||||
uint32_t mMessageByteSize;
|
||||
|
||||
CreatePropertyMessage(StreamNamespacedName cls, StreamNamespacedName msgName, DataRef<StreamPropMessageArg> propArg,
|
||||
uint32_t messageByteSize)
|
||||
: mClass(cls), mMessageName(msgName), mMessageEntries(propArg), mMessageByteSize(messageByteSize)
|
||||
{
|
||||
}
|
||||
CreatePropertyMessage()
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer& s)
|
||||
{
|
||||
s.streamify(mClass);
|
||||
s.streamify(mMessageName);
|
||||
s.streamify(mMessageEntries);
|
||||
s.streamify(mMessageByteSize);
|
||||
}
|
||||
};
|
||||
|
||||
/**Changing immediate data on instances*/
|
||||
|
||||
// virtual PvdError createInstance( StreamNamespacedName cls, uint64_t instance ) = 0;
|
||||
struct CreateInstance : public EventSerializeable
|
||||
{
|
||||
StreamNamespacedName mClass;
|
||||
uint64_t mInstanceId;
|
||||
|
||||
CreateInstance(StreamNamespacedName cls, uint64_t streamId) : mClass(cls), mInstanceId(streamId)
|
||||
{
|
||||
}
|
||||
CreateInstance()
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer& s)
|
||||
{
|
||||
s.streamify(mClass);
|
||||
s.streamify(mInstanceId);
|
||||
}
|
||||
};
|
||||
|
||||
// virtual PvdError setPropertyValue( uint64_t instance, StringHandle name, DataRef<const uint8_t> data,
|
||||
// StreamNamespacedName incomingTypeName ) = 0;
|
||||
struct SetPropertyValue : public EventSerializeable
|
||||
{
|
||||
uint64_t mInstanceId;
|
||||
StringHandle mPropertyName;
|
||||
DataRef<const uint8_t> mData;
|
||||
StreamNamespacedName mIncomingTypeName;
|
||||
uint32_t mNumItems;
|
||||
|
||||
SetPropertyValue(uint64_t instance, StringHandle name, DataRef<const uint8_t> data,
|
||||
StreamNamespacedName incomingTypeName, uint32_t numItems)
|
||||
: mInstanceId(instance), mPropertyName(name), mData(data), mIncomingTypeName(incomingTypeName), mNumItems(numItems)
|
||||
{
|
||||
}
|
||||
|
||||
SetPropertyValue()
|
||||
{
|
||||
}
|
||||
|
||||
void serializeBeginning(PvdEventSerializer& s)
|
||||
{
|
||||
s.streamify(mInstanceId);
|
||||
s.streamify(mPropertyName);
|
||||
s.streamify(mIncomingTypeName);
|
||||
s.streamify(mNumItems);
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer& s)
|
||||
{
|
||||
serializeBeginning(s);
|
||||
s.streamify(mData);
|
||||
}
|
||||
};
|
||||
|
||||
DECLARE_TYPE_VARIABLE_SIZED(SetPropertyValue)
|
||||
|
||||
struct BeginSetPropertyValue : public EventSerializeable
|
||||
{
|
||||
uint64_t mInstanceId;
|
||||
StringHandle mPropertyName;
|
||||
StreamNamespacedName mIncomingTypeName;
|
||||
|
||||
BeginSetPropertyValue(uint64_t instance, StringHandle name, StreamNamespacedName incomingTypeName)
|
||||
: mInstanceId(instance), mPropertyName(name), mIncomingTypeName(incomingTypeName)
|
||||
{
|
||||
}
|
||||
BeginSetPropertyValue()
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer& s)
|
||||
{
|
||||
s.streamify(mInstanceId);
|
||||
s.streamify(mPropertyName);
|
||||
s.streamify(mIncomingTypeName);
|
||||
}
|
||||
};
|
||||
|
||||
// virtual PvdError appendPropertyValueData( DataRef<const uint8_t> data ) = 0;
|
||||
struct AppendPropertyValueData : public EventSerializeable
|
||||
{
|
||||
DataRef<const uint8_t> mData;
|
||||
uint32_t mNumItems;
|
||||
AppendPropertyValueData(DataRef<const uint8_t> data, uint32_t numItems) : mData(data), mNumItems(numItems)
|
||||
{
|
||||
}
|
||||
AppendPropertyValueData()
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer& s)
|
||||
{
|
||||
s.streamify(mData);
|
||||
s.streamify(mNumItems);
|
||||
}
|
||||
};
|
||||
|
||||
DECLARE_TYPE_VARIABLE_SIZED(AppendPropertyValueData)
|
||||
|
||||
// virtual PvdError endSetPropertyValue() = 0;
|
||||
struct EndSetPropertyValue : public EventSerializeable
|
||||
{
|
||||
EndSetPropertyValue()
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer&)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// virtual PvdError setPropertyMessage( uint64_t instance, StreamNamespacedName msgName, DataRef<const uint8_t> data ) =
|
||||
// 0;
|
||||
struct SetPropertyMessage : public EventSerializeable
|
||||
{
|
||||
uint64_t mInstanceId;
|
||||
StreamNamespacedName mMessageName;
|
||||
DataRef<const uint8_t> mData;
|
||||
|
||||
SetPropertyMessage(uint64_t instance, StreamNamespacedName msgName, DataRef<const uint8_t> data)
|
||||
: mInstanceId(instance), mMessageName(msgName), mData(data)
|
||||
{
|
||||
}
|
||||
|
||||
SetPropertyMessage()
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer& s)
|
||||
{
|
||||
s.streamify(mInstanceId);
|
||||
s.streamify(mMessageName);
|
||||
s.streamify(mData);
|
||||
}
|
||||
};
|
||||
|
||||
DECLARE_TYPE_VARIABLE_SIZED(SetPropertyMessage)
|
||||
|
||||
// virtual PvdError beginPropertyMessageGroup( StreamNamespacedName msgName ) = 0;
|
||||
struct BeginPropertyMessageGroup : public EventSerializeable
|
||||
{
|
||||
StreamNamespacedName mMsgName;
|
||||
BeginPropertyMessageGroup(StreamNamespacedName msgName) : mMsgName(msgName)
|
||||
{
|
||||
}
|
||||
BeginPropertyMessageGroup()
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer& s)
|
||||
{
|
||||
s.streamify(mMsgName);
|
||||
}
|
||||
};
|
||||
|
||||
// virtual PvdError sendPropertyMessageFromGroup( uint64_t instance, DataRef<const uint8_t*> data ) = 0;
|
||||
struct SendPropertyMessageFromGroup : public EventSerializeable
|
||||
{
|
||||
uint64_t mInstance;
|
||||
DataRef<const uint8_t> mData;
|
||||
|
||||
SendPropertyMessageFromGroup(uint64_t instance, DataRef<const uint8_t> data) : mInstance(instance), mData(data)
|
||||
{
|
||||
}
|
||||
SendPropertyMessageFromGroup()
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer& s)
|
||||
{
|
||||
s.streamify(mInstance);
|
||||
s.streamify(mData);
|
||||
}
|
||||
};
|
||||
|
||||
DECLARE_TYPE_VARIABLE_SIZED(SendPropertyMessageFromGroup)
|
||||
|
||||
// virtual PvdError endPropertyMessageGroup() = 0;
|
||||
struct EndPropertyMessageGroup : public EventSerializeable
|
||||
{
|
||||
EndPropertyMessageGroup()
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer&)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct PushBackObjectRef : public EventSerializeable
|
||||
{
|
||||
uint64_t mInstanceId;
|
||||
StringHandle mProperty;
|
||||
uint64_t mObjectRef;
|
||||
|
||||
PushBackObjectRef(uint64_t instId, StringHandle prop, uint64_t objRef)
|
||||
: mInstanceId(instId), mProperty(prop), mObjectRef(objRef)
|
||||
{
|
||||
}
|
||||
|
||||
PushBackObjectRef()
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer& s)
|
||||
{
|
||||
s.streamify(mInstanceId);
|
||||
s.streamify(mProperty);
|
||||
s.streamify(mObjectRef);
|
||||
}
|
||||
};
|
||||
|
||||
struct RemoveObjectRef : public EventSerializeable
|
||||
{
|
||||
uint64_t mInstanceId;
|
||||
StringHandle mProperty;
|
||||
uint64_t mObjectRef;
|
||||
|
||||
RemoveObjectRef(uint64_t instId, StringHandle prop, uint64_t objRef)
|
||||
: mInstanceId(instId), mProperty(prop), mObjectRef(objRef)
|
||||
{
|
||||
}
|
||||
|
||||
RemoveObjectRef()
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer& s)
|
||||
{
|
||||
s.streamify(mInstanceId);
|
||||
s.streamify(mProperty);
|
||||
s.streamify(mObjectRef);
|
||||
}
|
||||
};
|
||||
|
||||
// virtual PvdError destroyInstance( uint64_t key ) = 0;
|
||||
struct DestroyInstance : public EventSerializeable
|
||||
{
|
||||
uint64_t mInstanceId;
|
||||
DestroyInstance(uint64_t instance) : mInstanceId(instance)
|
||||
{
|
||||
}
|
||||
DestroyInstance()
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer& s)
|
||||
{
|
||||
s.streamify(mInstanceId);
|
||||
}
|
||||
};
|
||||
|
||||
// virtual PvdError beginSection( uint64_t sectionId, StringHandle name ) = 0;
|
||||
struct BeginSection : public EventSerializeable
|
||||
{
|
||||
uint64_t mSectionId;
|
||||
StringHandle mName;
|
||||
Timestamp mTimestamp;
|
||||
BeginSection(uint64_t sectionId, StringHandle name, uint64_t timestamp)
|
||||
: mSectionId(sectionId), mName(name), mTimestamp(timestamp)
|
||||
{
|
||||
}
|
||||
BeginSection()
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer& s)
|
||||
{
|
||||
s.streamify(mSectionId);
|
||||
s.streamify(mName);
|
||||
s.streamify(mTimestamp);
|
||||
}
|
||||
};
|
||||
// virtual PvdError endSection( uint64_t sectionId, StringHandle name ) = 0;
|
||||
struct EndSection : public EventSerializeable
|
||||
{
|
||||
uint64_t mSectionId;
|
||||
StringHandle mName;
|
||||
Timestamp mTimestamp;
|
||||
EndSection(uint64_t sectionId, StringHandle name, uint64_t timestamp)
|
||||
: mSectionId(sectionId), mName(name), mTimestamp(timestamp)
|
||||
{
|
||||
}
|
||||
EndSection()
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer& s)
|
||||
{
|
||||
s.streamify(mSectionId);
|
||||
s.streamify(mName);
|
||||
s.streamify(mTimestamp);
|
||||
}
|
||||
};
|
||||
|
||||
// virtual void setPickable( void* instance, bool pickable ) = 0;
|
||||
struct SetPickable : public EventSerializeable
|
||||
{
|
||||
uint64_t mInstanceId;
|
||||
bool mPickable;
|
||||
SetPickable(uint64_t instId, bool pick) : mInstanceId(instId), mPickable(pick)
|
||||
{
|
||||
}
|
||||
SetPickable()
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer& s)
|
||||
{
|
||||
s.streamify(mInstanceId);
|
||||
s.streamify(mPickable);
|
||||
}
|
||||
};
|
||||
// virtual void setColor( void* instance, const PvdColor& color ) = 0;
|
||||
struct SetColor : public EventSerializeable
|
||||
{
|
||||
uint64_t mInstanceId;
|
||||
PvdColor mColor;
|
||||
SetColor(uint64_t instId, PvdColor color) : mInstanceId(instId), mColor(color)
|
||||
{
|
||||
}
|
||||
SetColor()
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer& s)
|
||||
{
|
||||
s.streamify(mInstanceId);
|
||||
s.streamify(mColor);
|
||||
}
|
||||
};
|
||||
|
||||
// virtual void setColor( void* instance, const PvdColor& color ) = 0;
|
||||
struct SetIsTopLevel : public EventSerializeable
|
||||
{
|
||||
uint64_t mInstanceId;
|
||||
bool mIsTopLevel;
|
||||
|
||||
SetIsTopLevel(uint64_t instId, bool topLevel) : mInstanceId(instId), mIsTopLevel(topLevel)
|
||||
{
|
||||
}
|
||||
SetIsTopLevel() : mIsTopLevel(false)
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer& s)
|
||||
{
|
||||
s.streamify(mInstanceId);
|
||||
s.streamify(mIsTopLevel);
|
||||
}
|
||||
};
|
||||
|
||||
struct SetCamera : public EventSerializeable
|
||||
{
|
||||
String mName;
|
||||
PxVec3 mPosition;
|
||||
PxVec3 mUp;
|
||||
PxVec3 mTarget;
|
||||
SetCamera(String name, const PxVec3& pos, const PxVec3& up, const PxVec3& target)
|
||||
: mName(name), mPosition(pos), mUp(up), mTarget(target)
|
||||
{
|
||||
}
|
||||
SetCamera() : mName(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer& s)
|
||||
{
|
||||
s.streamify(mName);
|
||||
s.streamify(mPosition);
|
||||
s.streamify(mUp);
|
||||
s.streamify(mTarget);
|
||||
}
|
||||
};
|
||||
|
||||
struct ErrorMessage : public EventSerializeable
|
||||
{
|
||||
uint32_t mCode;
|
||||
String mMessage;
|
||||
String mFile;
|
||||
uint32_t mLine;
|
||||
|
||||
ErrorMessage(uint32_t code, String message, String file, uint32_t line)
|
||||
: mCode(code), mMessage(message), mFile(file), mLine(line)
|
||||
{
|
||||
}
|
||||
|
||||
ErrorMessage() : mMessage(NULL), mFile(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer& s)
|
||||
{
|
||||
s.streamify(mCode);
|
||||
s.streamify(mMessage);
|
||||
s.streamify(mFile);
|
||||
s.streamify(mLine);
|
||||
}
|
||||
};
|
||||
|
||||
struct AddProfileZone : public EventSerializeable
|
||||
{
|
||||
uint64_t mInstanceId;
|
||||
String mName;
|
||||
AddProfileZone(uint64_t iid, String nm) : mInstanceId(iid), mName(nm)
|
||||
{
|
||||
}
|
||||
AddProfileZone() : mName(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer& s)
|
||||
{
|
||||
s.streamify(mInstanceId);
|
||||
s.streamify(mName);
|
||||
}
|
||||
};
|
||||
|
||||
struct AddProfileZoneEvent : public EventSerializeable
|
||||
{
|
||||
uint64_t mInstanceId;
|
||||
String mName;
|
||||
uint16_t mEventId;
|
||||
bool mCompileTimeEnabled;
|
||||
AddProfileZoneEvent(uint64_t iid, String nm, uint16_t eid, bool cte)
|
||||
: mInstanceId(iid), mName(nm), mEventId(eid), mCompileTimeEnabled(cte)
|
||||
{
|
||||
}
|
||||
AddProfileZoneEvent()
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer& s)
|
||||
{
|
||||
s.streamify(mInstanceId);
|
||||
s.streamify(mName);
|
||||
s.streamify(mEventId);
|
||||
s.streamify(mCompileTimeEnabled);
|
||||
}
|
||||
};
|
||||
|
||||
struct StreamEndEvent : public EventSerializeable
|
||||
{
|
||||
String mName;
|
||||
StreamEndEvent() : mName("StreamEnd")
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer& s)
|
||||
{
|
||||
s.streamify(mName);
|
||||
}
|
||||
};
|
||||
|
||||
struct OriginShift : public EventSerializeable
|
||||
{
|
||||
uint64_t mInstanceId;
|
||||
PxVec3 mShift;
|
||||
|
||||
OriginShift(uint64_t iid, const PxVec3& shift) : mInstanceId(iid), mShift(shift)
|
||||
{
|
||||
}
|
||||
OriginShift()
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(PvdEventSerializer& s)
|
||||
{
|
||||
s.streamify(mInstanceId);
|
||||
s.streamify(mShift);
|
||||
}
|
||||
};
|
||||
} // pvdsdk
|
||||
} // physx
|
||||
|
||||
#endif // PXPVDSDK_PXPVDCOMMSTREAMEVENTS_H
|
||||
229
physx/source/pvd/src/PxPvdCommStreamTypes.h
Normal file
229
physx/source/pvd/src/PxPvdCommStreamTypes.h
Normal file
@ -0,0 +1,229 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef PXPVDSDK_PXPVDCOMMSTREAMTYPES_H
|
||||
#define PXPVDSDK_PXPVDCOMMSTREAMTYPES_H
|
||||
|
||||
#include "foundation/PxErrorCallback.h"
|
||||
#include "pvd/PxPvdTransport.h"
|
||||
|
||||
#include "PxPvdRenderBuffer.h"
|
||||
#include "PxPvdObjectModelBaseTypes.h"
|
||||
#include "PxPvdCommStreamEvents.h"
|
||||
#include "PxPvdDataStream.h"
|
||||
#include "PsMutex.h"
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace profile
|
||||
{
|
||||
class PxProfileZone;
|
||||
class PxProfileMemoryEventBuffer;
|
||||
}
|
||||
namespace pvdsdk
|
||||
{
|
||||
struct PvdErrorMessage;
|
||||
class PvdObjectModelMetaData;
|
||||
|
||||
DEFINE_PVD_TYPE_NAME_MAP(profile::PxProfileZone, "_debugger_", "PxProfileZone")
|
||||
DEFINE_PVD_TYPE_NAME_MAP(profile::PxProfileMemoryEventBuffer, "_debugger_", "PxProfileMemoryEventBuffer")
|
||||
DEFINE_PVD_TYPE_NAME_MAP(PvdErrorMessage, "_debugger_", "PvdErrorMessage")
|
||||
// All event streams are on the 'events' property of objects of these types
|
||||
static inline NamespacedName getMemoryEventTotalsClassName()
|
||||
{
|
||||
return NamespacedName("_debugger", "MemoryEventTotals");
|
||||
}
|
||||
|
||||
class PvdOMMetaDataProvider
|
||||
{
|
||||
protected:
|
||||
virtual ~PvdOMMetaDataProvider()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
virtual void addRef() = 0;
|
||||
virtual void release() = 0;
|
||||
virtual PvdObjectModelMetaData& lock() = 0;
|
||||
virtual void unlock() = 0;
|
||||
virtual bool createInstance(const NamespacedName& clsName, const void* instance) = 0;
|
||||
virtual bool isInstanceValid(const void* instance) = 0;
|
||||
virtual void destroyInstance(const void* instance) = 0;
|
||||
virtual int32_t getInstanceClassType(const void* instance) = 0;
|
||||
};
|
||||
|
||||
class PvdCommStreamEmbeddedTypes
|
||||
{
|
||||
public:
|
||||
static const char* getProfileEventStreamSemantic()
|
||||
{
|
||||
return "profile event stream";
|
||||
}
|
||||
static const char* getMemoryEventStreamSemantic()
|
||||
{
|
||||
return "memory event stream";
|
||||
}
|
||||
static const char* getRendererEventStreamSemantic()
|
||||
{
|
||||
return "render event stream";
|
||||
}
|
||||
};
|
||||
|
||||
class PvdCommStreamEventBufferClient;
|
||||
|
||||
template <typename TStreamType>
|
||||
struct EventStreamifier : public PvdEventSerializer
|
||||
{
|
||||
TStreamType& mBuffer;
|
||||
EventStreamifier(TStreamType& buf) : mBuffer(buf)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename TDataType>
|
||||
void write(const TDataType& type)
|
||||
{
|
||||
mBuffer.write(reinterpret_cast<const uint8_t*>(&type), sizeof(TDataType));
|
||||
}
|
||||
template <typename TDataType>
|
||||
void write(const TDataType* type, uint32_t count)
|
||||
{
|
||||
mBuffer.write(reinterpret_cast<const uint8_t*>(type), count * sizeof(TDataType));
|
||||
}
|
||||
|
||||
void writeRef(DataRef<const uint8_t> data)
|
||||
{
|
||||
uint32_t amount = static_cast<uint32_t>(data.size());
|
||||
write(amount);
|
||||
write(data.begin(), amount);
|
||||
}
|
||||
void writeRef(DataRef<StringHandle> data)
|
||||
{
|
||||
uint32_t amount = static_cast<uint32_t>(data.size());
|
||||
write(amount);
|
||||
write(data.begin(), amount);
|
||||
}
|
||||
template <typename TDataType>
|
||||
void writeRef(DataRef<TDataType> data)
|
||||
{
|
||||
uint32_t amount = static_cast<uint32_t>(data.size());
|
||||
write(amount);
|
||||
for(uint32_t idx = 0; idx < amount; ++idx)
|
||||
{
|
||||
TDataType& dtype(const_cast<TDataType&>(data[idx]));
|
||||
dtype.serialize(*this);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void streamify(uint16_t& val)
|
||||
{
|
||||
write(val);
|
||||
}
|
||||
virtual void streamify(uint8_t& val)
|
||||
{
|
||||
write(val);
|
||||
}
|
||||
virtual void streamify(uint32_t& val)
|
||||
{
|
||||
write(val);
|
||||
}
|
||||
virtual void streamify(float& val)
|
||||
{
|
||||
write(val);
|
||||
}
|
||||
virtual void streamify(uint64_t& val)
|
||||
{
|
||||
write(val);
|
||||
}
|
||||
virtual void streamify(PvdDebugText& val)
|
||||
{
|
||||
write(val.color);
|
||||
write(val.position);
|
||||
write(val.size);
|
||||
streamify(val.string);
|
||||
}
|
||||
|
||||
virtual void streamify(String& val)
|
||||
{
|
||||
uint32_t len = 0;
|
||||
String temp = nonNull(val);
|
||||
if(*temp)
|
||||
len = static_cast<uint32_t>(strlen(temp) + 1);
|
||||
write(len);
|
||||
write(val, len);
|
||||
}
|
||||
virtual void streamify(DataRef<const uint8_t>& val)
|
||||
{
|
||||
writeRef(val);
|
||||
}
|
||||
virtual void streamify(DataRef<NameHandleValue>& val)
|
||||
{
|
||||
writeRef(val);
|
||||
}
|
||||
virtual void streamify(DataRef<StreamPropMessageArg>& val)
|
||||
{
|
||||
writeRef(val);
|
||||
}
|
||||
virtual void streamify(DataRef<StringHandle>& val)
|
||||
{
|
||||
writeRef(val);
|
||||
}
|
||||
|
||||
private:
|
||||
EventStreamifier& operator=(const EventStreamifier&);
|
||||
};
|
||||
|
||||
struct MeasureStream
|
||||
{
|
||||
uint32_t mSize;
|
||||
MeasureStream() : mSize(0)
|
||||
{
|
||||
}
|
||||
template <typename TDataType>
|
||||
void write(const TDataType& val)
|
||||
{
|
||||
mSize += sizeof(val);
|
||||
}
|
||||
template <typename TDataType>
|
||||
void write(const TDataType*, uint32_t count)
|
||||
{
|
||||
mSize += sizeof(TDataType) * count;
|
||||
}
|
||||
};
|
||||
|
||||
struct DataStreamState
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Open,
|
||||
SetPropertyValue,
|
||||
PropertyMessageGroup
|
||||
};
|
||||
};
|
||||
|
||||
} // pvdsdk
|
||||
} // physx
|
||||
#endif // PXPVDSDK_PXPVDCOMMSTREAMTYPES_H
|
||||
865
physx/source/pvd/src/PxPvdDataStream.cpp
Normal file
865
physx/source/pvd/src/PxPvdDataStream.cpp
Normal file
@ -0,0 +1,865 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "foundation/PxAssert.h"
|
||||
#include "PxPvdCommStreamEventSink.h"
|
||||
#include "PxPvdDataStreamHelpers.h"
|
||||
#include "PxPvdObjectModelInternalTypes.h"
|
||||
#include "PxPvdImpl.h"
|
||||
#include "PsFoundation.h"
|
||||
|
||||
using namespace physx;
|
||||
using namespace physx::pvdsdk;
|
||||
using namespace physx::shdfnd;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
struct ScopedMetaData
|
||||
{
|
||||
PvdOMMetaDataProvider& mProvider;
|
||||
PvdObjectModelMetaData& mMeta;
|
||||
ScopedMetaData(PvdOMMetaDataProvider& provider) : mProvider(provider), mMeta(provider.lock())
|
||||
{
|
||||
}
|
||||
~ScopedMetaData()
|
||||
{
|
||||
mProvider.unlock();
|
||||
}
|
||||
PvdObjectModelMetaData* operator->()
|
||||
{
|
||||
return &mMeta;
|
||||
}
|
||||
|
||||
private:
|
||||
ScopedMetaData& operator=(const ScopedMetaData&);
|
||||
};
|
||||
|
||||
struct PropertyDefinitionHelper : public PvdPropertyDefinitionHelper
|
||||
{
|
||||
PvdDataStream* mStream;
|
||||
PvdOMMetaDataProvider& mProvider;
|
||||
Array<char> mNameBuffer;
|
||||
Array<uint32_t> mNameStack;
|
||||
Array<NamedValue> mNamedValues;
|
||||
Array<PropertyMessageArg> mPropertyMessageArgs;
|
||||
|
||||
PropertyDefinitionHelper(PvdOMMetaDataProvider& provider)
|
||||
: mStream(NULL)
|
||||
, mProvider(provider)
|
||||
, mNameBuffer("PropertyDefinitionHelper::mNameBuffer")
|
||||
, mNameStack("PropertyDefinitionHelper::mNameStack")
|
||||
, mNamedValues("PropertyDefinitionHelper::mNamedValues")
|
||||
, mPropertyMessageArgs("PropertyDefinitionHelper::mPropertyMessageArgs")
|
||||
{
|
||||
}
|
||||
void setStream(PvdDataStream* stream)
|
||||
{
|
||||
mStream = stream;
|
||||
}
|
||||
|
||||
inline void appendStrToBuffer(const char* str)
|
||||
{
|
||||
if(str == NULL)
|
||||
return;
|
||||
size_t strLen = strlen(str);
|
||||
size_t endBufOffset = mNameBuffer.size();
|
||||
size_t resizeLen = endBufOffset;
|
||||
// account for null
|
||||
if(mNameBuffer.empty())
|
||||
resizeLen += 1;
|
||||
else
|
||||
endBufOffset -= 1;
|
||||
|
||||
mNameBuffer.resize(static_cast<uint32_t>(resizeLen + strLen));
|
||||
char* endPtr = mNameBuffer.begin() + endBufOffset;
|
||||
PxMemCopy(endPtr, str, static_cast<uint32_t>(strLen));
|
||||
}
|
||||
|
||||
virtual void pushName(const char* nm, const char* appender = ".")
|
||||
{
|
||||
size_t nameBufLen = mNameBuffer.size();
|
||||
mNameStack.pushBack(static_cast<uint32_t>(nameBufLen));
|
||||
if(mNameBuffer.empty() == false)
|
||||
appendStrToBuffer(appender);
|
||||
appendStrToBuffer(nm);
|
||||
mNameBuffer.back() = 0;
|
||||
}
|
||||
|
||||
virtual void pushBracketedName(const char* inName, const char* leftBracket = "[", const char* rightBracket = "]")
|
||||
{
|
||||
size_t nameBufLen = mNameBuffer.size();
|
||||
mNameStack.pushBack(static_cast<uint32_t>(nameBufLen));
|
||||
appendStrToBuffer(leftBracket);
|
||||
appendStrToBuffer(inName);
|
||||
appendStrToBuffer(rightBracket);
|
||||
mNameBuffer.back() = 0;
|
||||
}
|
||||
|
||||
virtual void popName()
|
||||
{
|
||||
if(mNameStack.empty())
|
||||
return;
|
||||
mNameBuffer.resize(static_cast<uint32_t>(mNameStack.back()));
|
||||
mNameStack.popBack();
|
||||
if(mNameBuffer.empty() == false)
|
||||
mNameBuffer.back() = 0;
|
||||
}
|
||||
|
||||
virtual const char* getTopName()
|
||||
{
|
||||
if(mNameBuffer.size())
|
||||
return mNameBuffer.begin();
|
||||
return "";
|
||||
}
|
||||
virtual void clearNameStack()
|
||||
{
|
||||
mNameBuffer.clear();
|
||||
mNameStack.clear();
|
||||
}
|
||||
|
||||
virtual void addNamedValue(const char* name, uint32_t value)
|
||||
{
|
||||
mNamedValues.pushBack(NamedValue(name, value));
|
||||
}
|
||||
virtual void clearNamedValues()
|
||||
{
|
||||
mNamedValues.clear();
|
||||
}
|
||||
|
||||
virtual DataRef<NamedValue> getNamedValues()
|
||||
{
|
||||
return DataRef<NamedValue>(mNamedValues.begin(), mNamedValues.size());
|
||||
}
|
||||
|
||||
virtual void createProperty(const NamespacedName& clsName, const char* inSemantic, const NamespacedName& dtypeName,
|
||||
PropertyType::Enum propType)
|
||||
{
|
||||
mStream->createProperty(clsName, getTopName(), inSemantic, dtypeName, propType, getNamedValues());
|
||||
clearNamedValues();
|
||||
}
|
||||
const char* registerStr(const char* str)
|
||||
{
|
||||
ScopedMetaData scopedProvider(mProvider);
|
||||
return scopedProvider->getStringTable().registerStr(str);
|
||||
}
|
||||
virtual void addPropertyMessageArg(const NamespacedName& inDatatype, uint32_t inOffset, uint32_t inSize)
|
||||
{
|
||||
mPropertyMessageArgs.pushBack(PropertyMessageArg(registerStr(getTopName()), inDatatype, inOffset, inSize));
|
||||
}
|
||||
virtual void addPropertyMessage(const NamespacedName& clsName, const NamespacedName& msgName,
|
||||
uint32_t inStructSizeInBytes)
|
||||
{
|
||||
if(mPropertyMessageArgs.empty())
|
||||
{
|
||||
PX_ASSERT(false);
|
||||
return;
|
||||
}
|
||||
mStream->createPropertyMessage(
|
||||
clsName, msgName, DataRef<PropertyMessageArg>(mPropertyMessageArgs.begin(), mPropertyMessageArgs.size()),
|
||||
inStructSizeInBytes);
|
||||
}
|
||||
virtual void clearPropertyMessageArgs()
|
||||
{
|
||||
mPropertyMessageArgs.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
PropertyDefinitionHelper& operator=(const PropertyDefinitionHelper&);
|
||||
};
|
||||
|
||||
class PvdMemPool
|
||||
{
|
||||
// Link List
|
||||
Array<uint8_t*> mMemBuffer;
|
||||
uint32_t mLength;
|
||||
uint32_t mBufIndex;
|
||||
|
||||
// 4k for one page
|
||||
static const int BUFFER_LENGTH = 4096;
|
||||
PX_NOCOPY(PvdMemPool)
|
||||
public:
|
||||
PvdMemPool(const char* bufDataName) : mMemBuffer(bufDataName), mLength(0), mBufIndex(0)
|
||||
{
|
||||
grow();
|
||||
}
|
||||
|
||||
~PvdMemPool()
|
||||
{
|
||||
for(uint32_t i = 0; i < mMemBuffer.size(); i++)
|
||||
{
|
||||
PX_FREE(mMemBuffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void grow()
|
||||
{
|
||||
if(mBufIndex + 1 < mMemBuffer.size())
|
||||
{
|
||||
mBufIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t* Buf = reinterpret_cast<uint8_t*>(PX_ALLOC(BUFFER_LENGTH, "PvdMemPool::mMemBuffer.buf"));
|
||||
mMemBuffer.pushBack(Buf);
|
||||
mBufIndex = mMemBuffer.size() - 1;
|
||||
}
|
||||
mLength = 0;
|
||||
}
|
||||
|
||||
void* allocate(uint32_t length)
|
||||
{
|
||||
if(length > uint32_t(BUFFER_LENGTH))
|
||||
return NULL;
|
||||
|
||||
if(length + mLength > uint32_t(BUFFER_LENGTH))
|
||||
grow();
|
||||
|
||||
void* mem = reinterpret_cast<void*>(&mMemBuffer[mBufIndex][mLength]);
|
||||
mLength += length;
|
||||
return mem;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
mLength = 0;
|
||||
mBufIndex = 0;
|
||||
}
|
||||
};
|
||||
struct PvdOutStream : public PvdDataStream, public UserAllocated
|
||||
{
|
||||
HashMap<String, uint32_t> mStringHashMap;
|
||||
PvdOMMetaDataProvider& mMetaDataProvider;
|
||||
Array<uint8_t> mTempBuffer;
|
||||
PropertyDefinitionHelper mPropertyDefinitionHelper;
|
||||
DataStreamState::Enum mStreamState;
|
||||
|
||||
ClassDescription mSPVClass;
|
||||
PropertyMessageDescription mMessageDesc;
|
||||
// Set property value and SetPropertyMessage calls require
|
||||
// us to write the data out to a separate buffer
|
||||
// when strings are involved.
|
||||
ForwardingMemoryBuffer mSPVBuffer;
|
||||
uint32_t mEventCount;
|
||||
uint32_t mPropertyMessageSize;
|
||||
bool mConnected;
|
||||
uint64_t mStreamId;
|
||||
Array<PvdCommand*> mPvdCommandArray;
|
||||
PvdMemPool mPvdCommandPool;
|
||||
PxPvdTransport& mTransport;
|
||||
|
||||
PvdOutStream(PxPvdTransport& transport, PvdOMMetaDataProvider& provider, uint64_t streamId)
|
||||
: mStringHashMap("PvdOutStream::mStringHashMap")
|
||||
, mMetaDataProvider(provider)
|
||||
, mTempBuffer("PvdOutStream::mTempBuffer")
|
||||
, mPropertyDefinitionHelper(mMetaDataProvider)
|
||||
, mStreamState(DataStreamState::Open)
|
||||
, mSPVBuffer("PvdCommStreamBufferedEventSink::mSPVBuffer")
|
||||
, mEventCount(0)
|
||||
, mPropertyMessageSize(0)
|
||||
, mConnected(true)
|
||||
, mStreamId(streamId)
|
||||
, mPvdCommandArray("PvdCommStreamBufferedEventSink::mPvdCommandArray")
|
||||
, mPvdCommandPool("PvdCommStreamBufferedEventSink::mPvdCommandPool")
|
||||
, mTransport(transport)
|
||||
{
|
||||
mPropertyDefinitionHelper.setStream(this);
|
||||
}
|
||||
virtual ~PvdOutStream()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void release()
|
||||
{
|
||||
PVD_DELETE(this);
|
||||
}
|
||||
|
||||
StringHandle toStream(String nm)
|
||||
{
|
||||
if(nm == NULL || *nm == 0)
|
||||
return 0;
|
||||
const HashMap<String, uint32_t>::Entry* entry(mStringHashMap.find(nm));
|
||||
if(entry)
|
||||
return entry->second;
|
||||
ScopedMetaData meta(mMetaDataProvider);
|
||||
StringHandle hdl = meta->getStringTable().strToHandle(nm);
|
||||
nm = meta->getStringTable().handleToStr(hdl);
|
||||
handlePvdEvent(StringHandleEvent(nm, hdl));
|
||||
mStringHashMap.insert(nm, hdl);
|
||||
return hdl;
|
||||
}
|
||||
|
||||
StreamNamespacedName toStream(const NamespacedName& nm)
|
||||
{
|
||||
return StreamNamespacedName(toStream(nm.mNamespace), toStream(nm.mName));
|
||||
}
|
||||
|
||||
bool isClassExist(const NamespacedName& nm)
|
||||
{
|
||||
ScopedMetaData meta(mMetaDataProvider);
|
||||
return meta->findClass(nm).hasValue();
|
||||
}
|
||||
|
||||
bool createMetaClass(const NamespacedName& nm)
|
||||
{
|
||||
ScopedMetaData meta(mMetaDataProvider);
|
||||
meta->getOrCreateClass(nm);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool deriveMetaClass(const NamespacedName& parent, const NamespacedName& child)
|
||||
{
|
||||
ScopedMetaData meta(mMetaDataProvider);
|
||||
return meta->deriveClass(parent, child);
|
||||
}
|
||||
|
||||
// You will notice that some functions are #pragma'd out throughout this file.
|
||||
// This is because they are only called from asserts which means they aren't
|
||||
// called in release. This causes warnings when building using snc which break
|
||||
// the build.
|
||||
#if PX_DEBUG
|
||||
|
||||
bool propertyExists(const NamespacedName& nm, String pname)
|
||||
{
|
||||
ScopedMetaData meta(mMetaDataProvider);
|
||||
return meta->findProperty(nm, pname).hasValue();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
PvdError boolToError(bool val)
|
||||
{
|
||||
if(val)
|
||||
return PvdErrorType::Success;
|
||||
return PvdErrorType::NetworkError;
|
||||
}
|
||||
|
||||
// PvdMetaDataStream
|
||||
virtual PvdError createClass(const NamespacedName& nm)
|
||||
{
|
||||
PX_ASSERT(mStreamState == DataStreamState::Open);
|
||||
#if PX_DEBUG
|
||||
PX_ASSERT(isClassExist(nm) == false);
|
||||
#endif
|
||||
createMetaClass(nm);
|
||||
return boolToError(handlePvdEvent(CreateClass(toStream(nm))));
|
||||
}
|
||||
|
||||
virtual PvdError deriveClass(const NamespacedName& parent, const NamespacedName& child)
|
||||
{
|
||||
PX_ASSERT(mStreamState == DataStreamState::Open);
|
||||
#if PX_DEBUG
|
||||
PX_ASSERT(isClassExist(parent));
|
||||
PX_ASSERT(isClassExist(child));
|
||||
#endif
|
||||
deriveMetaClass(parent, child);
|
||||
return boolToError(handlePvdEvent(DeriveClass(toStream(parent), toStream(child))));
|
||||
}
|
||||
|
||||
template <typename TDataType>
|
||||
TDataType* allocTemp(uint32_t numItems)
|
||||
{
|
||||
uint32_t desiredBytes = numItems * sizeof(TDataType);
|
||||
if(desiredBytes > mTempBuffer.size())
|
||||
mTempBuffer.resize(desiredBytes);
|
||||
TDataType* retval = reinterpret_cast<TDataType*>(mTempBuffer.begin());
|
||||
if(numItems)
|
||||
{
|
||||
PVD_FOREACH(idx, numItems) new (retval + idx) TDataType();
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
#if PX_DEBUG
|
||||
|
||||
// Property datatypes need to be uniform.
|
||||
// At this point, the data stream cannot handle properties that
|
||||
// A struct with a float member and a char member would work.
|
||||
// A struct with a float member and a long member would work (more efficiently).
|
||||
bool isValidPropertyDatatype(const NamespacedName& dtypeName)
|
||||
{
|
||||
ScopedMetaData meta(mMetaDataProvider);
|
||||
ClassDescription clsDesc(meta->findClass(dtypeName));
|
||||
return clsDesc.mRequiresDestruction == false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
NamespacedName createMetaProperty(const NamespacedName& clsName, String name, String semantic,
|
||||
const NamespacedName& dtypeName, PropertyType::Enum propertyType)
|
||||
{
|
||||
ScopedMetaData meta(mMetaDataProvider);
|
||||
int32_t dtypeType = meta->findClass(dtypeName)->mClassId;
|
||||
NamespacedName typeName = dtypeName;
|
||||
if(dtypeType == getPvdTypeForType<String>())
|
||||
{
|
||||
dtypeType = getPvdTypeForType<StringHandle>();
|
||||
typeName = getPvdNamespacedNameForType<StringHandle>();
|
||||
}
|
||||
Option<PropertyDescription> propOpt =
|
||||
meta->createProperty(meta->findClass(clsName)->mClassId, name, semantic, dtypeType, propertyType);
|
||||
PX_ASSERT(propOpt.hasValue());
|
||||
PX_UNUSED(propOpt);
|
||||
return typeName;
|
||||
}
|
||||
|
||||
virtual PvdError createProperty(const NamespacedName& clsName, String name, String semantic,
|
||||
const NamespacedName& incomingDtypeName, PropertyType::Enum propertyType,
|
||||
DataRef<NamedValue> values)
|
||||
{
|
||||
PX_ASSERT(mStreamState == DataStreamState::Open);
|
||||
#if PX_DEBUG
|
||||
PX_ASSERT(isClassExist(clsName));
|
||||
PX_ASSERT(propertyExists(clsName, name) == false);
|
||||
#endif
|
||||
NamespacedName dtypeName(incomingDtypeName);
|
||||
if(safeStrEq(dtypeName.mName, "VoidPtr"))
|
||||
dtypeName.mName = "ObjectRef";
|
||||
#if PX_DEBUG
|
||||
PX_ASSERT(isClassExist(dtypeName));
|
||||
PX_ASSERT(isValidPropertyDatatype(dtypeName));
|
||||
#endif
|
||||
NamespacedName typeName = createMetaProperty(clsName, name, semantic, dtypeName, propertyType);
|
||||
// Can't have arrays of strings or arrays of string handles due to the difficulty
|
||||
// of quickly dealing with them on the network receiving side.
|
||||
if(propertyType == PropertyType::Array && safeStrEq(typeName.mName, "StringHandle"))
|
||||
{
|
||||
PX_ASSERT(false);
|
||||
return PvdErrorType::ArgumentError;
|
||||
}
|
||||
uint32_t numItems = values.size();
|
||||
NameHandleValue* streamValues = allocTemp<NameHandleValue>(numItems);
|
||||
PVD_FOREACH(idx, numItems)
|
||||
streamValues[idx] = NameHandleValue(toStream(values[idx].mName), values[idx].mValue);
|
||||
CreateProperty evt(toStream(clsName), toStream(name), toStream(semantic), toStream(typeName), propertyType,
|
||||
DataRef<NameHandleValue>(streamValues, numItems));
|
||||
return boolToError(handlePvdEvent(evt));
|
||||
}
|
||||
|
||||
bool createMetaPropertyMessage(const NamespacedName& cls, const NamespacedName& msgName,
|
||||
DataRef<PropertyMessageArg> entries, uint32_t messageSizeInBytes)
|
||||
{
|
||||
ScopedMetaData meta(mMetaDataProvider);
|
||||
return meta->createPropertyMessage(cls, msgName, entries, messageSizeInBytes).hasValue();
|
||||
}
|
||||
#if PX_DEBUG
|
||||
|
||||
bool messageExists(const NamespacedName& msgName)
|
||||
{
|
||||
ScopedMetaData meta(mMetaDataProvider);
|
||||
return meta->findPropertyMessage(msgName).hasValue();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
virtual PvdError createPropertyMessage(const NamespacedName& cls, const NamespacedName& msgName,
|
||||
DataRef<PropertyMessageArg> entries, uint32_t messageSizeInBytes)
|
||||
{
|
||||
PX_ASSERT(mStreamState == DataStreamState::Open);
|
||||
#if PX_DEBUG
|
||||
PX_ASSERT(isClassExist(cls));
|
||||
PX_ASSERT(messageExists(msgName) == false);
|
||||
#endif
|
||||
createMetaPropertyMessage(cls, msgName, entries, messageSizeInBytes);
|
||||
uint32_t numItems = entries.size();
|
||||
StreamPropMessageArg* streamValues = allocTemp<StreamPropMessageArg>(numItems);
|
||||
PVD_FOREACH(idx, numItems)
|
||||
streamValues[idx] =
|
||||
StreamPropMessageArg(toStream(entries[idx].mPropertyName), toStream(entries[idx].mDatatypeName),
|
||||
entries[idx].mMessageOffset, entries[idx].mByteSize);
|
||||
CreatePropertyMessage evt(toStream(cls), toStream(msgName),
|
||||
DataRef<StreamPropMessageArg>(streamValues, numItems), messageSizeInBytes);
|
||||
return boolToError(handlePvdEvent(evt));
|
||||
}
|
||||
|
||||
uint64_t toStream(const void* instance)
|
||||
{
|
||||
return PVD_POINTER_TO_U64(instance);
|
||||
}
|
||||
virtual PvdError createInstance(const NamespacedName& cls, const void* instance)
|
||||
{
|
||||
PX_ASSERT(isInstanceValid(instance) == false);
|
||||
PX_ASSERT(mStreamState == DataStreamState::Open);
|
||||
bool success = mMetaDataProvider.createInstance(cls, instance);
|
||||
PX_ASSERT(success);
|
||||
(void)success;
|
||||
return boolToError(handlePvdEvent(CreateInstance(toStream(cls), toStream(instance))));
|
||||
}
|
||||
|
||||
virtual bool isInstanceValid(const void* instance)
|
||||
{
|
||||
return mMetaDataProvider.isInstanceValid(instance);
|
||||
}
|
||||
|
||||
#if PX_DEBUG
|
||||
|
||||
// If the property will fit or is already completely in memory
|
||||
bool checkPropertyType(const void* instance, String name, const NamespacedName& incomingType)
|
||||
{
|
||||
int32_t instType = mMetaDataProvider.getInstanceClassType(instance);
|
||||
ScopedMetaData meta(mMetaDataProvider);
|
||||
Option<PropertyDescription> prop = meta->findProperty(instType, name);
|
||||
if(prop.hasValue() == false)
|
||||
return false;
|
||||
int32_t propType = prop->mDatatype;
|
||||
int32_t incomingTypeId = meta->findClass(incomingType)->mClassId;
|
||||
if(incomingTypeId != getPvdTypeForType<VoidPtr>())
|
||||
{
|
||||
MarshalQueryResult result = meta->checkMarshalling(incomingTypeId, propType);
|
||||
bool possible = result.needsMarshalling == false || result.canMarshal;
|
||||
return possible;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(propType != getPvdTypeForType<ObjectRef>())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
DataRef<const uint8_t> bufferPropertyValue(ClassDescriptionSizeInfo info, DataRef<const uint8_t> data)
|
||||
{
|
||||
uint32_t realSize = info.mByteSize;
|
||||
uint32_t numItems = data.size() / realSize;
|
||||
if(info.mPtrOffsets.size() != 0)
|
||||
{
|
||||
mSPVBuffer.clear();
|
||||
PVD_FOREACH(item, numItems)
|
||||
{
|
||||
const uint8_t* itemPtr = data.begin() + item * realSize;
|
||||
mSPVBuffer.write(itemPtr, realSize);
|
||||
PVD_FOREACH(stringIdx, info.mPtrOffsets.size())
|
||||
{
|
||||
PtrOffset offset(info.mPtrOffsets[stringIdx]);
|
||||
if(offset.mOffsetType == PtrOffsetType::VoidPtrOffset)
|
||||
continue;
|
||||
const char* strPtr;
|
||||
physx::intrinsics::memCopy(&strPtr, itemPtr + offset.mOffset, sizeof(char*));
|
||||
strPtr = nonNull(strPtr);
|
||||
uint32_t len = safeStrLen(strPtr) + 1;
|
||||
mSPVBuffer.write(strPtr, len);
|
||||
}
|
||||
}
|
||||
data = DataRef<const uint8_t>(mSPVBuffer.begin(), mSPVBuffer.size());
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
virtual PvdError setPropertyValue(const void* instance, String name, DataRef<const uint8_t> data,
|
||||
const NamespacedName& incomingTypeName)
|
||||
{
|
||||
|
||||
PX_ASSERT(isInstanceValid(instance));
|
||||
#if PX_DEBUG
|
||||
PX_ASSERT(isClassExist(incomingTypeName));
|
||||
#endif
|
||||
PX_ASSERT(mStreamState == DataStreamState::Open);
|
||||
ClassDescription clsDesc;
|
||||
{
|
||||
ScopedMetaData meta(mMetaDataProvider);
|
||||
clsDesc = meta->findClass(incomingTypeName);
|
||||
}
|
||||
uint32_t realSize = clsDesc.getNativeSize();
|
||||
uint32_t numItems = data.size() / realSize;
|
||||
data = bufferPropertyValue(clsDesc.getNativeSizeInfo(), data);
|
||||
SetPropertyValue evt(toStream(instance), toStream(name), data, toStream(incomingTypeName), numItems);
|
||||
return boolToError(handlePvdEvent(evt));
|
||||
}
|
||||
|
||||
// Else if the property is very large (contact reports) you can send it in chunks.
|
||||
virtual PvdError beginSetPropertyValue(const void* instance, String name, const NamespacedName& incomingTypeName)
|
||||
{
|
||||
PX_ASSERT(isInstanceValid(instance));
|
||||
#if PX_DEBUG
|
||||
PX_ASSERT(isClassExist(incomingTypeName));
|
||||
PX_ASSERT(checkPropertyType(instance, name, incomingTypeName));
|
||||
#endif
|
||||
PX_ASSERT(mStreamState == DataStreamState::Open);
|
||||
mStreamState = DataStreamState::SetPropertyValue;
|
||||
{
|
||||
ScopedMetaData meta(mMetaDataProvider);
|
||||
mSPVClass = meta->findClass(incomingTypeName);
|
||||
}
|
||||
BeginSetPropertyValue evt(toStream(instance), toStream(name), toStream(incomingTypeName));
|
||||
return boolToError(handlePvdEvent(evt));
|
||||
}
|
||||
|
||||
virtual PvdError appendPropertyValueData(DataRef<const uint8_t> data)
|
||||
{
|
||||
uint32_t realSize = mSPVClass.getNativeSize();
|
||||
uint32_t numItems = data.size() / realSize;
|
||||
data = bufferPropertyValue(mSPVClass.getNativeSizeInfo(), data);
|
||||
PX_ASSERT(mStreamState == DataStreamState::SetPropertyValue);
|
||||
return boolToError(handlePvdEvent(AppendPropertyValueData(data, numItems)));
|
||||
}
|
||||
virtual PvdError endSetPropertyValue()
|
||||
{
|
||||
PX_ASSERT(mStreamState == DataStreamState::SetPropertyValue);
|
||||
mStreamState = DataStreamState::Open;
|
||||
return boolToError(handlePvdEvent(EndSetPropertyValue()));
|
||||
}
|
||||
|
||||
#if PX_DEBUG
|
||||
|
||||
bool checkPropertyMessage(const void* instance, const NamespacedName& msgName)
|
||||
{
|
||||
int32_t clsId = mMetaDataProvider.getInstanceClassType(instance);
|
||||
ScopedMetaData meta(mMetaDataProvider);
|
||||
PropertyMessageDescription desc(meta->findPropertyMessage(msgName));
|
||||
bool retval = meta->isDerivedFrom(clsId, desc.mClassId);
|
||||
return retval;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
DataRef<const uint8_t> bufferPropertyMessage(const PropertyMessageDescription& desc, DataRef<const uint8_t> data)
|
||||
{
|
||||
if(desc.mStringOffsets.size())
|
||||
{
|
||||
mSPVBuffer.clear();
|
||||
mSPVBuffer.write(data.begin(), data.size());
|
||||
PVD_FOREACH(idx, desc.mStringOffsets.size())
|
||||
{
|
||||
const char* strPtr;
|
||||
physx::intrinsics::memCopy(&strPtr, data.begin() + desc.mStringOffsets[idx], sizeof(char*));
|
||||
strPtr = nonNull(strPtr);
|
||||
uint32_t len = safeStrLen(strPtr) + 1;
|
||||
mSPVBuffer.write(strPtr, len);
|
||||
}
|
||||
data = DataRef<const uint8_t>(mSPVBuffer.begin(), mSPVBuffer.end());
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
virtual PvdError setPropertyMessage(const void* instance, const NamespacedName& msgName, DataRef<const uint8_t> data)
|
||||
{
|
||||
ScopedMetaData meta(mMetaDataProvider);
|
||||
PX_ASSERT(isInstanceValid(instance));
|
||||
#if PX_DEBUG
|
||||
PX_ASSERT(messageExists(msgName));
|
||||
PX_ASSERT(checkPropertyMessage(instance, msgName));
|
||||
#endif
|
||||
PropertyMessageDescription desc(meta->findPropertyMessage(msgName));
|
||||
if(data.size() < desc.mMessageByteSize)
|
||||
{
|
||||
PX_ASSERT(false);
|
||||
return PvdErrorType::ArgumentError;
|
||||
}
|
||||
data = bufferPropertyMessage(desc, data);
|
||||
PX_ASSERT(mStreamState == DataStreamState::Open);
|
||||
return boolToError(handlePvdEvent(SetPropertyMessage(toStream(instance), toStream(msgName), data)));
|
||||
}
|
||||
|
||||
#if PX_DEBUG
|
||||
|
||||
bool checkBeginPropertyMessageGroup(const NamespacedName& msgName)
|
||||
{
|
||||
ScopedMetaData meta(mMetaDataProvider);
|
||||
PropertyMessageDescription desc(meta->findPropertyMessage(msgName));
|
||||
return desc.mStringOffsets.size() == 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
// If you need to send of lot of identical messages, this avoids a hashtable lookup per message.
|
||||
virtual PvdError beginPropertyMessageGroup(const NamespacedName& msgName)
|
||||
{
|
||||
#if PX_DEBUG
|
||||
PX_ASSERT(messageExists(msgName));
|
||||
PX_ASSERT(checkBeginPropertyMessageGroup(msgName));
|
||||
#endif
|
||||
PX_ASSERT(mStreamState == DataStreamState::Open);
|
||||
mStreamState = DataStreamState::PropertyMessageGroup;
|
||||
ScopedMetaData meta(mMetaDataProvider);
|
||||
mMessageDesc = meta->findPropertyMessage(msgName);
|
||||
return boolToError(handlePvdEvent(BeginPropertyMessageGroup(toStream(msgName))));
|
||||
}
|
||||
|
||||
virtual PvdError sendPropertyMessageFromGroup(const void* instance, DataRef<const uint8_t> data)
|
||||
{
|
||||
PX_ASSERT(mStreamState == DataStreamState::PropertyMessageGroup);
|
||||
PX_ASSERT(isInstanceValid(instance));
|
||||
#if PX_DEBUG
|
||||
PX_ASSERT(checkPropertyMessage(instance, mMessageDesc.mMessageName));
|
||||
#endif
|
||||
if(mMessageDesc.mMessageByteSize != data.size())
|
||||
{
|
||||
PX_ASSERT(false);
|
||||
return PvdErrorType::ArgumentError;
|
||||
}
|
||||
if(data.size() < mMessageDesc.mMessageByteSize)
|
||||
return PvdErrorType::ArgumentError;
|
||||
data = bufferPropertyMessage(mMessageDesc, data);
|
||||
return boolToError(handlePvdEvent(SendPropertyMessageFromGroup(toStream(instance), data)));
|
||||
}
|
||||
virtual PvdError endPropertyMessageGroup()
|
||||
{
|
||||
PX_ASSERT(mStreamState == DataStreamState::PropertyMessageGroup);
|
||||
mStreamState = DataStreamState::Open;
|
||||
return boolToError(handlePvdEvent(EndPropertyMessageGroup()));
|
||||
}
|
||||
virtual PvdError pushBackObjectRef(const void* instance, String propName, const void* data)
|
||||
{
|
||||
PX_ASSERT(isInstanceValid(instance));
|
||||
PX_ASSERT(isInstanceValid(data));
|
||||
PX_ASSERT(mStreamState == DataStreamState::Open);
|
||||
return boolToError(handlePvdEvent(PushBackObjectRef(toStream(instance), toStream(propName), toStream(data))));
|
||||
}
|
||||
virtual PvdError removeObjectRef(const void* instance, String propName, const void* data)
|
||||
{
|
||||
PX_ASSERT(isInstanceValid(instance));
|
||||
PX_ASSERT(isInstanceValid(data));
|
||||
PX_ASSERT(mStreamState == DataStreamState::Open);
|
||||
return boolToError(handlePvdEvent(RemoveObjectRef(toStream(instance), toStream(propName), toStream(data))));
|
||||
}
|
||||
// Instance elimination.
|
||||
virtual PvdError destroyInstance(const void* instance)
|
||||
{
|
||||
PX_ASSERT(isInstanceValid(instance));
|
||||
PX_ASSERT(mStreamState == DataStreamState::Open);
|
||||
mMetaDataProvider.destroyInstance(instance);
|
||||
return boolToError(handlePvdEvent(DestroyInstance(toStream(instance))));
|
||||
}
|
||||
|
||||
// Profiling hooks
|
||||
virtual PvdError beginSection(const void* instance, String name)
|
||||
{
|
||||
PX_ASSERT(mStreamState == DataStreamState::Open);
|
||||
return boolToError(handlePvdEvent(
|
||||
BeginSection(toStream(instance), toStream(name), Time::getCurrentCounterValue())));
|
||||
}
|
||||
|
||||
virtual PvdError endSection(const void* instance, String name)
|
||||
{
|
||||
PX_ASSERT(mStreamState == DataStreamState::Open);
|
||||
return boolToError(handlePvdEvent(
|
||||
EndSection(toStream(instance), toStream(name), Time::getCurrentCounterValue())));
|
||||
}
|
||||
|
||||
virtual PvdError originShift(const void* scene, PxVec3 shift)
|
||||
{
|
||||
PX_ASSERT(mStreamState == DataStreamState::Open);
|
||||
return boolToError(handlePvdEvent(OriginShift(toStream(scene), shift)));
|
||||
}
|
||||
|
||||
virtual void addProfileZone(void* zone, const char* name)
|
||||
{
|
||||
handlePvdEvent(AddProfileZone(toStream(zone), name));
|
||||
}
|
||||
virtual void addProfileZoneEvent(void* zone, const char* name, uint16_t eventId, bool compileTimeEnabled)
|
||||
{
|
||||
handlePvdEvent(AddProfileZoneEvent(toStream(zone), name, eventId, compileTimeEnabled));
|
||||
}
|
||||
|
||||
// add a variable sized event
|
||||
void addEvent(const EventSerializeable& evt, PvdCommStreamEventTypes::Enum evtType)
|
||||
{
|
||||
MeasureStream measure;
|
||||
PvdCommStreamEventSink::writeStreamEvent(evt, evtType, measure);
|
||||
EventGroup evtGroup(measure.mSize, 1, mStreamId, Time::getCurrentCounterValue());
|
||||
EventStreamifier<PxPvdTransport> streamifier(mTransport.lock());
|
||||
evtGroup.serialize(streamifier);
|
||||
PvdCommStreamEventSink::writeStreamEvent(evt, evtType, mTransport);
|
||||
mTransport.unlock();
|
||||
}
|
||||
|
||||
void setIsTopLevelUIElement(const void* instance, bool topLevel)
|
||||
{
|
||||
addEvent(SetIsTopLevel(static_cast<uint64_t>(reinterpret_cast<size_t>(instance)), topLevel),
|
||||
getCommStreamEventType<SetIsTopLevel>());
|
||||
}
|
||||
|
||||
void sendErrorMessage(uint32_t code, const char* message, const char* file, uint32_t line)
|
||||
{
|
||||
addEvent(ErrorMessage(code, message, file, line), getCommStreamEventType<ErrorMessage>());
|
||||
}
|
||||
|
||||
void updateCamera(const char* name, const PxVec3& origin, const PxVec3& up, const PxVec3& target)
|
||||
{
|
||||
addEvent(SetCamera(name, origin, up, target), getCommStreamEventType<SetCamera>());
|
||||
}
|
||||
|
||||
template <typename TEventType>
|
||||
bool handlePvdEvent(const TEventType& evt)
|
||||
{
|
||||
addEvent(evt, getCommStreamEventType<TEventType>());
|
||||
return mConnected;
|
||||
}
|
||||
|
||||
virtual PvdPropertyDefinitionHelper& getPropertyDefinitionHelper()
|
||||
{
|
||||
mPropertyDefinitionHelper.clearBufferedData();
|
||||
return mPropertyDefinitionHelper;
|
||||
}
|
||||
|
||||
virtual bool isConnected()
|
||||
{
|
||||
return mConnected;
|
||||
}
|
||||
|
||||
virtual void* allocateMemForCmd(uint32_t length)
|
||||
{
|
||||
return mPvdCommandPool.allocate(length);
|
||||
}
|
||||
|
||||
virtual void pushPvdCommand(PvdCommand& cmd)
|
||||
{
|
||||
mPvdCommandArray.pushBack(&cmd);
|
||||
}
|
||||
|
||||
virtual void flushPvdCommand()
|
||||
{
|
||||
uint32_t cmdQueueSize = mPvdCommandArray.size();
|
||||
for(uint32_t i = 0; i < cmdQueueSize; i++)
|
||||
{
|
||||
if(mPvdCommandArray[i])
|
||||
{
|
||||
// if(mPvdCommandArray[i]->canRun(*this))
|
||||
mPvdCommandArray[i]->run(*this);
|
||||
mPvdCommandArray[i]->~PvdCommand();
|
||||
}
|
||||
}
|
||||
mPvdCommandArray.clear();
|
||||
mPvdCommandPool.clear();
|
||||
}
|
||||
|
||||
PX_NOCOPY(PvdOutStream)
|
||||
};
|
||||
}
|
||||
|
||||
PvdDataStream* PvdDataStream::create(PxPvd* pvd)
|
||||
{
|
||||
if(pvd == NULL)
|
||||
{
|
||||
getFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "PvdDataStream::create - pvd must be non-NULL!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PvdImpl* pvdImpl = static_cast<PvdImpl*>(pvd);
|
||||
return PVD_NEW(PvdOutStream)(*pvdImpl->getTransport(), pvdImpl->getMetaDataProvider(), pvdImpl->getNextStreamId());
|
||||
}
|
||||
218
physx/source/pvd/src/PxPvdDefaultFileTransport.cpp
Normal file
218
physx/source/pvd/src/PxPvdDefaultFileTransport.cpp
Normal file
@ -0,0 +1,218 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#include "PxPvdDefaultFileTransport.h"
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace pvdsdk
|
||||
{
|
||||
|
||||
PvdDefaultFileTransport::PvdDefaultFileTransport(const char* name) : mConnected(false), mWrittenData(0), mLocked(false)
|
||||
{
|
||||
mFileBuffer = PX_NEW(PsFileBuffer)(name, PxFileBuf::OPEN_WRITE_ONLY);
|
||||
}
|
||||
|
||||
PvdDefaultFileTransport::~PvdDefaultFileTransport()
|
||||
{
|
||||
}
|
||||
|
||||
bool PvdDefaultFileTransport::connect()
|
||||
{
|
||||
PX_ASSERT(mFileBuffer);
|
||||
mConnected = mFileBuffer->isOpen();
|
||||
return mConnected;
|
||||
}
|
||||
|
||||
void PvdDefaultFileTransport::disconnect()
|
||||
{
|
||||
mConnected = false;
|
||||
}
|
||||
|
||||
bool PvdDefaultFileTransport::isConnected()
|
||||
{
|
||||
return mConnected;
|
||||
}
|
||||
|
||||
bool PvdDefaultFileTransport::write(const uint8_t* inBytes, uint32_t inLength)
|
||||
{
|
||||
PX_ASSERT(mLocked);
|
||||
PX_ASSERT(mFileBuffer);
|
||||
if (mConnected)
|
||||
{
|
||||
uint32_t len = mFileBuffer->write(inBytes, inLength);
|
||||
mWrittenData += len;
|
||||
return len == inLength;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
PxPvdTransport& PvdDefaultFileTransport::lock()
|
||||
{
|
||||
mMutex.lock();
|
||||
PX_ASSERT(!mLocked);
|
||||
mLocked = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void PvdDefaultFileTransport::unlock()
|
||||
{
|
||||
PX_ASSERT(mLocked);
|
||||
mLocked = false;
|
||||
mMutex.unlock();
|
||||
}
|
||||
|
||||
void PvdDefaultFileTransport::flush()
|
||||
{
|
||||
}
|
||||
|
||||
uint64_t PvdDefaultFileTransport::getWrittenDataSize()
|
||||
{
|
||||
return mWrittenData;
|
||||
}
|
||||
|
||||
void PvdDefaultFileTransport::release()
|
||||
{
|
||||
if (mFileBuffer)
|
||||
{
|
||||
mFileBuffer->close();
|
||||
delete mFileBuffer;
|
||||
}
|
||||
mFileBuffer = NULL;
|
||||
PX_DELETE(this);
|
||||
}
|
||||
|
||||
class NullFileTransport : public physx::PxPvdTransport, public physx::shdfnd::UserAllocated
|
||||
{
|
||||
PX_NOCOPY(NullFileTransport)
|
||||
public:
|
||||
NullFileTransport();
|
||||
virtual ~NullFileTransport();
|
||||
|
||||
virtual bool connect();
|
||||
virtual void disconnect();
|
||||
virtual bool isConnected();
|
||||
|
||||
virtual bool write(const uint8_t* inBytes, uint32_t inLength);
|
||||
|
||||
virtual PxPvdTransport& lock();
|
||||
virtual void unlock();
|
||||
|
||||
virtual void flush();
|
||||
|
||||
virtual uint64_t getWrittenDataSize();
|
||||
|
||||
virtual void release();
|
||||
|
||||
private:
|
||||
bool mConnected;
|
||||
uint64_t mWrittenData;
|
||||
physx::shdfnd::Mutex mMutex;
|
||||
bool mLocked; // for debug, remove it when finished
|
||||
};
|
||||
|
||||
NullFileTransport::NullFileTransport() : mConnected(false), mWrittenData(0), mLocked(false)
|
||||
{
|
||||
}
|
||||
|
||||
NullFileTransport::~NullFileTransport()
|
||||
{
|
||||
}
|
||||
|
||||
bool NullFileTransport::connect()
|
||||
{
|
||||
mConnected = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void NullFileTransport::disconnect()
|
||||
{
|
||||
mConnected = false;
|
||||
}
|
||||
|
||||
bool NullFileTransport::isConnected()
|
||||
{
|
||||
return mConnected;
|
||||
}
|
||||
|
||||
bool NullFileTransport::write(const uint8_t* /*inBytes*/, uint32_t inLength)
|
||||
{
|
||||
PX_ASSERT(mLocked);
|
||||
if(mConnected)
|
||||
{
|
||||
uint32_t len = inLength;
|
||||
mWrittenData += len;
|
||||
return len == inLength;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
PxPvdTransport& NullFileTransport::lock()
|
||||
{
|
||||
mMutex.lock();
|
||||
PX_ASSERT(!mLocked);
|
||||
mLocked = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void NullFileTransport::unlock()
|
||||
{
|
||||
PX_ASSERT(mLocked);
|
||||
mLocked = false;
|
||||
mMutex.unlock();
|
||||
}
|
||||
|
||||
void NullFileTransport::flush()
|
||||
{
|
||||
}
|
||||
|
||||
uint64_t NullFileTransport::getWrittenDataSize()
|
||||
{
|
||||
return mWrittenData;
|
||||
}
|
||||
|
||||
void NullFileTransport::release()
|
||||
{
|
||||
PX_DELETE(this);
|
||||
}
|
||||
|
||||
} // namespace pvdsdk
|
||||
|
||||
PxPvdTransport* PxDefaultPvdFileTransportCreate(const char* name)
|
||||
{
|
||||
if(name)
|
||||
return PX_NEW(pvdsdk::PvdDefaultFileTransport)(name);
|
||||
else
|
||||
return PX_NEW(pvdsdk::NullFileTransport)();
|
||||
}
|
||||
|
||||
} // namespace physx
|
||||
|
||||
77
physx/source/pvd/src/PxPvdDefaultFileTransport.h
Normal file
77
physx/source/pvd/src/PxPvdDefaultFileTransport.h
Normal file
@ -0,0 +1,77 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifndef PXPVDSDK_PXPVDDEFAULTFILETRANSPORT_H
|
||||
#define PXPVDSDK_PXPVDDEFAULTFILETRANSPORT_H
|
||||
|
||||
#include "pvd/PxPvdTransport.h"
|
||||
|
||||
#include "PsUserAllocated.h"
|
||||
#include "PsFileBuffer.h"
|
||||
#include "PsMutex.h"
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace pvdsdk
|
||||
{
|
||||
|
||||
class PvdDefaultFileTransport : public physx::PxPvdTransport, public physx::shdfnd::UserAllocated
|
||||
{
|
||||
PX_NOCOPY(PvdDefaultFileTransport)
|
||||
public:
|
||||
PvdDefaultFileTransport(const char* name);
|
||||
virtual ~PvdDefaultFileTransport();
|
||||
|
||||
virtual bool connect();
|
||||
virtual void disconnect();
|
||||
virtual bool isConnected();
|
||||
|
||||
virtual bool write(const uint8_t* inBytes, uint32_t inLength);
|
||||
|
||||
virtual PxPvdTransport& lock();
|
||||
virtual void unlock();
|
||||
|
||||
virtual void flush();
|
||||
|
||||
virtual uint64_t getWrittenDataSize();
|
||||
|
||||
virtual void release();
|
||||
|
||||
private:
|
||||
physx::PsFileBuffer* mFileBuffer;
|
||||
bool mConnected;
|
||||
uint64_t mWrittenData;
|
||||
physx::shdfnd::Mutex mMutex;
|
||||
bool mLocked; // for debug, remove it when finished
|
||||
};
|
||||
|
||||
} // pvdsdk
|
||||
} // physx
|
||||
|
||||
#endif // PXPVDSDK_PXPVDDEFAULTFILETRANSPORT_H
|
||||
134
physx/source/pvd/src/PxPvdDefaultSocketTransport.cpp
Normal file
134
physx/source/pvd/src/PxPvdDefaultSocketTransport.cpp
Normal file
@ -0,0 +1,134 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#include "PxPvdDefaultSocketTransport.h"
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace pvdsdk
|
||||
{
|
||||
PvdDefaultSocketTransport::PvdDefaultSocketTransport(const char* host, int port, unsigned int timeoutInMilliseconds)
|
||||
: mHost(host), mPort(uint16_t(port)), mTimeout(timeoutInMilliseconds), mConnected(false), mWrittenData(0)
|
||||
{
|
||||
}
|
||||
|
||||
PvdDefaultSocketTransport::~PvdDefaultSocketTransport()
|
||||
{
|
||||
}
|
||||
|
||||
bool PvdDefaultSocketTransport::connect()
|
||||
{
|
||||
if(mConnected)
|
||||
return true;
|
||||
|
||||
if(mSocket.connect(mHost, mPort, mTimeout))
|
||||
{
|
||||
mSocket.setBlocking(true);
|
||||
mConnected = true;
|
||||
}
|
||||
return mConnected;
|
||||
}
|
||||
|
||||
void PvdDefaultSocketTransport::disconnect()
|
||||
{
|
||||
mSocket.flush();
|
||||
mSocket.disconnect();
|
||||
mConnected = false;
|
||||
}
|
||||
|
||||
bool PvdDefaultSocketTransport::isConnected()
|
||||
{
|
||||
return mSocket.isConnected();
|
||||
}
|
||||
|
||||
bool PvdDefaultSocketTransport::write(const uint8_t* inBytes, uint32_t inLength)
|
||||
{
|
||||
if(mConnected)
|
||||
{
|
||||
if(inLength == 0)
|
||||
return true;
|
||||
|
||||
uint32_t amountWritten = 0;
|
||||
uint32_t totalWritten = 0;
|
||||
do
|
||||
{
|
||||
// Sockets don't have to write as much as requested, so we need
|
||||
// to wrap this call in a do/while loop.
|
||||
// If they don't write any bytes then we consider them disconnected.
|
||||
amountWritten = mSocket.write(inBytes, inLength);
|
||||
inLength -= amountWritten;
|
||||
inBytes += amountWritten;
|
||||
totalWritten += amountWritten;
|
||||
} while(inLength && amountWritten);
|
||||
|
||||
if(amountWritten == 0)
|
||||
return false;
|
||||
|
||||
mWrittenData += totalWritten;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
PxPvdTransport& PvdDefaultSocketTransport::lock()
|
||||
{
|
||||
mMutex.lock();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void PvdDefaultSocketTransport::unlock()
|
||||
{
|
||||
mMutex.unlock();
|
||||
}
|
||||
|
||||
void PvdDefaultSocketTransport::flush()
|
||||
{
|
||||
mSocket.flush();
|
||||
}
|
||||
|
||||
uint64_t PvdDefaultSocketTransport::getWrittenDataSize()
|
||||
{
|
||||
return mWrittenData;
|
||||
}
|
||||
|
||||
void PvdDefaultSocketTransport::release()
|
||||
{
|
||||
PX_DELETE(this);
|
||||
}
|
||||
|
||||
} // namespace pvdsdk
|
||||
|
||||
PxPvdTransport* PxDefaultPvdSocketTransportCreate(const char* host, int port, unsigned int timeoutInMilliseconds)
|
||||
{
|
||||
return PX_NEW(pvdsdk::PvdDefaultSocketTransport)(host, port, timeoutInMilliseconds);
|
||||
}
|
||||
|
||||
} // namespace physx
|
||||
79
physx/source/pvd/src/PxPvdDefaultSocketTransport.h
Normal file
79
physx/source/pvd/src/PxPvdDefaultSocketTransport.h
Normal file
@ -0,0 +1,79 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifndef PXPVDSDK_PXPVDDEFAULTSOCKETTRANSPORT_H
|
||||
#define PXPVDSDK_PXPVDDEFAULTSOCKETTRANSPORT_H
|
||||
|
||||
#include "pvd/PxPvdTransport.h"
|
||||
|
||||
#include "PsUserAllocated.h"
|
||||
#include "PsSocket.h"
|
||||
#include "PsMutex.h"
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace pvdsdk
|
||||
{
|
||||
class PvdDefaultSocketTransport : public PxPvdTransport, public shdfnd::UserAllocated
|
||||
{
|
||||
PX_NOCOPY(PvdDefaultSocketTransport)
|
||||
public:
|
||||
PvdDefaultSocketTransport(const char* host, int port, unsigned int timeoutInMilliseconds);
|
||||
virtual ~PvdDefaultSocketTransport();
|
||||
|
||||
virtual bool connect();
|
||||
virtual void disconnect();
|
||||
virtual bool isConnected();
|
||||
|
||||
virtual bool write(const uint8_t* inBytes, uint32_t inLength);
|
||||
|
||||
virtual void flush();
|
||||
|
||||
virtual PxPvdTransport& lock();
|
||||
virtual void unlock();
|
||||
|
||||
virtual uint64_t getWrittenDataSize();
|
||||
|
||||
virtual void release();
|
||||
|
||||
private:
|
||||
shdfnd::Socket mSocket;
|
||||
const char* mHost;
|
||||
uint16_t mPort;
|
||||
unsigned int mTimeout;
|
||||
bool mConnected;
|
||||
uint64_t mWrittenData;
|
||||
shdfnd::Mutex mMutex;
|
||||
bool mlocked;
|
||||
};
|
||||
|
||||
} // pvdsdk
|
||||
} // physx
|
||||
|
||||
#endif // PXPVDSDK_PXPVDDEFAULTSOCKETTRANSPORT_H
|
||||
318
physx/source/pvd/src/PxPvdFoundation.h
Normal file
318
physx/source/pvd/src/PxPvdFoundation.h
Normal file
@ -0,0 +1,318 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef PXPVDSDK_PXPVDFOUNDATION_H
|
||||
#define PXPVDSDK_PXPVDFOUNDATION_H
|
||||
|
||||
#include "foundation/PxVec3.h"
|
||||
#include "foundation/PxTransform.h"
|
||||
#include "foundation/PxBounds3.h"
|
||||
|
||||
#include "PsArray.h"
|
||||
#include "PsHashMap.h"
|
||||
#include "PsHashSet.h"
|
||||
#include "PsPool.h"
|
||||
#include "PsString.h"
|
||||
|
||||
#include "PxPvdObjectModelBaseTypes.h"
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace pvdsdk
|
||||
{
|
||||
|
||||
extern PxAllocatorCallback* gPvdAllocatorCallback;
|
||||
|
||||
class ForwardingAllocator : public PxAllocatorCallback
|
||||
{
|
||||
void* allocate(size_t size, const char* typeName, const char* filename, int line)
|
||||
{
|
||||
return shdfnd::getAllocator().allocate(size, typeName, filename, line);
|
||||
}
|
||||
void deallocate(void* ptr)
|
||||
{
|
||||
shdfnd::getAllocator().deallocate(ptr);
|
||||
}
|
||||
};
|
||||
|
||||
class RawMemoryBuffer
|
||||
{
|
||||
uint8_t* mBegin;
|
||||
uint8_t* mEnd;
|
||||
uint8_t* mCapacityEnd;
|
||||
const char* mBufDataName;
|
||||
|
||||
public:
|
||||
RawMemoryBuffer(const char* name) : mBegin(0), mEnd(0), mCapacityEnd(0),mBufDataName(name)
|
||||
{
|
||||
PX_UNUSED(mBufDataName);
|
||||
}
|
||||
~RawMemoryBuffer()
|
||||
{
|
||||
if(mBegin)
|
||||
PX_FREE(mBegin);
|
||||
}
|
||||
uint32_t size() const
|
||||
{
|
||||
return static_cast<uint32_t>(mEnd - mBegin);
|
||||
}
|
||||
uint32_t capacity() const
|
||||
{
|
||||
return static_cast<uint32_t>(mCapacityEnd - mBegin);
|
||||
}
|
||||
uint8_t* begin()
|
||||
{
|
||||
return mBegin;
|
||||
}
|
||||
uint8_t* end()
|
||||
{
|
||||
return mEnd;
|
||||
}
|
||||
const uint8_t* begin() const
|
||||
{
|
||||
return mBegin;
|
||||
}
|
||||
const uint8_t* end() const
|
||||
{
|
||||
return mEnd;
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
mEnd = mBegin;
|
||||
}
|
||||
const char* cStr()
|
||||
{
|
||||
if(mEnd && (*mEnd != 0))
|
||||
write(0);
|
||||
return reinterpret_cast<const char*>(mBegin);
|
||||
}
|
||||
uint32_t write(uint8_t inValue)
|
||||
{
|
||||
*growBuf(1) = inValue;
|
||||
return 1;
|
||||
}
|
||||
|
||||
template <typename TDataType>
|
||||
uint32_t write(const TDataType& inValue)
|
||||
{
|
||||
const uint8_t* __restrict readPtr = reinterpret_cast<const uint8_t*>(&inValue);
|
||||
uint8_t* __restrict writePtr = growBuf(sizeof(TDataType));
|
||||
for(uint32_t idx = 0; idx < sizeof(TDataType); ++idx)
|
||||
writePtr[idx] = readPtr[idx];
|
||||
return sizeof(TDataType);
|
||||
}
|
||||
|
||||
template <typename TDataType>
|
||||
uint32_t write(const TDataType* inValue, uint32_t inLength)
|
||||
{
|
||||
uint32_t writeSize = inLength * sizeof(TDataType);
|
||||
if(inValue && inLength)
|
||||
{
|
||||
physx::intrinsics::memCopy(growBuf(writeSize), inValue, writeSize);
|
||||
}
|
||||
if(inLength && !inValue)
|
||||
{
|
||||
PX_ASSERT(false);
|
||||
// You can't not write something, because that will cause
|
||||
// the receiving end to crash.
|
||||
for(uint32_t idx = 0; idx < writeSize; ++idx)
|
||||
write(0);
|
||||
}
|
||||
return writeSize;
|
||||
}
|
||||
|
||||
uint8_t* growBuf(uint32_t inAmount)
|
||||
{
|
||||
uint32_t offset = size();
|
||||
uint32_t newSize = offset + inAmount;
|
||||
reserve(newSize);
|
||||
mEnd += inAmount;
|
||||
return mBegin + offset;
|
||||
}
|
||||
void writeZeros(uint32_t inAmount)
|
||||
{
|
||||
uint32_t offset = size();
|
||||
growBuf(inAmount);
|
||||
physx::intrinsics::memZero(begin() + offset, inAmount);
|
||||
}
|
||||
void reserve(uint32_t newSize)
|
||||
{
|
||||
uint32_t currentSize = size();
|
||||
if(newSize && newSize >= capacity())
|
||||
{
|
||||
uint32_t newDataSize = newSize > 4096 ? newSize + (newSize >> 2) : newSize*2;
|
||||
uint8_t* newData = static_cast<uint8_t*>(PX_ALLOC(newDataSize, mBufDataName));
|
||||
if(mBegin)
|
||||
{
|
||||
physx::intrinsics::memCopy(newData, mBegin, currentSize);
|
||||
PX_FREE(mBegin);
|
||||
}
|
||||
mBegin = newData;
|
||||
mEnd = mBegin + currentSize;
|
||||
mCapacityEnd = mBegin + newDataSize;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct ForwardingMemoryBuffer : public RawMemoryBuffer
|
||||
{
|
||||
ForwardingMemoryBuffer(const char* bufDataName) : RawMemoryBuffer(bufDataName)
|
||||
{
|
||||
}
|
||||
|
||||
ForwardingMemoryBuffer& operator<<(const char* inString)
|
||||
{
|
||||
if(inString && *inString)
|
||||
{
|
||||
uint32_t len = static_cast<uint32_t>(strlen(inString));
|
||||
write(inString, len);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename TDataType>
|
||||
inline ForwardingMemoryBuffer& toStream(const char* inFormat, const TDataType inData)
|
||||
{
|
||||
char buffer[128] = { 0 };
|
||||
shdfnd::snprintf(buffer, 128, inFormat, inData);
|
||||
*this << buffer;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline ForwardingMemoryBuffer& operator<<(bool inData)
|
||||
{
|
||||
*this << (inData ? "true" : "false");
|
||||
return *this;
|
||||
}
|
||||
inline ForwardingMemoryBuffer& operator<<(int32_t inData)
|
||||
{
|
||||
return toStream("%d", inData);
|
||||
}
|
||||
inline ForwardingMemoryBuffer& operator<<(uint16_t inData)
|
||||
{
|
||||
return toStream("%u", uint32_t(inData));
|
||||
}
|
||||
inline ForwardingMemoryBuffer& operator<<(uint8_t inData)
|
||||
{
|
||||
return toStream("%u", uint32_t(inData));
|
||||
}
|
||||
inline ForwardingMemoryBuffer& operator<<(char inData)
|
||||
{
|
||||
return toStream("%c", inData);
|
||||
}
|
||||
inline ForwardingMemoryBuffer& operator<<(uint32_t inData)
|
||||
{
|
||||
return toStream("%u", inData);
|
||||
}
|
||||
inline ForwardingMemoryBuffer& operator<<(uint64_t inData)
|
||||
{
|
||||
return toStream("%I64u", inData);
|
||||
}
|
||||
inline ForwardingMemoryBuffer& operator<<(int64_t inData)
|
||||
{
|
||||
return toStream("%I64d", inData);
|
||||
}
|
||||
inline ForwardingMemoryBuffer& operator<<(const void* inData)
|
||||
{
|
||||
return *this << static_cast<uint64_t>(reinterpret_cast<size_t>(inData));
|
||||
}
|
||||
inline ForwardingMemoryBuffer& operator<<(float inData)
|
||||
{
|
||||
return toStream("%g", double(inData));
|
||||
}
|
||||
inline ForwardingMemoryBuffer& operator<<(double inData)
|
||||
{
|
||||
return toStream("%g", inData);
|
||||
}
|
||||
inline ForwardingMemoryBuffer& operator<<(const PxVec3& inData)
|
||||
{
|
||||
*this << inData[0];
|
||||
*this << " ";
|
||||
*this << inData[1];
|
||||
*this << " ";
|
||||
*this << inData[2];
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline ForwardingMemoryBuffer& operator<<(const PxQuat& inData)
|
||||
{
|
||||
*this << inData.x;
|
||||
*this << " ";
|
||||
*this << inData.y;
|
||||
*this << " ";
|
||||
*this << inData.z;
|
||||
*this << " ";
|
||||
*this << inData.w;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline ForwardingMemoryBuffer& operator<<(const PxTransform& inData)
|
||||
{
|
||||
*this << inData.q;
|
||||
*this << " ";
|
||||
*this << inData.p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline ForwardingMemoryBuffer& operator<<(const PxBounds3& inData)
|
||||
{
|
||||
*this << inData.minimum;
|
||||
*this << " ";
|
||||
*this << inData.maximum;
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename TDataType>
|
||||
inline void* PvdAllocate(const char* typeName, const char* file, int line)
|
||||
{
|
||||
PX_ASSERT(gPvdAllocatorCallback);
|
||||
return gPvdAllocatorCallback->allocate(sizeof(TDataType), typeName, file, line);
|
||||
}
|
||||
|
||||
template <typename TDataType>
|
||||
inline void PvdDeleteAndDeallocate(TDataType* inDType)
|
||||
{
|
||||
PX_ASSERT(gPvdAllocatorCallback);
|
||||
if(inDType)
|
||||
{
|
||||
inDType->~TDataType();
|
||||
gPvdAllocatorCallback->deallocate(inDType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define PVD_NEW(dtype) new (PvdAllocate<dtype>(#dtype, __FILE__, __LINE__)) dtype
|
||||
#define PVD_DELETE(obj) PvdDeleteAndDeallocate(obj);
|
||||
//#define PVD_NEW(dtype) PX_NEW(dtype)
|
||||
//#define PVD_DELETE(obj) PX_DELETE(obj)
|
||||
#define PVD_FOREACH(varname, stop) for(uint32_t varname = 0; varname < stop; ++varname)
|
||||
#define PVD_POINTER_TO_U64(ptr) static_cast<uint64_t>(reinterpret_cast<size_t>(ptr))
|
||||
|
||||
#endif // PXPVDSDK_PXPVDFOUNDATION_H
|
||||
399
physx/source/pvd/src/PxPvdImpl.cpp
Normal file
399
physx/source/pvd/src/PxPvdImpl.cpp
Normal file
@ -0,0 +1,399 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#include "PxPvdImpl.h"
|
||||
#include "PxPvdMemClient.h"
|
||||
#include "PxPvdProfileZoneClient.h"
|
||||
#include "PxPvdProfileZone.h"
|
||||
|
||||
#include "PsFoundation.h"
|
||||
|
||||
#if PX_NVTX
|
||||
#include "nvToolsExt.h"
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
const char* gSdkName = "PhysXSDK";
|
||||
}
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace pvdsdk
|
||||
{
|
||||
|
||||
class CmEventNameProvider : public physx::profile::PxProfileNameProvider
|
||||
{
|
||||
public:
|
||||
physx::profile::PxProfileNames getProfileNames() const
|
||||
{
|
||||
physx::profile::PxProfileNames ret;
|
||||
ret.eventCount = 0;
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
CmEventNameProvider gProfileNameProvider;
|
||||
|
||||
void initializeModelTypes(PvdDataStream& stream)
|
||||
{
|
||||
stream.createClass<profile::PxProfileZone>();
|
||||
stream.createProperty<profile::PxProfileZone, uint8_t>(
|
||||
"events", PvdCommStreamEmbeddedTypes::getProfileEventStreamSemantic(), PropertyType::Array);
|
||||
|
||||
stream.createClass<profile::PxProfileMemoryEventBuffer>();
|
||||
stream.createProperty<profile::PxProfileMemoryEventBuffer, uint8_t>(
|
||||
"events", PvdCommStreamEmbeddedTypes::getMemoryEventStreamSemantic(), PropertyType::Array);
|
||||
|
||||
stream.createClass<PvdUserRenderer>();
|
||||
stream.createProperty<PvdUserRenderer, uint8_t>(
|
||||
"events", PvdCommStreamEmbeddedTypes::getRendererEventStreamSemantic(), PropertyType::Array);
|
||||
}
|
||||
|
||||
PvdImpl* PvdImpl::sInstance = NULL;
|
||||
uint32_t PvdImpl::sRefCount = 0;
|
||||
|
||||
PvdImpl::PvdImpl()
|
||||
: mPvdTransport(NULL)
|
||||
, mSharedMetaProvider(NULL)
|
||||
, mMemClient(NULL)
|
||||
, mIsConnected(false)
|
||||
, mIsNVTXSupportEnabled(true)
|
||||
, mNVTXContext(0)
|
||||
, mNextStreamId(1)
|
||||
, mProfileClient(NULL)
|
||||
, mProfileZone(NULL)
|
||||
{
|
||||
mProfileZoneManager = &physx::profile::PxProfileZoneManager::createProfileZoneManager(&physx::shdfnd::getAllocator());
|
||||
mProfileClient = PVD_NEW(PvdProfileZoneClient)(*this);
|
||||
}
|
||||
|
||||
PvdImpl::~PvdImpl()
|
||||
{
|
||||
if((mFlags & PxPvdInstrumentationFlag::ePROFILE) )
|
||||
{
|
||||
PxSetProfilerCallback(NULL);
|
||||
}
|
||||
|
||||
disconnect();
|
||||
|
||||
if ( mProfileZoneManager )
|
||||
{
|
||||
mProfileZoneManager->release();
|
||||
mProfileZoneManager = NULL;
|
||||
}
|
||||
|
||||
PVD_DELETE(mProfileClient);
|
||||
mProfileClient = NULL;
|
||||
}
|
||||
|
||||
bool PvdImpl::connect(PxPvdTransport& transport, PxPvdInstrumentationFlags flags)
|
||||
{
|
||||
if(mIsConnected)
|
||||
{
|
||||
physx::shdfnd::getFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "PxPvd::connect - recall connect! Should call disconnect before re-connect.");
|
||||
return false;
|
||||
}
|
||||
|
||||
mFlags = flags;
|
||||
mPvdTransport = &transport;
|
||||
|
||||
mIsConnected = mPvdTransport->connect();
|
||||
|
||||
if(mIsConnected)
|
||||
{
|
||||
mSharedMetaProvider = PVD_NEW(MetaDataProvider);
|
||||
sendTransportInitialization();
|
||||
|
||||
PvdDataStream* stream = PvdDataStream::create(this);
|
||||
initializeModelTypes(*stream);
|
||||
stream->release();
|
||||
|
||||
if(mFlags & PxPvdInstrumentationFlag::eMEMORY)
|
||||
{
|
||||
mMemClient = PVD_NEW(PvdMemClient)(*this);
|
||||
mPvdClients.pushBack(mMemClient);
|
||||
}
|
||||
|
||||
if((mFlags & PxPvdInstrumentationFlag::ePROFILE) && mProfileZoneManager)
|
||||
{
|
||||
mPvdClients.pushBack(mProfileClient);
|
||||
mProfileZone = &physx::profile::PxProfileZone::createProfileZone(&physx::shdfnd::getAllocator(),gSdkName,gProfileNameProvider.getProfileNames());
|
||||
}
|
||||
|
||||
for(uint32_t i = 0; i < mPvdClients.size(); i++)
|
||||
mPvdClients[i]->onPvdConnected();
|
||||
|
||||
if (mProfileZone)
|
||||
{
|
||||
mProfileZoneManager->addProfileZoneHandler(*mProfileClient);
|
||||
mProfileZoneManager->addProfileZone( *mProfileZone );
|
||||
}
|
||||
|
||||
if ((mFlags & PxPvdInstrumentationFlag::ePROFILE))
|
||||
{
|
||||
PxSetProfilerCallback(this);
|
||||
}
|
||||
}
|
||||
return mIsConnected;
|
||||
}
|
||||
|
||||
void PvdImpl::disconnect()
|
||||
{
|
||||
if(mProfileZone)
|
||||
{
|
||||
mProfileZoneManager->removeProfileZoneHandler(*mProfileClient);
|
||||
mProfileZoneManager->removeProfileZone( *mProfileZone );
|
||||
mProfileZone->release();
|
||||
mProfileZone=NULL;
|
||||
removeClient(mProfileClient);
|
||||
}
|
||||
|
||||
if(mIsConnected)
|
||||
{
|
||||
for(uint32_t i = 0; i < mPvdClients.size(); i++)
|
||||
mPvdClients[i]->onPvdDisconnected();
|
||||
|
||||
if(mMemClient)
|
||||
{
|
||||
removeClient(mMemClient);
|
||||
PvdMemClient* tmp = mMemClient; //avoid tracking deallocation itsself
|
||||
mMemClient = NULL;
|
||||
PVD_DELETE(tmp);
|
||||
}
|
||||
|
||||
mSharedMetaProvider->release();
|
||||
mPvdTransport->disconnect();
|
||||
mObjectRegistrar.clear();
|
||||
mIsConnected = false;
|
||||
}
|
||||
}
|
||||
|
||||
void PvdImpl::flush()
|
||||
{
|
||||
for(uint32_t i = 0; i < mPvdClients.size(); i++)
|
||||
mPvdClients[i]->flush();
|
||||
if ( mProfileZone )
|
||||
{
|
||||
mProfileZone->flushEventIdNameMap();
|
||||
mProfileZone->flushProfileEvents();
|
||||
}
|
||||
}
|
||||
|
||||
bool PvdImpl::isConnected(bool useCachedStatus)
|
||||
{
|
||||
if(mPvdTransport)
|
||||
return useCachedStatus ? mIsConnected : mPvdTransport->isConnected();
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
PxPvdTransport* PvdImpl::getTransport()
|
||||
{
|
||||
return mPvdTransport;
|
||||
}
|
||||
|
||||
PxPvdInstrumentationFlags PvdImpl::getInstrumentationFlags()
|
||||
{
|
||||
return mFlags;
|
||||
}
|
||||
|
||||
void PvdImpl::sendTransportInitialization()
|
||||
{
|
||||
StreamInitialization init;
|
||||
EventStreamifier<PxPvdTransport> stream(mPvdTransport->lock());
|
||||
init.serialize(stream);
|
||||
mPvdTransport->unlock();
|
||||
}
|
||||
|
||||
void PvdImpl::addClient(PvdClient* client)
|
||||
{
|
||||
PX_ASSERT(client);
|
||||
for(uint32_t i = 0; i < mPvdClients.size(); i++)
|
||||
{
|
||||
if(client == mPvdClients[i])
|
||||
return;
|
||||
}
|
||||
mPvdClients.pushBack(client);
|
||||
if(mIsConnected)
|
||||
{
|
||||
client->onPvdConnected();
|
||||
}
|
||||
}
|
||||
|
||||
void PvdImpl::removeClient(PvdClient* client)
|
||||
{
|
||||
for(uint32_t i = 0; i < mPvdClients.size(); i++)
|
||||
{
|
||||
if(client == mPvdClients[i])
|
||||
{
|
||||
client->onPvdDisconnected();
|
||||
mPvdClients.remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PvdImpl::onAllocation(size_t inSize, const char* inType, const char* inFile, int inLine, void* inAddr)
|
||||
{
|
||||
if(mMemClient)
|
||||
mMemClient->onAllocation(inSize, inType, inFile, inLine, inAddr);
|
||||
}
|
||||
|
||||
void PvdImpl::onDeallocation(void* inAddr)
|
||||
{
|
||||
if(mMemClient)
|
||||
mMemClient->onDeallocation(inAddr);
|
||||
}
|
||||
|
||||
PvdOMMetaDataProvider& PvdImpl::getMetaDataProvider()
|
||||
{
|
||||
return *mSharedMetaProvider;
|
||||
}
|
||||
|
||||
bool PvdImpl::registerObject(const void* inItem)
|
||||
{
|
||||
return mObjectRegistrar.addItem(inItem);
|
||||
}
|
||||
|
||||
|
||||
bool PvdImpl::unRegisterObject(const void* inItem)
|
||||
{
|
||||
return mObjectRegistrar.decItem(inItem);
|
||||
}
|
||||
|
||||
uint64_t PvdImpl::getNextStreamId()
|
||||
{
|
||||
uint64_t retval = ++mNextStreamId;
|
||||
return retval;
|
||||
}
|
||||
|
||||
bool PvdImpl::initialize()
|
||||
{
|
||||
if(0 == sRefCount)
|
||||
{
|
||||
sInstance = PVD_NEW(PvdImpl)();
|
||||
}
|
||||
++sRefCount;
|
||||
return !!sInstance;
|
||||
}
|
||||
|
||||
void PvdImpl::release()
|
||||
{
|
||||
if(sRefCount > 0)
|
||||
{
|
||||
if(--sRefCount)
|
||||
return;
|
||||
|
||||
PVD_DELETE(sInstance);
|
||||
sInstance = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
PvdImpl* PvdImpl::getInstance()
|
||||
{
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************************************************************
|
||||
Instrumented profiling events
|
||||
***************************************************************************************************************************/
|
||||
|
||||
static const uint32_t CrossThreadId = 99999789;
|
||||
|
||||
void* PvdImpl::zoneStart(const char* eventName, bool detached, uint64_t contextId)
|
||||
{
|
||||
if(mProfileZone)
|
||||
{
|
||||
const uint16_t id = mProfileZone->getEventIdForName(eventName);
|
||||
if(detached)
|
||||
mProfileZone->startEvent(id, contextId, CrossThreadId);
|
||||
else
|
||||
mProfileZone->startEvent(id, contextId);
|
||||
}
|
||||
#if PX_NVTX
|
||||
if(mIsNVTXSupportEnabled)
|
||||
{
|
||||
if(detached)
|
||||
{
|
||||
// TODO : Need to use the nvtxRangeStart API for cross thread events
|
||||
nvtxEventAttributes_t eventAttrib;
|
||||
memset(&eventAttrib, 0, sizeof(eventAttrib));
|
||||
eventAttrib.version = NVTX_VERSION;
|
||||
eventAttrib.size = NVTX_EVENT_ATTRIB_STRUCT_SIZE;
|
||||
eventAttrib.colorType = NVTX_COLOR_ARGB;
|
||||
eventAttrib.color = 0xFF00FF00;
|
||||
eventAttrib.messageType = NVTX_MESSAGE_TYPE_ASCII;
|
||||
eventAttrib.message.ascii = eventName;
|
||||
nvtxMarkEx(&eventAttrib);
|
||||
}
|
||||
else
|
||||
{
|
||||
nvtxRangePush(eventName);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void PvdImpl::zoneEnd(void* /*profilerData*/, const char* eventName, bool detached, uint64_t contextId)
|
||||
{
|
||||
if(mProfileZone)
|
||||
{
|
||||
const uint16_t id = mProfileZone->getEventIdForName(eventName);
|
||||
if(detached)
|
||||
mProfileZone->stopEvent(id, contextId, CrossThreadId);
|
||||
else
|
||||
mProfileZone->stopEvent(id, contextId);
|
||||
}
|
||||
#if PX_NVTX
|
||||
if(mIsNVTXSupportEnabled)
|
||||
{
|
||||
if(detached)
|
||||
{
|
||||
nvtxEventAttributes_t eventAttrib;
|
||||
memset(&eventAttrib, 0, sizeof(eventAttrib));
|
||||
eventAttrib.version = NVTX_VERSION;
|
||||
eventAttrib.size = NVTX_EVENT_ATTRIB_STRUCT_SIZE;
|
||||
eventAttrib.colorType = NVTX_COLOR_ARGB;
|
||||
eventAttrib.color = 0xFFFF0000;
|
||||
eventAttrib.messageType = NVTX_MESSAGE_TYPE_ASCII;
|
||||
eventAttrib.message.ascii = eventName;
|
||||
nvtxMarkEx(&eventAttrib);
|
||||
}
|
||||
else
|
||||
{
|
||||
nvtxRangePop();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} // pvd
|
||||
|
||||
} // physx
|
||||
221
physx/source/pvd/src/PxPvdImpl.h
Normal file
221
physx/source/pvd/src/PxPvdImpl.h
Normal file
@ -0,0 +1,221 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifndef PXPVDSDK_PXPVDIMPL_H
|
||||
#define PXPVDSDK_PXPVDIMPL_H
|
||||
|
||||
#include "foundation/PxProfiler.h"
|
||||
|
||||
#include "PsAllocator.h"
|
||||
#include "PsPvd.h"
|
||||
#include "PsArray.h"
|
||||
#include "PsMutex.h"
|
||||
#include "PxPvdCommStreamTypes.h"
|
||||
#include "PxPvdFoundation.h"
|
||||
#include "PxPvdObjectModelMetaData.h"
|
||||
#include "PxPvdObjectRegistrar.h"
|
||||
|
||||
namespace physx
|
||||
{
|
||||
|
||||
namespace profile
|
||||
{
|
||||
class PxProfileZoneManager;
|
||||
}
|
||||
|
||||
namespace pvdsdk
|
||||
{
|
||||
class PvdMemClient;
|
||||
class PvdProfileZoneClient;
|
||||
|
||||
struct MetaDataProvider : public PvdOMMetaDataProvider, public shdfnd::UserAllocated
|
||||
{
|
||||
typedef shdfnd::Mutex::ScopedLock TScopedLockType;
|
||||
typedef shdfnd::HashMap<const void*, int32_t> TInstTypeMap;
|
||||
PvdObjectModelMetaData& mMetaData;
|
||||
shdfnd::Mutex mMutex;
|
||||
uint32_t mRefCount;
|
||||
TInstTypeMap mTypeMap;
|
||||
|
||||
MetaDataProvider()
|
||||
: mMetaData(PvdObjectModelMetaData::create()), mRefCount(0), mTypeMap("MetaDataProvider::mTypeMap")
|
||||
{
|
||||
mMetaData.addRef();
|
||||
}
|
||||
virtual ~MetaDataProvider()
|
||||
{
|
||||
mMetaData.release();
|
||||
}
|
||||
|
||||
virtual void addRef()
|
||||
{
|
||||
TScopedLockType locker(mMutex);
|
||||
++mRefCount;
|
||||
}
|
||||
virtual void release()
|
||||
{
|
||||
{
|
||||
TScopedLockType locker(mMutex);
|
||||
if(mRefCount)
|
||||
--mRefCount;
|
||||
}
|
||||
if(!mRefCount)
|
||||
PVD_DELETE(this);
|
||||
}
|
||||
virtual PvdObjectModelMetaData& lock()
|
||||
{
|
||||
mMutex.lock();
|
||||
return mMetaData;
|
||||
}
|
||||
virtual void unlock()
|
||||
{
|
||||
mMutex.unlock();
|
||||
}
|
||||
|
||||
virtual bool createInstance(const NamespacedName& clsName, const void* instance)
|
||||
{
|
||||
TScopedLockType locker(mMutex);
|
||||
Option<ClassDescription> cls(mMetaData.findClass(clsName));
|
||||
if(cls.hasValue() == false)
|
||||
return false;
|
||||
int32_t instType = cls->mClassId;
|
||||
mTypeMap.insert(instance, instType);
|
||||
return true;
|
||||
}
|
||||
virtual bool isInstanceValid(const void* instance)
|
||||
{
|
||||
TScopedLockType locker(mMutex);
|
||||
ClassDescription classDesc;
|
||||
bool retval = mTypeMap.find(instance) != NULL;
|
||||
#if PX_DEBUG
|
||||
if(retval)
|
||||
classDesc = mMetaData.getClass(mTypeMap.find(instance)->second);
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
virtual void destroyInstance(const void* instance)
|
||||
{
|
||||
{
|
||||
TScopedLockType locker(mMutex);
|
||||
mTypeMap.erase(instance);
|
||||
}
|
||||
}
|
||||
virtual int32_t getInstanceClassType(const void* instance)
|
||||
{
|
||||
TScopedLockType locker(mMutex);
|
||||
const TInstTypeMap::Entry* entry = mTypeMap.find(instance);
|
||||
if(entry)
|
||||
return entry->second;
|
||||
return -1;
|
||||
}
|
||||
|
||||
private:
|
||||
MetaDataProvider& operator=(const MetaDataProvider&);
|
||||
MetaDataProvider(const MetaDataProvider&);
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
/*!
|
||||
PvdImpl is the realization of PxPvd.
|
||||
It implements the interface methods and provides richer functionality for advanced users or internal clients (such as
|
||||
PhysX or APEX), including handler notification for clients.
|
||||
*/
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class PvdImpl : public PsPvd, public shdfnd::UserAllocated
|
||||
{
|
||||
PX_NOCOPY(PvdImpl)
|
||||
|
||||
typedef shdfnd::Mutex::ScopedLock TScopedLockType;
|
||||
typedef void (PvdImpl::*TAllocationHandler)(size_t size, const char* typeName, const char* filename, int line,
|
||||
void* allocatedMemory);
|
||||
typedef void (PvdImpl::*TDeallocationHandler)(void* allocatedMemory);
|
||||
|
||||
public:
|
||||
PvdImpl();
|
||||
virtual ~PvdImpl();
|
||||
void release();
|
||||
|
||||
bool connect(PxPvdTransport& transport, PxPvdInstrumentationFlags flags);
|
||||
void disconnect();
|
||||
bool isConnected(bool useCachedStatus = true);
|
||||
void flush();
|
||||
|
||||
PxPvdTransport* getTransport();
|
||||
PxPvdInstrumentationFlags getInstrumentationFlags();
|
||||
|
||||
void addClient(PvdClient* client);
|
||||
void removeClient(PvdClient* client);
|
||||
|
||||
PvdOMMetaDataProvider& getMetaDataProvider();
|
||||
|
||||
bool registerObject(const void* inItem);
|
||||
bool unRegisterObject(const void* inItem);
|
||||
|
||||
//AllocationListener
|
||||
void onAllocation(size_t size, const char* typeName, const char* filename, int line, void* allocatedMemory);
|
||||
void onDeallocation(void* addr);
|
||||
|
||||
uint64_t getNextStreamId();
|
||||
|
||||
static bool initialize();
|
||||
static PvdImpl* getInstance();
|
||||
|
||||
// Profiling
|
||||
|
||||
virtual void* zoneStart(const char* eventName, bool detached, uint64_t contextId);
|
||||
|
||||
virtual void zoneEnd(void* profilerData, const char *eventName, bool detached, uint64_t contextId);
|
||||
|
||||
private:
|
||||
void sendTransportInitialization();
|
||||
|
||||
PxPvdTransport* mPvdTransport;
|
||||
physx::shdfnd::Array<PvdClient*> mPvdClients;
|
||||
|
||||
MetaDataProvider* mSharedMetaProvider; // shared between clients
|
||||
ObjectRegistrar mObjectRegistrar;
|
||||
|
||||
PvdMemClient* mMemClient;
|
||||
|
||||
PxPvdInstrumentationFlags mFlags;
|
||||
bool mIsConnected;
|
||||
bool mIsNVTXSupportEnabled;
|
||||
uint32_t mNVTXContext;
|
||||
uint64_t mNextStreamId;
|
||||
physx::profile::PxProfileZoneManager*mProfileZoneManager;
|
||||
PvdProfileZoneClient* mProfileClient;
|
||||
physx::profile::PxProfileZone* mProfileZone;
|
||||
static PvdImpl* sInstance;
|
||||
static uint32_t sRefCount;
|
||||
};
|
||||
|
||||
} // namespace pvdsdk
|
||||
}
|
||||
|
||||
#endif // PXPVDSDK_PXPVDIMPL_H
|
||||
99
physx/source/pvd/src/PxPvdInternalByteStreams.h
Normal file
99
physx/source/pvd/src/PxPvdInternalByteStreams.h
Normal file
@ -0,0 +1,99 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef PXPVDSDK_PXPVDINTERNALBYTESTREAMS_H
|
||||
#define PXPVDSDK_PXPVDINTERNALBYTESTREAMS_H
|
||||
|
||||
#include "PxPvdByteStreams.h"
|
||||
#include "PxPvdFoundation.h"
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace pvdsdk
|
||||
{
|
||||
struct MemPvdInputStream : public PvdInputStream
|
||||
{
|
||||
const uint8_t* mBegin;
|
||||
const uint8_t* mEnd;
|
||||
bool mGood;
|
||||
|
||||
MemPvdInputStream(const uint8_t* beg = NULL, const uint8_t* end = NULL)
|
||||
{
|
||||
mBegin = beg;
|
||||
mEnd = end;
|
||||
mGood = true;
|
||||
}
|
||||
|
||||
uint32_t size() const
|
||||
{
|
||||
return mGood ? static_cast<uint32_t>(mEnd - mBegin) : 0;
|
||||
}
|
||||
bool isGood() const
|
||||
{
|
||||
return mGood;
|
||||
}
|
||||
|
||||
void setup(uint8_t* start, uint8_t* stop)
|
||||
{
|
||||
mBegin = start;
|
||||
mEnd = stop;
|
||||
}
|
||||
|
||||
void nocopyRead(uint8_t*& buffer, uint32_t& len)
|
||||
{
|
||||
if(len == 0 || mGood == false)
|
||||
{
|
||||
len = 0;
|
||||
buffer = NULL;
|
||||
return;
|
||||
}
|
||||
uint32_t original = len;
|
||||
len = PxMin(len, size());
|
||||
if(mGood && len != original)
|
||||
mGood = false;
|
||||
buffer = const_cast<uint8_t*>(mBegin);
|
||||
mBegin += len;
|
||||
}
|
||||
|
||||
virtual bool read(uint8_t* buffer, uint32_t& len)
|
||||
{
|
||||
if(len == 0)
|
||||
return true;
|
||||
uint32_t original = len;
|
||||
len = PxMin(len, size());
|
||||
|
||||
physx::intrinsics::memCopy(buffer, mBegin, len);
|
||||
mBegin += len;
|
||||
if(len < original)
|
||||
physx::intrinsics::memZero(buffer + len, original - len);
|
||||
mGood = mGood && len == original;
|
||||
return mGood;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif // PXPVDSDK_PXPVDINTERNALBYTESTREAMS_H
|
||||
220
physx/source/pvd/src/PxPvdMarshalling.h
Normal file
220
physx/source/pvd/src/PxPvdMarshalling.h
Normal file
@ -0,0 +1,220 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef PXPVDSDK_PXPVDMARSHALLING_H
|
||||
#define PXPVDSDK_PXPVDMARSHALLING_H
|
||||
|
||||
#include "foundation/PxIntrinsics.h"
|
||||
|
||||
#include "PxPvdObjectModelBaseTypes.h"
|
||||
#include "PxPvdBits.h"
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace pvdsdk
|
||||
{
|
||||
|
||||
// Define marshalling
|
||||
|
||||
template <typename TSmallerType, typename TLargerType>
|
||||
struct PvdMarshalling
|
||||
{
|
||||
bool canMarshal;
|
||||
PvdMarshalling() : canMarshal(false)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename smtype, typename lgtype>
|
||||
static inline void marshalSingleT(const uint8_t* srcData, uint8_t* destData)
|
||||
{
|
||||
smtype incoming;
|
||||
|
||||
physx::intrinsics::memCopy(&incoming, srcData, sizeof(smtype));
|
||||
lgtype outgoing = static_cast<lgtype>(incoming);
|
||||
physx::intrinsics::memCopy(destData, &outgoing, sizeof(lgtype));
|
||||
}
|
||||
|
||||
template <typename smtype, typename lgtype>
|
||||
static inline void marshalBlockT(const uint8_t* srcData, uint8_t* destData, uint32_t numBytes)
|
||||
{
|
||||
for(const uint8_t* item = srcData, *end = srcData + numBytes; item < end;
|
||||
item += sizeof(smtype), destData += sizeof(lgtype))
|
||||
marshalSingleT<smtype, lgtype>(item, destData);
|
||||
}
|
||||
|
||||
#define PVD_TYPE_MARSHALLER(smtype, lgtype) \
|
||||
template <> \
|
||||
struct PvdMarshalling<smtype, lgtype> \
|
||||
{ \
|
||||
uint32_t canMarshal; \
|
||||
static void marshalSingle(const uint8_t* srcData, uint8_t* destData) \
|
||||
{ \
|
||||
marshalSingleT<smtype, lgtype>(srcData, destData); \
|
||||
} \
|
||||
static void marshalBlock(const uint8_t* srcData, uint8_t* destData, uint32_t numBytes) \
|
||||
{ \
|
||||
marshalBlockT<smtype, lgtype>(srcData, destData, numBytes); \
|
||||
} \
|
||||
};
|
||||
|
||||
// define marshalling tables.
|
||||
PVD_TYPE_MARSHALLER(int8_t, int16_t)
|
||||
PVD_TYPE_MARSHALLER(int8_t, uint16_t)
|
||||
PVD_TYPE_MARSHALLER(int8_t, int32_t)
|
||||
PVD_TYPE_MARSHALLER(int8_t, uint32_t)
|
||||
PVD_TYPE_MARSHALLER(int8_t, int64_t)
|
||||
PVD_TYPE_MARSHALLER(int8_t, uint64_t)
|
||||
PVD_TYPE_MARSHALLER(int8_t, PvdF32)
|
||||
PVD_TYPE_MARSHALLER(int8_t, PvdF64)
|
||||
|
||||
PVD_TYPE_MARSHALLER(uint8_t, int16_t)
|
||||
PVD_TYPE_MARSHALLER(uint8_t, uint16_t)
|
||||
PVD_TYPE_MARSHALLER(uint8_t, int32_t)
|
||||
PVD_TYPE_MARSHALLER(uint8_t, uint32_t)
|
||||
PVD_TYPE_MARSHALLER(uint8_t, int64_t)
|
||||
PVD_TYPE_MARSHALLER(uint8_t, uint64_t)
|
||||
PVD_TYPE_MARSHALLER(uint8_t, PvdF32)
|
||||
PVD_TYPE_MARSHALLER(uint8_t, PvdF64)
|
||||
|
||||
PVD_TYPE_MARSHALLER(int16_t, int32_t)
|
||||
PVD_TYPE_MARSHALLER(int16_t, uint32_t)
|
||||
PVD_TYPE_MARSHALLER(int16_t, int64_t)
|
||||
PVD_TYPE_MARSHALLER(int16_t, uint64_t)
|
||||
PVD_TYPE_MARSHALLER(int16_t, PvdF32)
|
||||
PVD_TYPE_MARSHALLER(int16_t, PvdF64)
|
||||
|
||||
PVD_TYPE_MARSHALLER(uint16_t, int32_t)
|
||||
PVD_TYPE_MARSHALLER(uint16_t, uint32_t)
|
||||
PVD_TYPE_MARSHALLER(uint16_t, int64_t)
|
||||
PVD_TYPE_MARSHALLER(uint16_t, uint64_t)
|
||||
PVD_TYPE_MARSHALLER(uint16_t, PvdF32)
|
||||
PVD_TYPE_MARSHALLER(uint16_t, PvdF64)
|
||||
|
||||
PVD_TYPE_MARSHALLER(int32_t, int64_t)
|
||||
PVD_TYPE_MARSHALLER(int32_t, uint64_t)
|
||||
PVD_TYPE_MARSHALLER(int32_t, PvdF64)
|
||||
PVD_TYPE_MARSHALLER(int32_t, PvdF32)
|
||||
|
||||
PVD_TYPE_MARSHALLER(uint32_t, int64_t)
|
||||
PVD_TYPE_MARSHALLER(uint32_t, uint64_t)
|
||||
PVD_TYPE_MARSHALLER(uint32_t, PvdF64)
|
||||
PVD_TYPE_MARSHALLER(uint32_t, PvdF32)
|
||||
|
||||
PVD_TYPE_MARSHALLER(PvdF32, PvdF64)
|
||||
PVD_TYPE_MARSHALLER(PvdF32, uint32_t)
|
||||
PVD_TYPE_MARSHALLER(PvdF32, int32_t)
|
||||
|
||||
PVD_TYPE_MARSHALLER(uint64_t, PvdF64)
|
||||
PVD_TYPE_MARSHALLER(int64_t, PvdF64)
|
||||
PVD_TYPE_MARSHALLER(PvdF64, uint64_t)
|
||||
PVD_TYPE_MARSHALLER(PvdF64, int64_t)
|
||||
|
||||
template <typename TMarshaller>
|
||||
static inline bool getMarshalOperators(TSingleMarshaller&, TBlockMarshaller&, TMarshaller&, bool)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename TMarshaller>
|
||||
static inline bool getMarshalOperators(TSingleMarshaller& single, TBlockMarshaller& block, TMarshaller&, uint32_t)
|
||||
{
|
||||
single = TMarshaller::marshalSingle;
|
||||
block = TMarshaller::marshalBlock;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename smtype, typename lgtype>
|
||||
static inline bool getMarshalOperators(TSingleMarshaller& single, TBlockMarshaller& block)
|
||||
{
|
||||
single = NULL;
|
||||
block = NULL;
|
||||
PvdMarshalling<smtype, lgtype> marshaller = PvdMarshalling<smtype, lgtype>();
|
||||
return getMarshalOperators(single, block, marshaller, marshaller.canMarshal);
|
||||
}
|
||||
|
||||
template <typename smtype>
|
||||
static inline bool getMarshalOperators(TSingleMarshaller& single, TBlockMarshaller& block, int32_t lgtypeId)
|
||||
{
|
||||
switch(lgtypeId)
|
||||
{
|
||||
case PvdBaseType::PvdI8: // int8_t:
|
||||
return getMarshalOperators<smtype, int8_t>(single, block);
|
||||
case PvdBaseType::PvdU8: // uint8_t:
|
||||
return getMarshalOperators<smtype, uint8_t>(single, block);
|
||||
case PvdBaseType::PvdI16: // int16_t:
|
||||
return getMarshalOperators<smtype, int16_t>(single, block);
|
||||
case PvdBaseType::PvdU16: // uint16_t:
|
||||
return getMarshalOperators<smtype, uint16_t>(single, block);
|
||||
case PvdBaseType::PvdI32: // int32_t:
|
||||
return getMarshalOperators<smtype, int32_t>(single, block);
|
||||
case PvdBaseType::PvdU32: // uint32_t:
|
||||
return getMarshalOperators<smtype, uint32_t>(single, block);
|
||||
case PvdBaseType::PvdI64: // int64_t:
|
||||
return getMarshalOperators<smtype, int64_t>(single, block);
|
||||
case PvdBaseType::PvdU64: // uint64_t:
|
||||
return getMarshalOperators<smtype, uint64_t>(single, block);
|
||||
case PvdBaseType::PvdF32:
|
||||
return getMarshalOperators<smtype, PvdF32>(single, block);
|
||||
case PvdBaseType::PvdF64:
|
||||
return getMarshalOperators<smtype, PvdF64>(single, block);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool getMarshalOperators(TSingleMarshaller& single, TBlockMarshaller& block, int32_t smtypeId,
|
||||
int32_t lgtypeId)
|
||||
{
|
||||
switch(smtypeId)
|
||||
{
|
||||
case PvdBaseType::PvdI8: // int8_t:
|
||||
return getMarshalOperators<int8_t>(single, block, lgtypeId);
|
||||
case PvdBaseType::PvdU8: // uint8_t:
|
||||
return getMarshalOperators<uint8_t>(single, block, lgtypeId);
|
||||
case PvdBaseType::PvdI16: // int16_t:
|
||||
return getMarshalOperators<int16_t>(single, block, lgtypeId);
|
||||
case PvdBaseType::PvdU16: // uint16_t:
|
||||
return getMarshalOperators<uint16_t>(single, block, lgtypeId);
|
||||
case PvdBaseType::PvdI32: // int32_t:
|
||||
return getMarshalOperators<int32_t>(single, block, lgtypeId);
|
||||
case PvdBaseType::PvdU32: // uint32_t:
|
||||
return getMarshalOperators<uint32_t>(single, block, lgtypeId);
|
||||
case PvdBaseType::PvdI64: // int64_t:
|
||||
return getMarshalOperators<int64_t>(single, block, lgtypeId);
|
||||
case PvdBaseType::PvdU64: // uint64_t:
|
||||
return getMarshalOperators<uint64_t>(single, block, lgtypeId);
|
||||
case PvdBaseType::PvdF32:
|
||||
return getMarshalOperators<PvdF32>(single, block, lgtypeId);
|
||||
case PvdBaseType::PvdF64:
|
||||
return getMarshalOperators<PvdF64>(single, block, lgtypeId);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // PXPVDSDK_PXPVDMARSHALLING_H
|
||||
120
physx/source/pvd/src/PxPvdMemClient.cpp
Normal file
120
physx/source/pvd/src/PxPvdMemClient.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#include "PxPvdImpl.h"
|
||||
#include "PxPvdMemClient.h"
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace pvdsdk
|
||||
{
|
||||
|
||||
PvdMemClient::PvdMemClient(PvdImpl& pvd)
|
||||
: mSDKPvd(pvd)
|
||||
, mPvdDataStream(NULL)
|
||||
, mIsConnected(false)
|
||||
, mMemEventBuffer(profile::PxProfileMemoryEventBuffer::createMemoryEventBuffer(*gPvdAllocatorCallback))
|
||||
{
|
||||
}
|
||||
|
||||
PvdMemClient::~PvdMemClient()
|
||||
{
|
||||
mSDKPvd.removeClient(this);
|
||||
if(mMemEventBuffer.hasClients())
|
||||
mPvdDataStream->destroyInstance(&mMemEventBuffer);
|
||||
mMemEventBuffer.release();
|
||||
}
|
||||
|
||||
PvdDataStream* PvdMemClient::getDataStream()
|
||||
{
|
||||
return mPvdDataStream;
|
||||
}
|
||||
|
||||
bool PvdMemClient::isConnected() const
|
||||
{
|
||||
return mIsConnected;
|
||||
}
|
||||
|
||||
void PvdMemClient::onPvdConnected()
|
||||
{
|
||||
if(mIsConnected)
|
||||
return;
|
||||
mIsConnected = true;
|
||||
|
||||
mPvdDataStream = PvdDataStream::create(&mSDKPvd);
|
||||
mPvdDataStream->createInstance(&mMemEventBuffer);
|
||||
mMemEventBuffer.addClient(*this);
|
||||
}
|
||||
|
||||
void PvdMemClient::onPvdDisconnected()
|
||||
{
|
||||
if(!mIsConnected)
|
||||
return;
|
||||
mIsConnected = false;
|
||||
|
||||
flush();
|
||||
|
||||
mMemEventBuffer.removeClient(*this);
|
||||
mPvdDataStream->release();
|
||||
mPvdDataStream = NULL;
|
||||
}
|
||||
|
||||
void PvdMemClient::onAllocation(size_t inSize, const char* inType, const char* inFile, int inLine, void* inAddr)
|
||||
{
|
||||
mMutex.lock();
|
||||
mMemEventBuffer.onAllocation(inSize, inType, inFile, inLine, inAddr);
|
||||
mMutex.unlock();
|
||||
}
|
||||
|
||||
void PvdMemClient::onDeallocation(void* inAddr)
|
||||
{
|
||||
mMutex.lock();
|
||||
mMemEventBuffer.onDeallocation(inAddr);
|
||||
mMutex.unlock();
|
||||
}
|
||||
|
||||
void PvdMemClient::flush()
|
||||
{
|
||||
mMutex.lock();
|
||||
mMemEventBuffer.flushProfileEvents();
|
||||
mMutex.unlock();
|
||||
}
|
||||
|
||||
void PvdMemClient::handleBufferFlush(const uint8_t* inData, uint32_t inLength)
|
||||
{
|
||||
if(mPvdDataStream)
|
||||
mPvdDataStream->setPropertyValue(&mMemEventBuffer, "events", inData, inLength);
|
||||
}
|
||||
|
||||
void PvdMemClient::handleClientRemoved()
|
||||
{
|
||||
}
|
||||
|
||||
} // pvd
|
||||
} // physx
|
||||
83
physx/source/pvd/src/PxPvdMemClient.h
Normal file
83
physx/source/pvd/src/PxPvdMemClient.h
Normal file
@ -0,0 +1,83 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifndef PXPVDSDK_PXPVDMEMCLIENT_H
|
||||
#define PXPVDSDK_PXPVDMEMCLIENT_H
|
||||
|
||||
#include "PxPvdClient.h"
|
||||
#include "PsHashMap.h"
|
||||
#include "PsMutex.h"
|
||||
#include "PsBroadcast.h"
|
||||
#include "PxProfileEventBufferClient.h"
|
||||
#include "PxProfileMemory.h"
|
||||
|
||||
namespace physx
|
||||
{
|
||||
class PvdDataStream;
|
||||
|
||||
namespace pvdsdk
|
||||
{
|
||||
class PvdImpl;
|
||||
class PvdMemClient : public PvdClient,
|
||||
public profile::PxProfileEventBufferClient,
|
||||
public shdfnd::UserAllocated
|
||||
{
|
||||
PX_NOCOPY(PvdMemClient)
|
||||
public:
|
||||
PvdMemClient(PvdImpl& pvd);
|
||||
virtual ~PvdMemClient();
|
||||
|
||||
bool isConnected() const;
|
||||
void onPvdConnected();
|
||||
void onPvdDisconnected();
|
||||
void flush();
|
||||
|
||||
PvdDataStream* getDataStream();
|
||||
void sendMemEvents();
|
||||
|
||||
// memory event
|
||||
void onAllocation(size_t size, const char* typeName, const char* filename, int line, void* allocatedMemory);
|
||||
void onDeallocation(void* addr);
|
||||
|
||||
private:
|
||||
PvdImpl& mSDKPvd;
|
||||
PvdDataStream* mPvdDataStream;
|
||||
bool mIsConnected;
|
||||
|
||||
// mem profile
|
||||
shdfnd::Mutex mMutex; // mem onallocation can called from different threads
|
||||
profile::PxProfileMemoryEventBuffer& mMemEventBuffer;
|
||||
void handleBufferFlush(const uint8_t* inData, uint32_t inLength);
|
||||
void handleClientRemoved();
|
||||
};
|
||||
|
||||
} // namespace pvdsdk
|
||||
} // namespace physx
|
||||
|
||||
#endif // PXPVDSDK_PXPVDMEMCLIENT_H
|
||||
32
physx/source/pvd/src/PxPvdObjectModelInternalTypeDefs.h
Normal file
32
physx/source/pvd/src/PxPvdObjectModelInternalTypeDefs.h
Normal file
@ -0,0 +1,32 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#define THERE_IS_NO_INCLUDE_GUARD_HERE_FOR_A_REASON
|
||||
|
||||
DECLARE_INTERNAL_PVD_TYPE(ArrayData)
|
||||
|
||||
#undef THERE_IS_NO_INCLUDE_GUARD_HERE_FOR_A_REASON
|
||||
154
physx/source/pvd/src/PxPvdObjectModelInternalTypes.h
Normal file
154
physx/source/pvd/src/PxPvdObjectModelInternalTypes.h
Normal file
@ -0,0 +1,154 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef PXPVDSDK_PXPVDOBJECTMODELINTERNALTYPES_H
|
||||
#define PXPVDSDK_PXPVDOBJECTMODELINTERNALTYPES_H
|
||||
|
||||
#include "foundation/PxMemory.h"
|
||||
#include "PxPvdObjectModelBaseTypes.h"
|
||||
#include "PsArray.h"
|
||||
#include "PxPvdFoundation.h"
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace pvdsdk
|
||||
{
|
||||
|
||||
struct PvdInternalType
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
None = 0,
|
||||
#define DECLARE_INTERNAL_PVD_TYPE(type) type,
|
||||
#include "PxPvdObjectModelInternalTypeDefs.h"
|
||||
Last
|
||||
#undef DECLARE_INTERNAL_PVD_TYPE
|
||||
};
|
||||
};
|
||||
|
||||
PX_COMPILE_TIME_ASSERT(uint32_t(PvdInternalType::Last) <= uint32_t(PvdBaseType::InternalStop));
|
||||
|
||||
template <typename T>
|
||||
struct DataTypeToPvdTypeMap
|
||||
{
|
||||
bool compile_error;
|
||||
};
|
||||
template <PvdInternalType::Enum>
|
||||
struct PvdTypeToDataTypeMap
|
||||
{
|
||||
bool compile_error;
|
||||
};
|
||||
|
||||
#define DECLARE_INTERNAL_PVD_TYPE(type) \
|
||||
template <> \
|
||||
struct DataTypeToPvdTypeMap<type> \
|
||||
{ \
|
||||
enum Enum \
|
||||
{ \
|
||||
BaseTypeEnum = PvdInternalType::type \
|
||||
}; \
|
||||
}; \
|
||||
template <> \
|
||||
struct PvdTypeToDataTypeMap<PvdInternalType::type> \
|
||||
{ \
|
||||
typedef type TDataType; \
|
||||
}; \
|
||||
template <> \
|
||||
struct PvdDataTypeToNamespacedNameMap<type> \
|
||||
{ \
|
||||
NamespacedName Name; \
|
||||
PvdDataTypeToNamespacedNameMap<type>() : Name("physx3_debugger_internal", #type) \
|
||||
{ \
|
||||
} \
|
||||
};
|
||||
#include "PxPvdObjectModelInternalTypeDefs.h"
|
||||
#undef DECLARE_INTERNAL_PVD_TYPE
|
||||
|
||||
template <typename TDataType, typename TAlloc>
|
||||
DataRef<TDataType> toDataRef(const shdfnd::Array<TDataType, TAlloc>& data)
|
||||
{
|
||||
return DataRef<TDataType>(data.begin(), data.end());
|
||||
}
|
||||
|
||||
static inline bool safeStrEq(const DataRef<String>& lhs, const DataRef<String>& rhs)
|
||||
{
|
||||
uint32_t count = lhs.size();
|
||||
if(count != rhs.size())
|
||||
return false;
|
||||
for(uint32_t idx = 0; idx < count; ++idx)
|
||||
if(!safeStrEq(lhs[idx], rhs[idx]))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline char* copyStr(const char* str)
|
||||
{
|
||||
str = nonNull(str);
|
||||
uint32_t len = static_cast<uint32_t>(strlen(str));
|
||||
char* newData = reinterpret_cast<char*>(PX_ALLOC(len + 1, "string"));
|
||||
PxMemCopy(newData, str, len);
|
||||
newData[len] = 0;
|
||||
return newData;
|
||||
}
|
||||
|
||||
// Used for predictable bit fields.
|
||||
template <typename TDataType, uint8_t TNumBits, uint8_t TOffset, typename TInputType>
|
||||
struct BitMaskSetter
|
||||
{
|
||||
// Create a mask that masks out the orginal value shift into place
|
||||
static TDataType createOffsetMask()
|
||||
{
|
||||
return createMask() << TOffset;
|
||||
}
|
||||
// Create a mask of TNumBits number of tis
|
||||
static TDataType createMask()
|
||||
{
|
||||
return static_cast<TDataType>((1 << TNumBits) - 1);
|
||||
}
|
||||
void setValue(TDataType& inCurrent, TInputType inData)
|
||||
{
|
||||
PX_ASSERT(inData < (1 << TNumBits));
|
||||
|
||||
// Create a mask to remove the current value.
|
||||
TDataType theMask = ~(createOffsetMask());
|
||||
// Clear out current value.
|
||||
inCurrent = inCurrent & theMask;
|
||||
// Create the new value.
|
||||
TDataType theAddition = reinterpret_cast<TDataType>(inData << TOffset);
|
||||
// or it into the existing value.
|
||||
inCurrent = inCurrent | theAddition;
|
||||
}
|
||||
|
||||
TInputType getValue(TDataType inCurrent)
|
||||
{
|
||||
return static_cast<TInputType>((inCurrent >> TOffset) & createMask());
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif // PXPVDSDK_PXPVDOBJECTMODELINTERNALTYPES_H
|
||||
1503
physx/source/pvd/src/PxPvdObjectModelMetaData.cpp
Normal file
1503
physx/source/pvd/src/PxPvdObjectModelMetaData.cpp
Normal file
File diff suppressed because it is too large
Load Diff
481
physx/source/pvd/src/PxPvdObjectModelMetaData.h
Normal file
481
physx/source/pvd/src/PxPvdObjectModelMetaData.h
Normal file
@ -0,0 +1,481 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
#ifndef PXPVDSDK_PXPVDOBJECTMODELMETADATA_H
|
||||
#define PXPVDSDK_PXPVDOBJECTMODELMETADATA_H
|
||||
|
||||
#include "foundation/PxAssert.h"
|
||||
#include "PxPvdObjectModelBaseTypes.h"
|
||||
#include "PxPvdBits.h"
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace pvdsdk
|
||||
{
|
||||
|
||||
class PvdInputStream;
|
||||
class PvdOutputStream;
|
||||
|
||||
struct PropertyDescription
|
||||
{
|
||||
NamespacedName mOwnerClassName;
|
||||
int32_t mOwnerClassId;
|
||||
String mName;
|
||||
String mSemantic;
|
||||
// The datatype this property corresponds to.
|
||||
int32_t mDatatype;
|
||||
// The name of the datatype
|
||||
NamespacedName mDatatypeName;
|
||||
// Scalar or array.
|
||||
PropertyType::Enum mPropertyType;
|
||||
// No other property under any class has this id, it is DB-unique.
|
||||
int32_t mPropertyId;
|
||||
// Offset in bytes into the object's data section where this property starts.
|
||||
uint32_t m32BitOffset;
|
||||
// Offset in bytes into the object's data section where this property starts.
|
||||
uint32_t m64BitOffset;
|
||||
|
||||
PropertyDescription(const NamespacedName& clsName, int32_t classId, String name, String semantic, int32_t datatype,
|
||||
const NamespacedName& datatypeName, PropertyType::Enum propType, int32_t propId,
|
||||
uint32_t offset32, uint32_t offset64)
|
||||
: mOwnerClassName(clsName)
|
||||
, mOwnerClassId(classId)
|
||||
, mName(name)
|
||||
, mSemantic(semantic)
|
||||
, mDatatype(datatype)
|
||||
, mDatatypeName(datatypeName)
|
||||
, mPropertyType(propType)
|
||||
, mPropertyId(propId)
|
||||
, m32BitOffset(offset32)
|
||||
, m64BitOffset(offset64)
|
||||
{
|
||||
}
|
||||
PropertyDescription()
|
||||
: mOwnerClassId(-1)
|
||||
, mName("")
|
||||
, mSemantic("")
|
||||
, mDatatype(-1)
|
||||
, mPropertyType(PropertyType::Unknown)
|
||||
, mPropertyId(-1)
|
||||
, m32BitOffset(0)
|
||||
, m64BitOffset(0)
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~PropertyDescription()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct PtrOffsetType
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
UnknownOffset,
|
||||
VoidPtrOffset,
|
||||
StringOffset
|
||||
};
|
||||
};
|
||||
|
||||
struct PtrOffset
|
||||
{
|
||||
PtrOffsetType::Enum mOffsetType;
|
||||
uint32_t mOffset;
|
||||
PtrOffset(PtrOffsetType::Enum type, uint32_t offset) : mOffsetType(type), mOffset(offset)
|
||||
{
|
||||
}
|
||||
PtrOffset() : mOffsetType(PtrOffsetType::UnknownOffset), mOffset(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
inline uint32_t align(uint32_t offset, uint32_t alignment)
|
||||
{
|
||||
uint32_t startOffset = offset;
|
||||
uint32_t alignmentMask = ~(alignment - 1);
|
||||
offset = (offset + alignment - 1) & alignmentMask;
|
||||
PX_ASSERT(offset >= startOffset && (offset % alignment) == 0);
|
||||
(void)startOffset;
|
||||
return offset;
|
||||
}
|
||||
|
||||
struct ClassDescriptionSizeInfo
|
||||
{
|
||||
// The size of the data section of this object, padded to alignment.
|
||||
uint32_t mByteSize;
|
||||
// The last data member goes to here.
|
||||
uint32_t mDataByteSize;
|
||||
// Alignment in bytes of the data section of this object.
|
||||
uint32_t mAlignment;
|
||||
// the offsets of string handles in the binary value of this class
|
||||
DataRef<PtrOffset> mPtrOffsets;
|
||||
ClassDescriptionSizeInfo() : mByteSize(0), mDataByteSize(0), mAlignment(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct ClassDescription
|
||||
{
|
||||
NamespacedName mName;
|
||||
// No other class has this id, it is DB-unique
|
||||
int32_t mClassId;
|
||||
// Only single derivation supported.
|
||||
int32_t mBaseClass;
|
||||
// If this class has properties that are of uniform type, then we note that.
|
||||
// This means that when deserialization an array of these objects we can just use
|
||||
// single function to endian convert the entire mess at once.
|
||||
int32_t mPackedUniformWidth;
|
||||
// If this class is composed uniformly of members of a given type
|
||||
// Or all of its properties are composed uniformly of members of
|
||||
// a give ntype, then this class's packed type is that type.
|
||||
// PxTransform's packed type would be float.
|
||||
int32_t mPackedClassType;
|
||||
// 0: 32Bit 1: 64Bit
|
||||
ClassDescriptionSizeInfo mSizeInfo[2];
|
||||
// No further property additions allowed.
|
||||
bool mLocked;
|
||||
// True when this datatype has an array on it that needs to be
|
||||
// separately deleted.
|
||||
bool mRequiresDestruction;
|
||||
|
||||
ClassDescription(NamespacedName name, int32_t id)
|
||||
: mName(name)
|
||||
, mClassId(id)
|
||||
, mBaseClass(-1)
|
||||
, mPackedUniformWidth(-1)
|
||||
, mPackedClassType(-1)
|
||||
, mLocked(false)
|
||||
, mRequiresDestruction(false)
|
||||
{
|
||||
}
|
||||
ClassDescription()
|
||||
: mClassId(-1), mBaseClass(-1), mPackedUniformWidth(-1), mPackedClassType(-1), mLocked(false), mRequiresDestruction(false)
|
||||
{
|
||||
}
|
||||
virtual ~ClassDescription()
|
||||
{
|
||||
}
|
||||
|
||||
ClassDescriptionSizeInfo& get32BitSizeInfo()
|
||||
{
|
||||
return mSizeInfo[0];
|
||||
}
|
||||
ClassDescriptionSizeInfo& get64BitSizeInfo()
|
||||
{
|
||||
return mSizeInfo[1];
|
||||
}
|
||||
uint32_t& get32BitSize()
|
||||
{
|
||||
return get32BitSizeInfo().mByteSize;
|
||||
}
|
||||
uint32_t& get64BitSize()
|
||||
{
|
||||
return get64BitSizeInfo().mByteSize;
|
||||
}
|
||||
|
||||
uint32_t get32BitSize() const
|
||||
{
|
||||
return mSizeInfo[0].mByteSize;
|
||||
}
|
||||
const ClassDescriptionSizeInfo& getNativeSizeInfo() const
|
||||
{
|
||||
return mSizeInfo[(sizeof(void*) >> 2) - 1];
|
||||
}
|
||||
uint32_t getNativeSize() const
|
||||
{
|
||||
return getNativeSizeInfo().mByteSize;
|
||||
}
|
||||
};
|
||||
|
||||
struct MarshalQueryResult
|
||||
{
|
||||
int32_t srcType;
|
||||
int32_t dstType;
|
||||
// If canMarshal != needsMarshalling we have a problem.
|
||||
bool canMarshal;
|
||||
bool needsMarshalling;
|
||||
// Non null if marshalling is possible.
|
||||
TBlockMarshaller marshaller;
|
||||
MarshalQueryResult(int32_t _srcType = -1, int32_t _dstType = -1, bool _canMarshal = false, bool _needs = false,
|
||||
TBlockMarshaller _m = NULL)
|
||||
: srcType(_srcType), dstType(_dstType), canMarshal(_canMarshal), needsMarshalling(_needs), marshaller(_m)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct PropertyMessageEntry
|
||||
{
|
||||
PropertyDescription mProperty;
|
||||
NamespacedName mDatatypeName;
|
||||
// datatype of the data in the message.
|
||||
int32_t mDatatypeId;
|
||||
// where in the message this property starts.
|
||||
uint32_t mMessageOffset;
|
||||
// size of this entry object
|
||||
uint32_t mByteSize;
|
||||
|
||||
// If the chain of properties doesn't have any array properties this indicates the
|
||||
uint32_t mDestByteSize;
|
||||
|
||||
PropertyMessageEntry(PropertyDescription propName, NamespacedName dtypeName, int32_t dtype, uint32_t messageOff,
|
||||
uint32_t byteSize, uint32_t destByteSize)
|
||||
: mProperty(propName)
|
||||
, mDatatypeName(dtypeName)
|
||||
, mDatatypeId(dtype)
|
||||
, mMessageOffset(messageOff)
|
||||
, mByteSize(byteSize)
|
||||
, mDestByteSize(destByteSize)
|
||||
{
|
||||
}
|
||||
PropertyMessageEntry() : mDatatypeId(-1), mMessageOffset(0), mByteSize(0), mDestByteSize(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// Create a struct that defines a subset of the properties on an object.
|
||||
struct PropertyMessageDescription
|
||||
{
|
||||
NamespacedName mClassName;
|
||||
// No other class has this id, it is DB-unique
|
||||
int32_t mClassId;
|
||||
NamespacedName mMessageName;
|
||||
int32_t mMessageId;
|
||||
DataRef<PropertyMessageEntry> mProperties;
|
||||
uint32_t mMessageByteSize;
|
||||
// Offsets into the property message where const char* items are.
|
||||
DataRef<uint32_t> mStringOffsets;
|
||||
PropertyMessageDescription(const NamespacedName& nm, int32_t clsId, const NamespacedName& msgName, int32_t msgId,
|
||||
uint32_t msgSize)
|
||||
: mClassName(nm), mClassId(clsId), mMessageName(msgName), mMessageId(msgId), mMessageByteSize(msgSize)
|
||||
{
|
||||
}
|
||||
PropertyMessageDescription() : mClassId(-1), mMessageId(-1), mMessageByteSize(0)
|
||||
{
|
||||
}
|
||||
virtual ~PropertyMessageDescription()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class StringTable
|
||||
{
|
||||
protected:
|
||||
virtual ~StringTable()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
virtual uint32_t getNbStrs() = 0;
|
||||
virtual uint32_t getStrs(const char** outStrs, uint32_t bufLen, uint32_t startIdx = 0) = 0;
|
||||
virtual const char* registerStr(const char* str, bool& outAdded) = 0;
|
||||
const char* registerStr(const char* str)
|
||||
{
|
||||
bool ignored;
|
||||
return registerStr(str, ignored);
|
||||
}
|
||||
virtual StringHandle strToHandle(const char* str) = 0;
|
||||
virtual const char* handleToStr(uint32_t hdl) = 0;
|
||||
virtual void release() = 0;
|
||||
|
||||
static StringTable& create();
|
||||
};
|
||||
|
||||
struct None
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class Option
|
||||
{
|
||||
T mValue;
|
||||
bool mHasValue;
|
||||
|
||||
public:
|
||||
Option(const T& val) : mValue(val), mHasValue(true)
|
||||
{
|
||||
}
|
||||
Option(None nothing = None()) : mHasValue(false)
|
||||
{
|
||||
(void)nothing;
|
||||
}
|
||||
Option(const Option& other) : mValue(other.mValue), mHasValue(other.mHasValue)
|
||||
{
|
||||
}
|
||||
Option& operator=(const Option& other)
|
||||
{
|
||||
mValue = other.mValue;
|
||||
mHasValue = other.mHasValue;
|
||||
return *this;
|
||||
}
|
||||
bool hasValue() const
|
||||
{
|
||||
return mHasValue;
|
||||
}
|
||||
const T& getValue() const
|
||||
{
|
||||
PX_ASSERT(hasValue());
|
||||
return mValue;
|
||||
}
|
||||
T& getValue()
|
||||
{
|
||||
PX_ASSERT(hasValue());
|
||||
return mValue;
|
||||
}
|
||||
operator const T&() const
|
||||
{
|
||||
return getValue();
|
||||
}
|
||||
operator T&()
|
||||
{
|
||||
return getValue();
|
||||
}
|
||||
T* operator->()
|
||||
{
|
||||
return &getValue();
|
||||
}
|
||||
const T* operator->() const
|
||||
{
|
||||
return &getValue();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Create new classes and add properties to some existing ones.
|
||||
* The default classes are created already, the simple types
|
||||
* along with the basic math types.
|
||||
* (uint8_t, int8_t, etc )
|
||||
* (PxVec3, PxQuat, PxTransform, PxMat33, PxMat34, PxMat44)
|
||||
*/
|
||||
class PvdObjectModelMetaData
|
||||
{
|
||||
protected:
|
||||
virtual ~PvdObjectModelMetaData()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
virtual ClassDescription getOrCreateClass(const NamespacedName& nm) = 0;
|
||||
// get or create parent, lock parent. deriveFrom getOrCreatechild.
|
||||
virtual bool deriveClass(const NamespacedName& parent, const NamespacedName& child) = 0;
|
||||
virtual Option<ClassDescription> findClass(const NamespacedName& nm) const = 0;
|
||||
template <typename TDataType>
|
||||
Option<ClassDescription> findClass()
|
||||
{
|
||||
return findClass(getPvdNamespacedNameForType<TDataType>());
|
||||
}
|
||||
virtual Option<ClassDescription> getClass(int32_t classId) const = 0;
|
||||
virtual ClassDescription* getClassPtr(int32_t classId) const = 0;
|
||||
|
||||
virtual Option<ClassDescription> getParentClass(int32_t classId) const = 0;
|
||||
bool isDerivedFrom(int32_t classId, int32_t parentClass) const
|
||||
{
|
||||
if(classId == parentClass)
|
||||
return true;
|
||||
ClassDescription* p = getClassPtr(getClassPtr(classId)->mBaseClass);
|
||||
while(p != NULL)
|
||||
{
|
||||
if(p->mClassId == parentClass)
|
||||
return true;
|
||||
p = getClassPtr(p->mBaseClass);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void lockClass(int32_t classId) = 0;
|
||||
|
||||
virtual uint32_t getNbClasses() const = 0;
|
||||
virtual uint32_t getClasses(ClassDescription* outClasses, uint32_t requestCount, uint32_t startIndex = 0) const = 0;
|
||||
|
||||
// Create a nested property.
|
||||
// This way you can have obj.p.x without explicity defining the class p.
|
||||
virtual Option<PropertyDescription> createProperty(int32_t classId, String name, String semantic, int32_t datatype,
|
||||
PropertyType::Enum propertyType = PropertyType::Scalar) = 0;
|
||||
Option<PropertyDescription> createProperty(NamespacedName clsId, String name, String semantic, NamespacedName dtype,
|
||||
PropertyType::Enum propertyType = PropertyType::Scalar)
|
||||
{
|
||||
return createProperty(findClass(clsId)->mClassId, name, semantic, findClass(dtype)->mClassId, propertyType);
|
||||
}
|
||||
Option<PropertyDescription> createProperty(NamespacedName clsId, String name, NamespacedName dtype,
|
||||
PropertyType::Enum propertyType = PropertyType::Scalar)
|
||||
{
|
||||
return createProperty(findClass(clsId)->mClassId, name, "", findClass(dtype)->mClassId, propertyType);
|
||||
}
|
||||
Option<PropertyDescription> createProperty(int32_t clsId, String name, int32_t dtype,
|
||||
PropertyType::Enum propertyType = PropertyType::Scalar)
|
||||
{
|
||||
return createProperty(clsId, name, "", dtype, propertyType);
|
||||
}
|
||||
template <typename TDataType>
|
||||
Option<PropertyDescription> createProperty(int32_t clsId, String name, String semantic = "",
|
||||
PropertyType::Enum propertyType = PropertyType::Scalar)
|
||||
{
|
||||
return createProperty(clsId, name, semantic, getPvdNamespacedNameForType<TDataType>(), propertyType);
|
||||
}
|
||||
virtual Option<PropertyDescription> findProperty(const NamespacedName& cls, String prop) const = 0;
|
||||
virtual Option<PropertyDescription> findProperty(int32_t clsId, String prop) const = 0;
|
||||
virtual Option<PropertyDescription> getProperty(int32_t propId) const = 0;
|
||||
virtual void setNamedPropertyValues(DataRef<NamedValue> values, int32_t propId) = 0;
|
||||
// for enumerations and flags.
|
||||
virtual DataRef<NamedValue> getNamedPropertyValues(int32_t propId) const = 0;
|
||||
|
||||
virtual uint32_t getNbProperties(int32_t classId) const = 0;
|
||||
virtual uint32_t getProperties(int32_t classId, PropertyDescription* outBuffer, uint32_t bufCount,
|
||||
uint32_t startIdx = 0) const = 0;
|
||||
|
||||
// Does one cls id differ marshalling to another and if so return the functions to do it.
|
||||
virtual MarshalQueryResult checkMarshalling(int32_t srcClsId, int32_t dstClsId) const = 0;
|
||||
|
||||
// messages and classes are stored in separate maps, so a property message can have the same name as a class.
|
||||
virtual Option<PropertyMessageDescription> createPropertyMessage(const NamespacedName& cls,
|
||||
const NamespacedName& msgName,
|
||||
DataRef<PropertyMessageArg> entries,
|
||||
uint32_t messageSize) = 0;
|
||||
virtual Option<PropertyMessageDescription> findPropertyMessage(const NamespacedName& msgName) const = 0;
|
||||
virtual Option<PropertyMessageDescription> getPropertyMessage(int32_t msgId) const = 0;
|
||||
|
||||
virtual uint32_t getNbPropertyMessages() const = 0;
|
||||
virtual uint32_t getPropertyMessages(PropertyMessageDescription* msgBuf, uint32_t bufLen,
|
||||
uint32_t startIdx = 0) const = 0;
|
||||
|
||||
virtual StringTable& getStringTable() const = 0;
|
||||
|
||||
virtual void write(PvdOutputStream& stream) const = 0;
|
||||
void save(PvdOutputStream& stream) const
|
||||
{
|
||||
write(stream);
|
||||
}
|
||||
|
||||
virtual void addRef() = 0;
|
||||
virtual void release() = 0;
|
||||
|
||||
static uint32_t getCurrentPvdObjectModelVersion();
|
||||
static PvdObjectModelMetaData& create();
|
||||
static PvdObjectModelMetaData& create(PvdInputStream& stream);
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif // PXPVDSDK_PXPVDOBJECTMODELMETADATA_H
|
||||
80
physx/source/pvd/src/PxPvdObjectRegistrar.cpp
Normal file
80
physx/source/pvd/src/PxPvdObjectRegistrar.cpp
Normal file
@ -0,0 +1,80 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#include "PxPvdObjectRegistrar.h"
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace pvdsdk
|
||||
{
|
||||
|
||||
bool ObjectRegistrar::addItem(const void* inItem)
|
||||
{
|
||||
physx::shdfnd::Mutex::ScopedLock lock(mRefCountMapLock);
|
||||
|
||||
if(mRefCountMap.find(inItem))
|
||||
{
|
||||
uint32_t& counter = mRefCountMap[inItem];
|
||||
counter++;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
mRefCountMap.insert(inItem, 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool ObjectRegistrar::decItem(const void* inItem)
|
||||
{
|
||||
physx::shdfnd::Mutex::ScopedLock lock(mRefCountMapLock);
|
||||
const physx::shdfnd::HashMap<const void*, uint32_t>::Entry* entry = mRefCountMap.find(inItem);
|
||||
if(entry)
|
||||
{
|
||||
uint32_t& retval(const_cast<uint32_t&>(entry->second));
|
||||
if(retval)
|
||||
--retval;
|
||||
uint32_t theValue = retval;
|
||||
if(theValue == 0)
|
||||
{
|
||||
mRefCountMap.erase(inItem);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ObjectRegistrar::clear()
|
||||
{
|
||||
physx::shdfnd::Mutex::ScopedLock lock(mRefCountMapLock);
|
||||
mRefCountMap.clear();
|
||||
}
|
||||
|
||||
} // pvdsdk
|
||||
} // physx
|
||||
71
physx/source/pvd/src/PxPvdObjectRegistrar.h
Normal file
71
physx/source/pvd/src/PxPvdObjectRegistrar.h
Normal file
@ -0,0 +1,71 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifndef PXPVDSDK_PXPVDOBJECTREGISTRAR_H
|
||||
#define PXPVDSDK_PXPVDOBJECTREGISTRAR_H
|
||||
|
||||
/** \addtogroup pvd
|
||||
@{
|
||||
*/
|
||||
|
||||
#include "PsHashMap.h"
|
||||
#include "PsMutex.h"
|
||||
|
||||
#if !PX_DOXYGEN
|
||||
namespace physx
|
||||
{
|
||||
namespace pvdsdk
|
||||
{
|
||||
#endif
|
||||
class ObjectRegistrar
|
||||
{
|
||||
PX_NOCOPY(ObjectRegistrar)
|
||||
public:
|
||||
ObjectRegistrar()
|
||||
{
|
||||
}
|
||||
virtual ~ObjectRegistrar()
|
||||
{
|
||||
}
|
||||
|
||||
bool addItem(const void* inItem);
|
||||
bool decItem(const void* inItem);
|
||||
void clear();
|
||||
|
||||
private:
|
||||
physx::shdfnd::HashMap<const void*, uint32_t> mRefCountMap;
|
||||
physx::shdfnd::Mutex mRefCountMapLock;
|
||||
};
|
||||
#if !PX_DOXYGEN
|
||||
} // pvdsdk
|
||||
} // physx
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
#endif // PXPVDSDK_PXPVDOBJECTREGISTRAR_H
|
||||
142
physx/source/pvd/src/PxPvdProfileZone.h
Normal file
142
physx/source/pvd/src/PxPvdProfileZone.h
Normal file
@ -0,0 +1,142 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef PXPVDSDK_PXPVDPROFILEZONE_H
|
||||
#define PXPVDSDK_PXPVDPROFILEZONE_H
|
||||
|
||||
#include "foundation/PxPreprocessor.h"
|
||||
|
||||
#include "PxProfileEventBufferClientManager.h"
|
||||
#include "PxProfileEventNames.h"
|
||||
#include "PxProfileEventSender.h"
|
||||
|
||||
namespace physx {
|
||||
class PxAllocatorCallback;
|
||||
|
||||
namespace profile {
|
||||
|
||||
class PxProfileZoneManager;
|
||||
|
||||
/**
|
||||
\brief The profiling system was setup in the expectation that there would be several
|
||||
systems that each had its own island of profile information. PhysX, client code,
|
||||
and APEX would be the first examples of these. Each one of these islands is represented
|
||||
by a profile zone.
|
||||
|
||||
A profile zone combines a name, a place where all the events coming from its interface
|
||||
can flushed, and a mapping from event number to full event name.
|
||||
|
||||
It also provides a top level filtering service where profile events
|
||||
can be filtered by event id.
|
||||
|
||||
The profile zone implements a system where if there is no one
|
||||
listening to events it doesn't provide a mechanism to send them. In this way
|
||||
the event system is short circuited when there aren't any clients.
|
||||
|
||||
All functions on this interface should be considered threadsafe.
|
||||
|
||||
@see PxProfileZoneClientManager, PxProfileNameProvider, PxProfileEventSender, PxProfileEventFlusher
|
||||
*/
|
||||
class PxProfileZone : public PxProfileZoneClientManager
|
||||
, public PxProfileNameProvider
|
||||
, public PxProfileEventSender
|
||||
, public PxProfileEventFlusher
|
||||
{
|
||||
protected:
|
||||
virtual ~PxProfileZone(){}
|
||||
public:
|
||||
/**
|
||||
\brief Get profile zone name.
|
||||
\return Zone name.
|
||||
*/
|
||||
virtual const char* getName() = 0;
|
||||
/**
|
||||
\brief Release the profile zone.
|
||||
*/
|
||||
virtual void release() = 0;
|
||||
|
||||
/**
|
||||
\brief Set profile zone manager for the zone.
|
||||
\param inMgr Profile zone manager.
|
||||
*/
|
||||
virtual void setProfileZoneManager(PxProfileZoneManager* inMgr) = 0;
|
||||
/**
|
||||
\brief Get profile zone manager for the zone.
|
||||
\return Profile zone manager.
|
||||
*/
|
||||
virtual PxProfileZoneManager* getProfileZoneManager() = 0;
|
||||
|
||||
/**
|
||||
\brief Get or create a new event id for a given name.
|
||||
If you pass in a previously defined event name (including one returned)
|
||||
from the name provider) you will just get the same event id back.
|
||||
\param inName Profile event name.
|
||||
*/
|
||||
virtual uint16_t getEventIdForName( const char* inName ) = 0;
|
||||
|
||||
/**
|
||||
\brief Specifies that it is a safe point to flush read-write name map into
|
||||
read-only map. Make sure getEventIdForName is not called from a different thread.
|
||||
*/
|
||||
virtual void flushEventIdNameMap() = 0;
|
||||
|
||||
/**
|
||||
\brief Reserve a contiguous set of profile event ids for a set of names.
|
||||
|
||||
This function does not do any meaningful error checking other than to ensure
|
||||
that if it does generate new ids they are contiguous. If the first name is already
|
||||
registered, that is the ID that will be returned regardless of what other
|
||||
names are registered. Thus either use this function alone (without the above
|
||||
function) or don't use it.
|
||||
If you register "one","two","three" and the function returns an id of 4, then
|
||||
"one" is mapped to 4, "two" is mapped to 5, and "three" is mapped to 6.
|
||||
|
||||
\param inNames set of names to register.
|
||||
\param inLen Length of the name list.
|
||||
|
||||
\return The first id associated with the first name. The rest of the names
|
||||
will be associated with monotonically incrementing uint16_t values from the first
|
||||
id.
|
||||
*/
|
||||
virtual uint16_t getEventIdsForNames( const char** inNames, uint32_t inLen ) = 0;
|
||||
|
||||
/**
|
||||
\brief Create a new profile zone.
|
||||
|
||||
\param inAllocator memory allocation is controlled through the foundation if one is passed in.
|
||||
\param inSDKName Name of the profile zone; useful for clients to understand where events came from.
|
||||
\param inNames Mapping from event id -> event name.
|
||||
\param inEventBufferByteSize Size of the canonical event buffer. This does not need to be a large number
|
||||
as profile events are fairly small individually.
|
||||
\return a profile zone implementation.
|
||||
*/
|
||||
static PxProfileZone& createProfileZone(PxAllocatorCallback* inAllocator, const char* inSDKName, PxProfileNames inNames = PxProfileNames(), uint32_t inEventBufferByteSize = 0x10000 /*64k*/);
|
||||
|
||||
};
|
||||
} }
|
||||
|
||||
#endif // PXPVDSDK_PXPVDPROFILEZONE_H
|
||||
161
physx/source/pvd/src/PxPvdProfileZoneClient.cpp
Normal file
161
physx/source/pvd/src/PxPvdProfileZoneClient.cpp
Normal file
@ -0,0 +1,161 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#include "PxPvdImpl.h"
|
||||
#include "PxPvdProfileZoneClient.h"
|
||||
#include "PxPvdProfileZone.h"
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace pvdsdk
|
||||
{
|
||||
struct ProfileZoneClient : public profile::PxProfileZoneClient, public shdfnd::UserAllocated
|
||||
{
|
||||
profile::PxProfileZone& mZone;
|
||||
PvdDataStream& mStream;
|
||||
|
||||
ProfileZoneClient(profile::PxProfileZone& zone, PvdDataStream& stream) : mZone(zone), mStream(stream)
|
||||
{
|
||||
}
|
||||
|
||||
~ProfileZoneClient()
|
||||
{
|
||||
mZone.removeClient(*this);
|
||||
}
|
||||
|
||||
virtual void createInstance()
|
||||
{
|
||||
mStream.addProfileZone(&mZone, mZone.getName());
|
||||
mStream.createInstance(&mZone);
|
||||
mZone.addClient(*this);
|
||||
profile::PxProfileNames names(mZone.getProfileNames());
|
||||
PVD_FOREACH(idx, names.eventCount)
|
||||
{
|
||||
handleEventAdded(names.events[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void handleEventAdded(const profile::PxProfileEventName& inName)
|
||||
{
|
||||
mStream.addProfileZoneEvent(&mZone, inName.name, inName.eventId.eventId, inName.eventId.compileTimeEnabled);
|
||||
}
|
||||
|
||||
virtual void handleBufferFlush(const uint8_t* inData, uint32_t inLength)
|
||||
{
|
||||
mStream.setPropertyValue(&mZone, "events", inData, inLength);
|
||||
}
|
||||
|
||||
virtual void handleClientRemoved()
|
||||
{
|
||||
mStream.destroyInstance(&mZone);
|
||||
}
|
||||
|
||||
private:
|
||||
ProfileZoneClient& operator=(const ProfileZoneClient&);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
using namespace physx;
|
||||
using namespace pvdsdk;
|
||||
|
||||
PvdProfileZoneClient::PvdProfileZoneClient(PvdImpl& pvd) : mSDKPvd(pvd), mPvdDataStream(NULL), mIsConnected(false)
|
||||
{
|
||||
}
|
||||
|
||||
PvdProfileZoneClient::~PvdProfileZoneClient()
|
||||
{
|
||||
mSDKPvd.removeClient(this);
|
||||
// all zones should removed
|
||||
PX_ASSERT(mProfileZoneClients.size() == 0);
|
||||
}
|
||||
|
||||
PvdDataStream* PvdProfileZoneClient::getDataStream()
|
||||
{
|
||||
return mPvdDataStream;
|
||||
}
|
||||
|
||||
bool PvdProfileZoneClient::isConnected() const
|
||||
{
|
||||
return mIsConnected;
|
||||
}
|
||||
|
||||
void PvdProfileZoneClient::onPvdConnected()
|
||||
{
|
||||
if(mIsConnected)
|
||||
return;
|
||||
mIsConnected = true;
|
||||
|
||||
mPvdDataStream = PvdDataStream::create(&mSDKPvd);
|
||||
|
||||
}
|
||||
|
||||
void PvdProfileZoneClient::onPvdDisconnected()
|
||||
{
|
||||
if(!mIsConnected)
|
||||
return;
|
||||
|
||||
mIsConnected = false;
|
||||
flush();
|
||||
|
||||
mPvdDataStream->release();
|
||||
mPvdDataStream = NULL;
|
||||
}
|
||||
|
||||
void PvdProfileZoneClient::flush()
|
||||
{
|
||||
PVD_FOREACH(idx, mProfileZoneClients.size())
|
||||
mProfileZoneClients[idx]->mZone.flushProfileEvents();
|
||||
}
|
||||
|
||||
void PvdProfileZoneClient::onZoneAdded(profile::PxProfileZone& zone)
|
||||
{
|
||||
PX_ASSERT(mIsConnected);
|
||||
ProfileZoneClient* client = PVD_NEW(ProfileZoneClient)(zone, *mPvdDataStream);
|
||||
mMutex.lock();
|
||||
client->createInstance();
|
||||
mProfileZoneClients.pushBack(client);
|
||||
mMutex.unlock();
|
||||
}
|
||||
|
||||
void PvdProfileZoneClient::onZoneRemoved(profile::PxProfileZone& zone)
|
||||
{
|
||||
for(uint32_t i = 0; i < mProfileZoneClients.size(); i++)
|
||||
{
|
||||
if(&zone == &mProfileZoneClients[i]->mZone)
|
||||
{
|
||||
mMutex.lock();
|
||||
ProfileZoneClient* client = mProfileZoneClients[i];
|
||||
mProfileZoneClients.replaceWithLast(i);
|
||||
PVD_DELETE(client);
|
||||
mMutex.unlock();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
75
physx/source/pvd/src/PxPvdProfileZoneClient.h
Normal file
75
physx/source/pvd/src/PxPvdProfileZoneClient.h
Normal file
@ -0,0 +1,75 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifndef PXPVDSDK_PXPVDPROFILEZONECLIENT_H
|
||||
#define PXPVDSDK_PXPVDPROFILEZONECLIENT_H
|
||||
#include "PxPvdClient.h"
|
||||
#include "PsHashMap.h"
|
||||
#include "PsMutex.h"
|
||||
#include "PxProfileZoneManager.h"
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace pvdsdk
|
||||
{
|
||||
class PvdImpl;
|
||||
class PvdDataStream;
|
||||
|
||||
struct ProfileZoneClient;
|
||||
|
||||
class PvdProfileZoneClient : public PvdClient, public profile::PxProfileZoneHandler, public shdfnd::UserAllocated
|
||||
{
|
||||
PX_NOCOPY(PvdProfileZoneClient)
|
||||
public:
|
||||
PvdProfileZoneClient(PvdImpl& pvd);
|
||||
virtual ~PvdProfileZoneClient();
|
||||
|
||||
bool isConnected() const;
|
||||
void onPvdConnected();
|
||||
void onPvdDisconnected();
|
||||
void flush();
|
||||
|
||||
PvdDataStream* getDataStream();
|
||||
|
||||
// PxProfileZoneHandler
|
||||
void onZoneAdded(profile::PxProfileZone& inSDK);
|
||||
void onZoneRemoved(profile::PxProfileZone& inSDK);
|
||||
|
||||
private:
|
||||
shdfnd::Mutex mMutex; // zoneAdded can called from different threads
|
||||
PvdImpl& mSDKPvd;
|
||||
PvdDataStream* mPvdDataStream;
|
||||
physx::shdfnd::Array<ProfileZoneClient*> mProfileZoneClients;
|
||||
bool mIsConnected;
|
||||
};
|
||||
|
||||
} // namespace pvdsdk
|
||||
} // namespace physx
|
||||
|
||||
#endif // PXPVDSDK_PXPVDPROFILEZONECLIENT_H
|
||||
385
physx/source/pvd/src/PxPvdUserRenderImpl.h
Normal file
385
physx/source/pvd/src/PxPvdUserRenderImpl.h
Normal file
@ -0,0 +1,385 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef PXPVDSDK_PXPVDUSERRENDERIMPL_H
|
||||
#define PXPVDSDK_PXPVDUSERRENDERIMPL_H
|
||||
|
||||
#include "PxPvdUserRenderer.h"
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace pvdsdk
|
||||
{
|
||||
|
||||
struct PvdUserRenderTypes
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Unknown = 0,
|
||||
#define DECLARE_PVD_IMMEDIATE_RENDER_TYPE(type) type,
|
||||
#define DECLARE_PVD_IMMEDIATE_RENDER_TYPE_NO_COMMA(type) type
|
||||
#include "PxPvdUserRenderTypes.h"
|
||||
#undef DECLARE_PVD_IMMEDIATE_RENDER_TYPE_NO_COMMA
|
||||
#undef DECLARE_PVD_IMMEDIATE_RENDER_TYPE
|
||||
};
|
||||
};
|
||||
|
||||
class RenderSerializer
|
||||
{
|
||||
protected:
|
||||
virtual ~RenderSerializer()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
virtual void streamify(uint64_t& val) = 0;
|
||||
virtual void streamify(float& val) = 0;
|
||||
virtual void streamify(uint32_t& val) = 0;
|
||||
virtual void streamify(uint8_t& val) = 0;
|
||||
virtual void streamify(DataRef<uint8_t>& val) = 0;
|
||||
virtual void streamify(DataRef<PvdDebugPoint>& val) = 0;
|
||||
virtual void streamify(DataRef<PvdDebugLine>& val) = 0;
|
||||
virtual void streamify(DataRef<PvdDebugTriangle>& val) = 0;
|
||||
virtual void streamify(PvdDebugText& val) = 0;
|
||||
virtual bool isGood() = 0;
|
||||
virtual uint32_t hasData() = 0;
|
||||
|
||||
void streamify(PvdUserRenderTypes::Enum& val)
|
||||
{
|
||||
uint8_t data = static_cast<uint8_t>(val);
|
||||
streamify(data);
|
||||
val = static_cast<PvdUserRenderTypes::Enum>(data);
|
||||
}
|
||||
void streamify(PxVec3& val)
|
||||
{
|
||||
streamify(val[0]);
|
||||
streamify(val[1]);
|
||||
streamify(val[2]);
|
||||
}
|
||||
|
||||
void streamify(PvdColor& val)
|
||||
{
|
||||
streamify(val.r);
|
||||
streamify(val.g);
|
||||
streamify(val.b);
|
||||
streamify(val.a);
|
||||
}
|
||||
void streamify(PxTransform& val)
|
||||
{
|
||||
streamify(val.q.x);
|
||||
streamify(val.q.y);
|
||||
streamify(val.q.z);
|
||||
streamify(val.q.w);
|
||||
streamify(val.p.x);
|
||||
streamify(val.p.y);
|
||||
streamify(val.p.z);
|
||||
}
|
||||
void streamify(bool& val)
|
||||
{
|
||||
uint8_t tempVal = uint8_t(val ? 1 : 0);
|
||||
streamify(tempVal);
|
||||
val = tempVal ? true : false;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TBulkRenderType>
|
||||
struct BulkRenderEvent
|
||||
{
|
||||
DataRef<TBulkRenderType> mData;
|
||||
BulkRenderEvent(const TBulkRenderType* data, uint32_t count) : mData(data, count)
|
||||
{
|
||||
}
|
||||
BulkRenderEvent()
|
||||
{
|
||||
}
|
||||
void serialize(RenderSerializer& serializer)
|
||||
{
|
||||
serializer.streamify(mData);
|
||||
}
|
||||
};
|
||||
struct SetInstanceIdRenderEvent
|
||||
{
|
||||
uint64_t mInstanceId;
|
||||
SetInstanceIdRenderEvent(uint64_t iid) : mInstanceId(iid)
|
||||
{
|
||||
}
|
||||
SetInstanceIdRenderEvent()
|
||||
{
|
||||
}
|
||||
void serialize(RenderSerializer& serializer)
|
||||
{
|
||||
serializer.streamify(mInstanceId);
|
||||
}
|
||||
};
|
||||
struct PointsRenderEvent : BulkRenderEvent<PvdDebugPoint>
|
||||
{
|
||||
PointsRenderEvent(const PvdDebugPoint* data, uint32_t count) : BulkRenderEvent<PvdDebugPoint>(data, count)
|
||||
{
|
||||
}
|
||||
PointsRenderEvent()
|
||||
{
|
||||
}
|
||||
};
|
||||
struct LinesRenderEvent : BulkRenderEvent<PvdDebugLine>
|
||||
{
|
||||
LinesRenderEvent(const PvdDebugLine* data, uint32_t count) : BulkRenderEvent<PvdDebugLine>(data, count)
|
||||
{
|
||||
}
|
||||
LinesRenderEvent()
|
||||
{
|
||||
}
|
||||
};
|
||||
struct TrianglesRenderEvent : BulkRenderEvent<PvdDebugTriangle>
|
||||
{
|
||||
TrianglesRenderEvent(const PvdDebugTriangle* data, uint32_t count) : BulkRenderEvent<PvdDebugTriangle>(data, count)
|
||||
{
|
||||
}
|
||||
TrianglesRenderEvent()
|
||||
{
|
||||
}
|
||||
};
|
||||
struct DebugRenderEvent
|
||||
{
|
||||
DataRef<PvdDebugPoint> mPointData;
|
||||
DataRef<PvdDebugLine> mLineData;
|
||||
DataRef<PvdDebugTriangle> mTriangleData;
|
||||
DebugRenderEvent(const PvdDebugPoint* pointData, uint32_t pointCount, const PvdDebugLine* lineData,
|
||||
uint32_t lineCount, const PvdDebugTriangle* triangleData, uint32_t triangleCount)
|
||||
: mPointData(pointData, pointCount), mLineData(lineData, lineCount), mTriangleData(triangleData, triangleCount)
|
||||
{
|
||||
}
|
||||
|
||||
DebugRenderEvent()
|
||||
{
|
||||
}
|
||||
void serialize(RenderSerializer& serializer)
|
||||
{
|
||||
serializer.streamify(mPointData);
|
||||
serializer.streamify(mLineData);
|
||||
serializer.streamify(mTriangleData);
|
||||
}
|
||||
};
|
||||
|
||||
struct TextRenderEvent
|
||||
{
|
||||
PvdDebugText mText;
|
||||
TextRenderEvent(const PvdDebugText& text)
|
||||
{
|
||||
mText.color = text.color;
|
||||
mText.position = text.position;
|
||||
mText.size = text.size;
|
||||
mText.string = text.string;
|
||||
}
|
||||
TextRenderEvent()
|
||||
{
|
||||
}
|
||||
void serialize(RenderSerializer& serializer)
|
||||
{
|
||||
serializer.streamify(mText);
|
||||
}
|
||||
};
|
||||
|
||||
struct JointFramesRenderEvent
|
||||
{
|
||||
PxTransform parent;
|
||||
PxTransform child;
|
||||
JointFramesRenderEvent(const PxTransform& p, const PxTransform& c) : parent(p), child(c)
|
||||
{
|
||||
}
|
||||
JointFramesRenderEvent()
|
||||
{
|
||||
}
|
||||
void serialize(RenderSerializer& serializer)
|
||||
{
|
||||
serializer.streamify(parent);
|
||||
serializer.streamify(child);
|
||||
}
|
||||
};
|
||||
struct LinearLimitRenderEvent
|
||||
{
|
||||
PxTransform t0;
|
||||
PxTransform t1;
|
||||
float value;
|
||||
bool active;
|
||||
LinearLimitRenderEvent(const PxTransform& _t0, const PxTransform& _t1, float _value, bool _active)
|
||||
: t0(_t0), t1(_t1), value(_value), active(_active)
|
||||
{
|
||||
}
|
||||
LinearLimitRenderEvent()
|
||||
{
|
||||
}
|
||||
void serialize(RenderSerializer& serializer)
|
||||
{
|
||||
serializer.streamify(t0);
|
||||
serializer.streamify(t1);
|
||||
serializer.streamify(value);
|
||||
serializer.streamify(active);
|
||||
}
|
||||
};
|
||||
struct AngularLimitRenderEvent
|
||||
{
|
||||
PxTransform t0;
|
||||
float lower;
|
||||
float upper;
|
||||
bool active;
|
||||
AngularLimitRenderEvent(const PxTransform& _t0, float _lower, float _upper, bool _active)
|
||||
: t0(_t0), lower(_lower), upper(_upper), active(_active)
|
||||
{
|
||||
}
|
||||
AngularLimitRenderEvent()
|
||||
{
|
||||
}
|
||||
void serialize(RenderSerializer& serializer)
|
||||
{
|
||||
serializer.streamify(t0);
|
||||
serializer.streamify(lower);
|
||||
serializer.streamify(upper);
|
||||
serializer.streamify(active);
|
||||
}
|
||||
};
|
||||
struct LimitConeRenderEvent
|
||||
{
|
||||
PxTransform t;
|
||||
float ySwing;
|
||||
float zSwing;
|
||||
bool active;
|
||||
LimitConeRenderEvent(const PxTransform& _t, float _ySwing, float _zSwing, bool _active)
|
||||
: t(_t), ySwing(_ySwing), zSwing(_zSwing), active(_active)
|
||||
{
|
||||
}
|
||||
LimitConeRenderEvent()
|
||||
{
|
||||
}
|
||||
void serialize(RenderSerializer& serializer)
|
||||
{
|
||||
serializer.streamify(t);
|
||||
serializer.streamify(ySwing);
|
||||
serializer.streamify(zSwing);
|
||||
serializer.streamify(active);
|
||||
}
|
||||
};
|
||||
struct DoubleConeRenderEvent
|
||||
{
|
||||
PxTransform t;
|
||||
float angle;
|
||||
bool active;
|
||||
DoubleConeRenderEvent(const PxTransform& _t, float _angle, bool _active) : t(_t), angle(_angle), active(_active)
|
||||
{
|
||||
}
|
||||
DoubleConeRenderEvent()
|
||||
{
|
||||
}
|
||||
void serialize(RenderSerializer& serializer)
|
||||
{
|
||||
serializer.streamify(t);
|
||||
serializer.streamify(angle);
|
||||
serializer.streamify(active);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TDataType>
|
||||
struct RenderSerializerMap
|
||||
{
|
||||
void serialize(RenderSerializer& s, TDataType& d)
|
||||
{
|
||||
d.serialize(s);
|
||||
}
|
||||
};
|
||||
template <>
|
||||
struct RenderSerializerMap<uint8_t>
|
||||
{
|
||||
void serialize(RenderSerializer& s, uint8_t& d)
|
||||
{
|
||||
s.streamify(d);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct RenderSerializerMap<PvdDebugPoint>
|
||||
{
|
||||
void serialize(RenderSerializer& s, PvdDebugPoint& d)
|
||||
{
|
||||
s.streamify(d.pos);
|
||||
s.streamify(d.color);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct RenderSerializerMap<PvdDebugLine>
|
||||
{
|
||||
void serialize(RenderSerializer& s, PvdDebugLine& d)
|
||||
{
|
||||
s.streamify(d.pos0);
|
||||
s.streamify(d.color0);
|
||||
s.streamify(d.pos1);
|
||||
s.streamify(d.color1);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct RenderSerializerMap<PvdDebugTriangle>
|
||||
{
|
||||
void serialize(RenderSerializer& s, PvdDebugTriangle& d)
|
||||
{
|
||||
s.streamify(d.pos0);
|
||||
s.streamify(d.color0);
|
||||
s.streamify(d.pos1);
|
||||
s.streamify(d.color1);
|
||||
s.streamify(d.pos2);
|
||||
s.streamify(d.color2);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TDataType>
|
||||
struct PvdTypeToRenderType
|
||||
{
|
||||
bool compile_error;
|
||||
};
|
||||
|
||||
#define DECLARE_PVD_IMMEDIATE_RENDER_TYPE(type) \
|
||||
template <> \
|
||||
struct PvdTypeToRenderType<type##RenderEvent> \
|
||||
{ \
|
||||
enum Enum \
|
||||
{ \
|
||||
EnumVal = PvdUserRenderTypes::type \
|
||||
}; \
|
||||
};
|
||||
|
||||
#include "PxPvdUserRenderTypes.h"
|
||||
#undef DECLARE_PVD_IMMEDIATE_RENDER_TYPE
|
||||
|
||||
template <typename TDataType>
|
||||
PvdUserRenderTypes::Enum getPvdRenderTypeFromType()
|
||||
{
|
||||
return static_cast<PvdUserRenderTypes::Enum>(PvdTypeToRenderType<TDataType>::EnumVal);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // PXPVDSDK_PXPVDUSERRENDERIMPL_H
|
||||
46
physx/source/pvd/src/PxPvdUserRenderTypes.h
Normal file
46
physx/source/pvd/src/PxPvdUserRenderTypes.h
Normal file
@ -0,0 +1,46 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
#define THERE_IS_NO_INCLUDE_GUARD_HERE_FOR_A_REASON
|
||||
|
||||
#ifndef DECLARE_PVD_IMMEDIATE_RENDER_TYPE_NO_COMMA
|
||||
#define DECLARE_PVD_IMMEDIATE_RENDER_TYPE_NO_COMMA DECLARE_PVD_IMMEDIATE_RENDER_TYPE
|
||||
#endif
|
||||
|
||||
DECLARE_PVD_IMMEDIATE_RENDER_TYPE(SetInstanceId)
|
||||
DECLARE_PVD_IMMEDIATE_RENDER_TYPE(Points)
|
||||
DECLARE_PVD_IMMEDIATE_RENDER_TYPE(Lines)
|
||||
DECLARE_PVD_IMMEDIATE_RENDER_TYPE(Triangles)
|
||||
DECLARE_PVD_IMMEDIATE_RENDER_TYPE(JointFrames)
|
||||
DECLARE_PVD_IMMEDIATE_RENDER_TYPE(LinearLimit)
|
||||
DECLARE_PVD_IMMEDIATE_RENDER_TYPE(AngularLimit)
|
||||
DECLARE_PVD_IMMEDIATE_RENDER_TYPE(LimitCone)
|
||||
DECLARE_PVD_IMMEDIATE_RENDER_TYPE(DoubleCone)
|
||||
DECLARE_PVD_IMMEDIATE_RENDER_TYPE(Text)
|
||||
DECLARE_PVD_IMMEDIATE_RENDER_TYPE_NO_COMMA(Debug)
|
||||
|
||||
#undef DECLARE_PVD_IMMEDIATE_RENDER_TYPE_NO_COMMA
|
||||
#undef THERE_IS_NO_INCLUDE_GUARD_HERE_FOR_A_REASON
|
||||
405
physx/source/pvd/src/PxPvdUserRenderer.cpp
Normal file
405
physx/source/pvd/src/PxPvdUserRenderer.cpp
Normal file
@ -0,0 +1,405 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "PxPvdUserRenderImpl.h"
|
||||
#include "PxPvdInternalByteStreams.h"
|
||||
#include "PxPvdBits.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
using namespace physx;
|
||||
using namespace physx::pvdsdk;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
template <typename TStreamType>
|
||||
struct RenderWriter : public RenderSerializer
|
||||
{
|
||||
TStreamType& mStream;
|
||||
RenderWriter(TStreamType& stream) : mStream(stream)
|
||||
{
|
||||
}
|
||||
template <typename TDataType>
|
||||
void write(const TDataType* val, uint32_t count)
|
||||
{
|
||||
uint32_t numBytes = count * sizeof(TDataType);
|
||||
mStream.write(reinterpret_cast<const uint8_t*>(val), numBytes);
|
||||
}
|
||||
template <typename TDataType>
|
||||
void write(const TDataType& val)
|
||||
{
|
||||
write(&val, 1);
|
||||
}
|
||||
|
||||
template <typename TDataType>
|
||||
void writeRef(DataRef<TDataType>& val)
|
||||
{
|
||||
uint32_t amount = val.size();
|
||||
write(amount);
|
||||
if(amount)
|
||||
write(val.begin(), amount);
|
||||
}
|
||||
|
||||
virtual void streamify(uint64_t& val)
|
||||
{
|
||||
write(val);
|
||||
}
|
||||
virtual void streamify(uint32_t& val)
|
||||
{
|
||||
write(val);
|
||||
}
|
||||
virtual void streamify(float& val)
|
||||
{
|
||||
write(val);
|
||||
}
|
||||
virtual void streamify(uint8_t& val)
|
||||
{
|
||||
write(val);
|
||||
}
|
||||
virtual void streamify(DataRef<uint8_t>& val)
|
||||
{
|
||||
writeRef(val);
|
||||
}
|
||||
|
||||
virtual void streamify(PvdDebugText& val)
|
||||
{
|
||||
write(val.color);
|
||||
write(val.position);
|
||||
write(val.size);
|
||||
|
||||
uint32_t amount = static_cast<uint32_t>(strlen(val.string)) + 1;
|
||||
write(amount);
|
||||
if(amount)
|
||||
write(val.string, amount);
|
||||
}
|
||||
|
||||
virtual void streamify(DataRef<PvdDebugPoint>& val)
|
||||
{
|
||||
writeRef(val);
|
||||
}
|
||||
virtual void streamify(DataRef<PvdDebugLine>& val)
|
||||
{
|
||||
writeRef(val);
|
||||
}
|
||||
virtual void streamify(DataRef<PvdDebugTriangle>& val)
|
||||
{
|
||||
writeRef(val);
|
||||
}
|
||||
|
||||
virtual uint32_t hasData()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual bool isGood()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
RenderWriter& operator=(const RenderWriter&);
|
||||
};
|
||||
|
||||
struct UserRenderer : public PvdUserRenderer
|
||||
{
|
||||
ForwardingMemoryBuffer mBuffer;
|
||||
uint32_t mBufferCapacity;
|
||||
RendererEventClient* mClient;
|
||||
|
||||
UserRenderer(uint32_t bufferFullAmount)
|
||||
: mBuffer("UserRenderBuffer"), mBufferCapacity(bufferFullAmount), mClient(NULL)
|
||||
{
|
||||
}
|
||||
virtual ~UserRenderer()
|
||||
{
|
||||
}
|
||||
virtual void release()
|
||||
{
|
||||
PVD_DELETE(this);
|
||||
}
|
||||
|
||||
template <typename TEventType>
|
||||
void handleEvent(TEventType evt)
|
||||
{
|
||||
RenderWriter<ForwardingMemoryBuffer> _writer(mBuffer);
|
||||
RenderSerializer& writer(_writer);
|
||||
|
||||
PvdUserRenderTypes::Enum evtType(getPvdRenderTypeFromType<TEventType>());
|
||||
writer.streamify(evtType);
|
||||
evt.serialize(writer);
|
||||
if(mBuffer.size() >= mBufferCapacity)
|
||||
flushRenderEvents();
|
||||
}
|
||||
virtual void setInstanceId(const void* iid)
|
||||
{
|
||||
handleEvent(SetInstanceIdRenderEvent(PVD_POINTER_TO_U64(iid)));
|
||||
}
|
||||
// Draw these points associated with this instance
|
||||
virtual void drawPoints(const PvdDebugPoint* points, uint32_t count)
|
||||
{
|
||||
handleEvent(PointsRenderEvent(points, count));
|
||||
}
|
||||
// Draw these lines associated with this instance
|
||||
virtual void drawLines(const PvdDebugLine* lines, uint32_t count)
|
||||
{
|
||||
handleEvent(LinesRenderEvent(lines, count));
|
||||
}
|
||||
// Draw these triangles associated with this instance
|
||||
virtual void drawTriangles(const PvdDebugTriangle* triangles, uint32_t count)
|
||||
{
|
||||
handleEvent(TrianglesRenderEvent(triangles, count));
|
||||
}
|
||||
|
||||
virtual void drawText(const PvdDebugText& text)
|
||||
{
|
||||
handleEvent(TextRenderEvent(text));
|
||||
}
|
||||
|
||||
virtual void drawRenderbuffer(const PvdDebugPoint* pointData, uint32_t pointCount, const PvdDebugLine* lineData,
|
||||
uint32_t lineCount, const PvdDebugTriangle* triangleData, uint32_t triangleCount)
|
||||
{
|
||||
handleEvent(DebugRenderEvent(pointData, pointCount, lineData, lineCount, triangleData, triangleCount));
|
||||
}
|
||||
|
||||
// Constraint visualization routines
|
||||
virtual void visualizeJointFrames(const PxTransform& parent, const PxTransform& child)
|
||||
{
|
||||
handleEvent(JointFramesRenderEvent(parent, child));
|
||||
}
|
||||
virtual void visualizeLinearLimit(const PxTransform& t0, const PxTransform& t1, float value, bool active)
|
||||
{
|
||||
handleEvent(LinearLimitRenderEvent(t0, t1, value, active));
|
||||
}
|
||||
virtual void visualizeAngularLimit(const PxTransform& t0, float lower, float upper, bool active)
|
||||
{
|
||||
handleEvent(AngularLimitRenderEvent(t0, lower, upper, active));
|
||||
}
|
||||
virtual void visualizeLimitCone(const PxTransform& t, float tanQSwingY, float tanQSwingZ, bool active)
|
||||
{
|
||||
handleEvent(LimitConeRenderEvent(t, tanQSwingY, tanQSwingZ, active));
|
||||
}
|
||||
virtual void visualizeDoubleCone(const PxTransform& t, float angle, bool active)
|
||||
{
|
||||
handleEvent(DoubleConeRenderEvent(t, angle, active));
|
||||
}
|
||||
// Clear the immedate buffer.
|
||||
virtual void flushRenderEvents()
|
||||
{
|
||||
if(mClient)
|
||||
mClient->handleBufferFlush(mBuffer.begin(), mBuffer.size());
|
||||
mBuffer.clear();
|
||||
}
|
||||
|
||||
virtual void setClient(RendererEventClient* client)
|
||||
{
|
||||
mClient = client;
|
||||
}
|
||||
|
||||
private:
|
||||
UserRenderer& operator=(const UserRenderer&);
|
||||
};
|
||||
|
||||
template <bool swapBytes>
|
||||
struct RenderReader : public RenderSerializer
|
||||
{
|
||||
MemPvdInputStream mStream;
|
||||
ForwardingMemoryBuffer& mBuffer;
|
||||
|
||||
RenderReader(ForwardingMemoryBuffer& buf) : mBuffer(buf)
|
||||
{
|
||||
}
|
||||
void setData(DataRef<const uint8_t> data)
|
||||
{
|
||||
mStream.setup(const_cast<uint8_t*>(data.begin()), const_cast<uint8_t*>(data.end()));
|
||||
}
|
||||
virtual void streamify(uint32_t& val)
|
||||
{
|
||||
mStream >> val;
|
||||
}
|
||||
virtual void streamify(uint64_t& val)
|
||||
{
|
||||
mStream >> val;
|
||||
}
|
||||
virtual void streamify(float& val)
|
||||
{
|
||||
mStream >> val;
|
||||
}
|
||||
virtual void streamify(uint8_t& val)
|
||||
{
|
||||
mStream >> val;
|
||||
}
|
||||
template <typename TDataType>
|
||||
void readRef(DataRef<TDataType>& val)
|
||||
{
|
||||
uint32_t count;
|
||||
mStream >> count;
|
||||
uint32_t numBytes = sizeof(TDataType) * count;
|
||||
|
||||
TDataType* dataPtr = reinterpret_cast<TDataType*>(mBuffer.growBuf(numBytes));
|
||||
mStream.read(reinterpret_cast<uint8_t*>(dataPtr), numBytes);
|
||||
val = DataRef<TDataType>(dataPtr, count);
|
||||
}
|
||||
|
||||
virtual void streamify(DataRef<PvdDebugPoint>& val)
|
||||
{
|
||||
readRef(val);
|
||||
}
|
||||
virtual void streamify(DataRef<PvdDebugLine>& val)
|
||||
{
|
||||
readRef(val);
|
||||
}
|
||||
virtual void streamify(DataRef<PvdDebugTriangle>& val)
|
||||
{
|
||||
readRef(val);
|
||||
}
|
||||
virtual void streamify(PvdDebugText& val)
|
||||
{
|
||||
mStream >> val.color;
|
||||
mStream >> val.position;
|
||||
mStream >> val.size;
|
||||
|
||||
uint32_t len = 0;
|
||||
mStream >> len;
|
||||
|
||||
uint8_t* dataPtr = mBuffer.growBuf(len);
|
||||
mStream.read(dataPtr, len);
|
||||
val.string = reinterpret_cast<const char*>(dataPtr);
|
||||
}
|
||||
virtual void streamify(DataRef<uint8_t>& val)
|
||||
{
|
||||
readRef(val);
|
||||
}
|
||||
virtual bool isGood()
|
||||
{
|
||||
return mStream.isGood();
|
||||
}
|
||||
virtual uint32_t hasData()
|
||||
{
|
||||
return uint32_t(mStream.size() > 0);
|
||||
}
|
||||
|
||||
private:
|
||||
RenderReader& operator=(const RenderReader&);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct RenderReader<true> : public RenderSerializer
|
||||
{
|
||||
MemPvdInputStream mStream;
|
||||
ForwardingMemoryBuffer& mBuffer;
|
||||
RenderReader(ForwardingMemoryBuffer& buf) : mBuffer(buf)
|
||||
{
|
||||
}
|
||||
void setData(DataRef<const uint8_t> data)
|
||||
{
|
||||
mStream.setup(const_cast<uint8_t*>(data.begin()), const_cast<uint8_t*>(data.end()));
|
||||
}
|
||||
|
||||
template <typename TDataType>
|
||||
void read(TDataType& val)
|
||||
{
|
||||
mStream >> val;
|
||||
swapBytes(val);
|
||||
}
|
||||
virtual void streamify(uint64_t& val)
|
||||
{
|
||||
read(val);
|
||||
}
|
||||
virtual void streamify(uint32_t& val)
|
||||
{
|
||||
read(val);
|
||||
}
|
||||
virtual void streamify(float& val)
|
||||
{
|
||||
read(val);
|
||||
}
|
||||
virtual void streamify(uint8_t& val)
|
||||
{
|
||||
read(val);
|
||||
}
|
||||
template <typename TDataType>
|
||||
void readRef(DataRef<TDataType>& val)
|
||||
{
|
||||
uint32_t count;
|
||||
mStream >> count;
|
||||
swapBytes(count);
|
||||
uint32_t numBytes = sizeof(TDataType) * count;
|
||||
|
||||
TDataType* dataPtr = reinterpret_cast<TDataType*>(mBuffer.growBuf(numBytes));
|
||||
PVD_FOREACH(idx, count)
|
||||
RenderSerializerMap<TDataType>().serialize(*this, dataPtr[idx]);
|
||||
val = DataRef<TDataType>(dataPtr, count);
|
||||
}
|
||||
|
||||
virtual void streamify(DataRef<PvdDebugPoint>& val)
|
||||
{
|
||||
readRef(val);
|
||||
}
|
||||
virtual void streamify(DataRef<PvdDebugLine>& val)
|
||||
{
|
||||
readRef(val);
|
||||
}
|
||||
virtual void streamify(DataRef<PvdDebugTriangle>& val)
|
||||
{
|
||||
readRef(val);
|
||||
}
|
||||
virtual void streamify(PvdDebugText& val)
|
||||
{
|
||||
mStream >> val.color;
|
||||
mStream >> val.position;
|
||||
mStream >> val.size;
|
||||
|
||||
uint32_t len = 0;
|
||||
mStream >> len;
|
||||
|
||||
uint8_t* dataPtr = mBuffer.growBuf(len);
|
||||
mStream.read(dataPtr, len);
|
||||
val.string = reinterpret_cast<const char*>(dataPtr);
|
||||
}
|
||||
virtual void streamify(DataRef<uint8_t>& val)
|
||||
{
|
||||
readRef(val);
|
||||
}
|
||||
virtual bool isGood()
|
||||
{
|
||||
return mStream.isGood();
|
||||
}
|
||||
virtual uint32_t hasData()
|
||||
{
|
||||
return uint32_t(mStream.size() > 0);
|
||||
}
|
||||
|
||||
private:
|
||||
RenderReader& operator=(const RenderReader&);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
PvdUserRenderer* PvdUserRenderer::create(uint32_t bufferSize)
|
||||
{
|
||||
return PVD_NEW(UserRenderer)(bufferSize);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user