GRK/dependencies/physx-4.1/source/pvd/src/PxPvdImpl.cpp
secret_dude a7bd7ecb75 master
2022-01-12 16:07:16 +01:00

400 lines
9.7 KiB
C++

//
// 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-2019 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