RavEngine
Loading...
Searching...
No Matches
physx::profile::EventBuffer< TContextProvider, TMutex, TScopedLock, TEventFilter > Class Template Reference

#include <PxProfileEventBuffer.h>

Inheritance diagram for physx::profile::EventBuffer< TContextProvider, TMutex, TScopedLock, TEventFilter >:
[legend]
Collaboration diagram for physx::profile::EventBuffer< TContextProvider, TMutex, TScopedLock, TEventFilter >:
[legend]

Public Types

typedef DataBuffer< TMutex, TScopedLock > TBaseType
 
typedef TContextProvider TContextProviderType
 
typedef TEventFilter TEventFilterType
 
typedef TBaseType::TMutexType TMutexType
 
typedef TBaseType::TScopedLockType TScopedLockType
 
typedef TBaseType::TU8AllocatorType TU8AllocatorType
 
typedef TBaseType::TMemoryBufferType TMemoryBufferType
 
typedef TBaseType::TBufferClientArray TBufferClientArray
 
- Public Types inherited from physx::profile::DataBuffer< TMutex, TScopedLock >
typedef TMutex TMutexType
 
typedef TScopedLock TScopedLockType
 
typedef PxProfileWrapperNamedAllocator TU8AllocatorType
 
typedef MemoryBuffer< TU8AllocatorType > TMemoryBufferType
 
typedef PxProfileArray< PxProfileEventBufferClient * > TBufferClientArray
 

Public Member Functions

 EventBuffer (PxAllocatorCallback *inFoundation, uint32_t inBufferFullAmount, const TContextProvider &inProvider, TMutexType *inBufferMutex, const TEventFilterType &inEventFilter)
 
TContextProvider & getContextProvider ()
 
PX_FORCE_INLINE void startEvent (uint16_t inId, uint32_t threadId, uint64_t contextId, uint8_t cpuId, uint8_t threadPriority, uint64_t inTimestamp)
 
PX_FORCE_INLINE void startEvent (uint16_t inId, uint64_t contextId)
 
PX_FORCE_INLINE void startEvent (uint16_t inId, uint64_t contextId, uint32_t threadId)
 
PX_FORCE_INLINE void stopEvent (uint16_t inId, uint32_t threadId, uint64_t contextId, uint8_t cpuId, uint8_t threadPriority, uint64_t inTimestamp)
 
PX_FORCE_INLINE void stopEvent (uint16_t inId, uint64_t contextId)
 
PX_FORCE_INLINE void stopEvent (uint16_t inId, uint64_t contextId, uint32_t threadId)
 
void eventValue (uint16_t inId, uint64_t contextId, int64_t inValue)
 
void eventValue (uint16_t inId, uint32_t threadId, uint64_t contextId, int64_t inValue)
 
void flushProfileEvents ()
 
void release ()
 
- Public Member Functions inherited from physx::profile::DataBuffer< TMutex, TScopedLock >
 DataBuffer (PxAllocatorCallback *inFoundation, uint32_t inBufferFullAmount, TMutexType *inBufferMutex, const char *inAllocationName)
 
PxProfileAllocatorWrapper & getWrapper ()
 
TMutexType * getBufferMutex ()
 
void setBufferMutex (TMutexType *mutex)
 
void addClient (PxProfileEventBufferClient &inClient)
 
void removeClient (PxProfileEventBufferClient &inClient)
 
bool hasClients () const
 
virtual void flushEvents ()
 
virtual void handleBufferFlush (const uint8_t *inData, uint32_t inDataSize)
 

Protected Member Functions

void clearCachedData ()
 
template<typename TProfileEventType >
PX_FORCE_INLINE void doAddProfileEvent (uint16_t eventId, const TProfileEventType &inType)
 
template<typename TDataType >
PX_FORCE_INLINE void doAddEvent (uint8_t inEventType, uint16_t eventId, const TDataType &inType)
 
template<typename TDataType >
PX_FORCE_INLINE void sendEvent (EventHeader &inHeader, TDataType &inType)
 

Additional Inherited Members

- Protected Attributes inherited from physx::profile::DataBuffer< TMutex, TScopedLock >
PxProfileAllocatorWrapper mWrapper
 
TMemoryBufferType mDataArray
 
TBufferClientArray mBufferClients
 
uint32_t mBufferFullAmount
 
EventContextInformation mEventContextInformation
 
TMutexType * mBufferMutex
 
volatile bool mHasClients
 
EventSerializer< TMemoryBufferType > mSerializer
 

Detailed Description

template<typename TContextProvider, typename TMutex, typename TScopedLock, typename TEventFilter>
class physx::profile::EventBuffer< TContextProvider, TMutex, TScopedLock, TEventFilter >

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.

Member Function Documentation

◆ clearCachedData()

template<typename TContextProvider , typename TMutex , typename TScopedLock , typename TEventFilter >
void physx::profile::EventBuffer< TContextProvider, TMutex, TScopedLock, TEventFilter >::clearCachedData ( )
inlineprotectedvirtual

The documentation for this class was generated from the following file: