Merge pull request #938 from erwincoumans/master
Move ChromeTracing in its own file, and add tracing support for VR se…
This commit is contained in:
@@ -192,7 +192,8 @@ files {
|
|||||||
"../ThirdPartyLibs/openvr/samples/shared/Vectors.h",
|
"../ThirdPartyLibs/openvr/samples/shared/Vectors.h",
|
||||||
"../Utils/b3Clock.cpp",
|
"../Utils/b3Clock.cpp",
|
||||||
"../Utils/b3Clock.h",
|
"../Utils/b3Clock.h",
|
||||||
|
"../Utils/ChromeTraceUtil.cpp",
|
||||||
|
"../Utils/ChromeTraceUtil.h",
|
||||||
}
|
}
|
||||||
|
|
||||||
if os.is("Windows") then
|
if os.is("Windows") then
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ ADD_LIBRARY(BulletExampleBrowserLib
|
|||||||
CollisionShape2TriangleMesh.h
|
CollisionShape2TriangleMesh.h
|
||||||
../Utils/b3Clock.cpp
|
../Utils/b3Clock.cpp
|
||||||
../Utils/b3Clock.h
|
../Utils/b3Clock.h
|
||||||
|
../Utils/ChromeTraceUtil.cpp
|
||||||
|
../Utils/ChromeTraceUtil.h
|
||||||
../Utils/b3ResourcePath.cpp
|
../Utils/b3ResourcePath.cpp
|
||||||
../Utils/b3ResourcePath.h
|
../Utils/b3ResourcePath.h
|
||||||
../Utils/b3ERPCFMHelper.hpp
|
../Utils/b3ERPCFMHelper.hpp
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include "GwenGUISupport/gwenInternalData.h"
|
#include "GwenGUISupport/gwenInternalData.h"
|
||||||
#include "GwenGUISupport/gwenUserInterface.h"
|
#include "GwenGUISupport/gwenUserInterface.h"
|
||||||
#include "../Utils/b3Clock.h"
|
#include "../Utils/b3Clock.h"
|
||||||
|
#include "../Utils/ChromeTraceUtil.h"
|
||||||
#include "GwenGUISupport/GwenParameterInterface.h"
|
#include "GwenGUISupport/GwenParameterInterface.h"
|
||||||
#ifndef BT_NO_PROFILE
|
#ifndef BT_NO_PROFILE
|
||||||
#include "GwenGUISupport/GwenProfileWindow.h"
|
#include "GwenGUISupport/GwenProfileWindow.h"
|
||||||
@@ -148,227 +149,6 @@ int gGpuArraySizeZ=45;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct btTiming
|
|
||||||
{
|
|
||||||
const char* m_name;
|
|
||||||
int m_threadId;
|
|
||||||
unsigned long long int m_usStartTime;
|
|
||||||
unsigned long long int m_usEndTime;
|
|
||||||
};
|
|
||||||
|
|
||||||
FILE* gTimingFile = 0;
|
|
||||||
#ifndef __STDC_FORMAT_MACROS
|
|
||||||
#define __STDC_FORMAT_MACROS
|
|
||||||
#endif //__STDC_FORMAT_MACROS
|
|
||||||
|
|
||||||
//see http://stackoverflow.com/questions/18107426/printf-format-for-unsigned-int64-on-windows
|
|
||||||
#ifndef _WIN32
|
|
||||||
#include <inttypes.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define BT_TIMING_CAPACITY 16*65536
|
|
||||||
static bool m_firstTiming = true;
|
|
||||||
|
|
||||||
|
|
||||||
struct btTimings
|
|
||||||
{
|
|
||||||
btTimings()
|
|
||||||
:m_numTimings(0),
|
|
||||||
m_activeBuffer(0)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
void flush()
|
|
||||||
{
|
|
||||||
for (int i=0;i<m_numTimings;i++)
|
|
||||||
{
|
|
||||||
const char* name = m_timings[m_activeBuffer][i].m_name;
|
|
||||||
int threadId = m_timings[m_activeBuffer][i].m_threadId;
|
|
||||||
unsigned long long int startTime = m_timings[m_activeBuffer][i].m_usStartTime;
|
|
||||||
unsigned long long int endTime = m_timings[m_activeBuffer][i].m_usEndTime;
|
|
||||||
|
|
||||||
if (!m_firstTiming)
|
|
||||||
{
|
|
||||||
fprintf(gTimingFile,",\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
m_firstTiming = false;
|
|
||||||
|
|
||||||
unsigned long long int startTimeDiv1000 = startTime/1000;
|
|
||||||
unsigned long long int endTimeDiv1000 = endTime/1000;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
fprintf(gTimingFile,"{\"cat\":\"timing\",\"pid\":1,\"tid\":%d,\"ts\":%" PRIu64 ".123 ,\"ph\":\"B\",\"name\":\"%s\",\"args\":{}},\n",
|
|
||||||
threadId, startTimeDiv1000, name);
|
|
||||||
fprintf(gTimingFile,"{\"cat\":\"timing\",\"pid\":1,\"tid\":%d,\"ts\":%" PRIu64 ".234 ,\"ph\":\"E\",\"name\":\"%s\",\"args\":{}}",
|
|
||||||
threadId, endTimeDiv1000,name);
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
|
|
||||||
if (startTime>endTime)
|
|
||||||
{
|
|
||||||
endTime = startTime;
|
|
||||||
}
|
|
||||||
unsigned int startTimeRem1000 = startTime%1000;
|
|
||||||
unsigned int endTimeRem1000 = endTime%1000;
|
|
||||||
|
|
||||||
char startTimeRem1000Str[16];
|
|
||||||
char endTimeRem1000Str[16];
|
|
||||||
|
|
||||||
if (startTimeRem1000<10)
|
|
||||||
{
|
|
||||||
sprintf(startTimeRem1000Str,"00%d",startTimeRem1000);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (startTimeRem1000<100)
|
|
||||||
{
|
|
||||||
sprintf(startTimeRem1000Str,"0%d",startTimeRem1000);
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
sprintf(startTimeRem1000Str,"%d",startTimeRem1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (endTimeRem1000<10)
|
|
||||||
{
|
|
||||||
sprintf(endTimeRem1000Str,"00%d",endTimeRem1000);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (endTimeRem1000<100)
|
|
||||||
{
|
|
||||||
sprintf(endTimeRem1000Str,"0%d",endTimeRem1000);
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
sprintf(endTimeRem1000Str,"%d",endTimeRem1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char newname[1024];
|
|
||||||
static int counter2=0;
|
|
||||||
sprintf(newname,"%s%d",name,counter2++);
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
|
|
||||||
fprintf(gTimingFile,"{\"cat\":\"timing\",\"pid\":1,\"tid\":%d,\"ts\":%I64d.%s ,\"ph\":\"B\",\"name\":\"%s\",\"args\":{}},\n",
|
|
||||||
threadId, startTimeDiv1000,startTimeRem1000Str, newname);
|
|
||||||
fprintf(gTimingFile,"{\"cat\":\"timing\",\"pid\":1,\"tid\":%d,\"ts\":%I64d.%s ,\"ph\":\"E\",\"name\":\"%s\",\"args\":{}}",
|
|
||||||
threadId, endTimeDiv1000,endTimeRem1000Str,newname);
|
|
||||||
|
|
||||||
#else
|
|
||||||
fprintf(gTimingFile,"{\"cat\":\"timing\",\"pid\":1,\"tid\":%d,\"ts\":%" PRIu64 ".%s ,\"ph\":\"B\",\"name\":\"%s\",\"args\":{}},\n",
|
|
||||||
threadId, startTimeDiv1000,startTimeRem1000Str, newname);
|
|
||||||
fprintf(gTimingFile,"{\"cat\":\"timing\",\"pid\":1,\"tid\":%d,\"ts\":%" PRIu64 ".%s ,\"ph\":\"E\",\"name\":\"%s\",\"args\":{}}",
|
|
||||||
threadId, endTimeDiv1000,endTimeRem1000Str,newname);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
m_numTimings = 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void addTiming(const char* name, int threadId, unsigned long long int startTime, unsigned long long int endTime)
|
|
||||||
{
|
|
||||||
if (m_numTimings>=BT_TIMING_CAPACITY)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_timings[0].size()==0)
|
|
||||||
{
|
|
||||||
m_timings[0].resize(BT_TIMING_CAPACITY);
|
|
||||||
}
|
|
||||||
|
|
||||||
int slot = m_numTimings++;
|
|
||||||
|
|
||||||
m_timings[m_activeBuffer][slot].m_name = name;
|
|
||||||
m_timings[m_activeBuffer][slot].m_threadId = threadId;
|
|
||||||
m_timings[m_activeBuffer][slot].m_usStartTime = startTime;
|
|
||||||
m_timings[m_activeBuffer][slot].m_usEndTime = endTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int m_numTimings;
|
|
||||||
int m_activeBuffer;
|
|
||||||
btAlignedObjectArray<btTiming> m_timings[1];
|
|
||||||
};
|
|
||||||
#ifndef BT_NO_PROFILE
|
|
||||||
btTimings gTimings[BT_QUICKPROF_MAX_THREAD_COUNT];
|
|
||||||
#define MAX_NESTING 1024
|
|
||||||
int gStackDepths[BT_QUICKPROF_MAX_THREAD_COUNT] = {0};
|
|
||||||
const char* gFuncNames[BT_QUICKPROF_MAX_THREAD_COUNT][MAX_NESTING];
|
|
||||||
unsigned long long int gStartTimes[BT_QUICKPROF_MAX_THREAD_COUNT][MAX_NESTING];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
btClock clk;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool gProfileDisabled = true;
|
|
||||||
|
|
||||||
|
|
||||||
void MyDummyEnterProfileZoneFunc(const char* msg)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void MyDummyLeaveProfileZoneFunc()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void MyEnterProfileZoneFunc(const char* msg)
|
|
||||||
{
|
|
||||||
if (gProfileDisabled)
|
|
||||||
return;
|
|
||||||
#ifndef BT_NO_PROFILE
|
|
||||||
int threadId = btQuickprofGetCurrentThreadIndex2();
|
|
||||||
if (threadId<0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (gStackDepths[threadId]>=MAX_NESTING)
|
|
||||||
{
|
|
||||||
btAssert(0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
gFuncNames[threadId][gStackDepths[threadId]] = msg;
|
|
||||||
gStartTimes[threadId][gStackDepths[threadId]] = clk.getTimeNanoseconds();
|
|
||||||
if (gStartTimes[threadId][gStackDepths[threadId]]<=gStartTimes[threadId][gStackDepths[threadId]-1])
|
|
||||||
{
|
|
||||||
gStartTimes[threadId][gStackDepths[threadId]]=1+gStartTimes[threadId][gStackDepths[threadId]-1];
|
|
||||||
}
|
|
||||||
gStackDepths[threadId]++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
void MyLeaveProfileZoneFunc()
|
|
||||||
{
|
|
||||||
if (gProfileDisabled)
|
|
||||||
return;
|
|
||||||
#ifndef BT_NO_PROFILE
|
|
||||||
int threadId = btQuickprofGetCurrentThreadIndex2();
|
|
||||||
if (threadId<0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (gStackDepths[threadId]<=0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
gStackDepths[threadId]--;
|
|
||||||
|
|
||||||
const char* name = gFuncNames[threadId][gStackDepths[threadId]];
|
|
||||||
unsigned long long int startTime = gStartTimes[threadId][gStackDepths[threadId]];
|
|
||||||
|
|
||||||
unsigned long long int endTime = clk.getTimeNanoseconds();
|
|
||||||
gTimings[threadId].addTiming(name,threadId,startTime,endTime);
|
|
||||||
#endif //BT_NO_PROFILE
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void deleteDemo()
|
void deleteDemo()
|
||||||
{
|
{
|
||||||
if (sCurrentDemo)
|
if (sCurrentDemo)
|
||||||
@@ -469,40 +249,12 @@ void MyKeyboardCallback(int key, int state)
|
|||||||
#ifndef BT_NO_PROFILE
|
#ifndef BT_NO_PROFILE
|
||||||
if (state)
|
if (state)
|
||||||
{
|
{
|
||||||
m_firstTiming = true;
|
b3ChromeUtilsStartTimings();
|
||||||
gProfileDisabled = false;//true;
|
|
||||||
b3SetCustomEnterProfileZoneFunc(MyEnterProfileZoneFunc);
|
|
||||||
b3SetCustomLeaveProfileZoneFunc(MyLeaveProfileZoneFunc);
|
|
||||||
|
|
||||||
//also for Bullet 2.x API
|
|
||||||
btSetCustomEnterProfileZoneFunc(MyEnterProfileZoneFunc);
|
|
||||||
btSetCustomLeaveProfileZoneFunc(MyLeaveProfileZoneFunc);
|
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
|
|
||||||
b3SetCustomEnterProfileZoneFunc(MyDummyEnterProfileZoneFunc);
|
b3ChromeUtilsStopTimingsAndWriteJsonFile();
|
||||||
b3SetCustomLeaveProfileZoneFunc(MyDummyLeaveProfileZoneFunc);
|
|
||||||
//also for Bullet 2.x API
|
|
||||||
btSetCustomEnterProfileZoneFunc(MyDummyEnterProfileZoneFunc);
|
|
||||||
btSetCustomLeaveProfileZoneFunc(MyDummyLeaveProfileZoneFunc);
|
|
||||||
char fileName[1024];
|
|
||||||
static int fileCounter = 0;
|
|
||||||
sprintf(fileName,"timings_%d.json",fileCounter++);
|
|
||||||
gTimingFile = fopen(fileName,"w");
|
|
||||||
fprintf(gTimingFile,"{\"traceEvents\":[\n");
|
|
||||||
//dump the content to file
|
|
||||||
for (int i=0;i<BT_QUICKPROF_MAX_THREAD_COUNT;i++)
|
|
||||||
{
|
|
||||||
if (gTimings[i].m_numTimings)
|
|
||||||
{
|
|
||||||
printf("Writing %d timings for thread %d\n", gTimings[i].m_numTimings, i);
|
|
||||||
gTimings[i].flush();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fprintf(gTimingFile,"\n],\n\"displayTimeUnit\": \"ns\"}");
|
|
||||||
fclose(gTimingFile);
|
|
||||||
gTimingFile = 0;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif //BT_NO_PROFILE
|
#endif //BT_NO_PROFILE
|
||||||
}
|
}
|
||||||
@@ -1063,14 +815,7 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
if (args.CheckCmdLineFlag("tracing"))
|
if (args.CheckCmdLineFlag("tracing"))
|
||||||
{
|
{
|
||||||
m_firstTiming = true;
|
b3ChromeUtilsStartTimings();
|
||||||
gProfileDisabled = false;//true;
|
|
||||||
b3SetCustomEnterProfileZoneFunc(MyEnterProfileZoneFunc);
|
|
||||||
b3SetCustomLeaveProfileZoneFunc(MyLeaveProfileZoneFunc);
|
|
||||||
|
|
||||||
//also for Bullet 2.x API
|
|
||||||
btSetCustomEnterProfileZoneFunc(MyEnterProfileZoneFunc);
|
|
||||||
btSetCustomLeaveProfileZoneFunc(MyLeaveProfileZoneFunc);
|
|
||||||
}
|
}
|
||||||
args.GetCmdLineArgument("fixed_timestep",gFixedTimeStep);
|
args.GetCmdLineArgument("fixed_timestep",gFixedTimeStep);
|
||||||
args.GetCmdLineArgument("png_skip_frames", gPngSkipFrames);
|
args.GetCmdLineArgument("png_skip_frames", gPngSkipFrames);
|
||||||
@@ -1378,8 +1123,8 @@ bool OpenGLExampleBrowser::requestedExit()
|
|||||||
|
|
||||||
void OpenGLExampleBrowser::update(float deltaTime)
|
void OpenGLExampleBrowser::update(float deltaTime)
|
||||||
{
|
{
|
||||||
gProfileDisabled = false;
|
b3ChromeUtilsEnableProfiling();
|
||||||
|
|
||||||
B3_PROFILE("OpenGLExampleBrowser::update");
|
B3_PROFILE("OpenGLExampleBrowser::update");
|
||||||
assert(glGetError()==GL_NO_ERROR);
|
assert(glGetError()==GL_NO_ERROR);
|
||||||
s_instancingRenderer->init();
|
s_instancingRenderer->init();
|
||||||
|
|||||||
@@ -193,6 +193,8 @@ project "BulletExampleBrowserLib"
|
|||||||
"OpenGLGuiHelper.cpp",
|
"OpenGLGuiHelper.cpp",
|
||||||
"OpenGLExampleBrowser.cpp",
|
"OpenGLExampleBrowser.cpp",
|
||||||
"../Utils/b3Clock.cpp",
|
"../Utils/b3Clock.cpp",
|
||||||
|
"../Utils/ChromeTraceUtil.cpp",
|
||||||
|
"../Utils/ChromeTraceUtil.h",
|
||||||
"*.h",
|
"*.h",
|
||||||
"GwenGUISupport/*.cpp",
|
"GwenGUISupport/*.cpp",
|
||||||
"GwenGUISupport/*.h",
|
"GwenGUISupport/*.h",
|
||||||
|
|||||||
@@ -61,6 +61,8 @@ SET(SharedMemory_SRCS
|
|||||||
../Importers/ImportMJCFDemo/BulletMJCFImporter.h
|
../Importers/ImportMJCFDemo/BulletMJCFImporter.h
|
||||||
../Utils/b3ResourcePath.cpp
|
../Utils/b3ResourcePath.cpp
|
||||||
../Utils/b3Clock.cpp
|
../Utils/b3Clock.cpp
|
||||||
|
../Utils/ChromeTraceUtil.cpp
|
||||||
|
../Utils/ChromeTraceUtil.h
|
||||||
../Importers/ImportURDFDemo/URDFImporterInterface.h
|
../Importers/ImportURDFDemo/URDFImporterInterface.h
|
||||||
../Importers/ImportURDFDemo/URDFJointTypes.h
|
../Importers/ImportURDFDemo/URDFJointTypes.h
|
||||||
../Importers/ImportObjDemo/Wavefront2GLInstanceGraphicsShape.cpp
|
../Importers/ImportObjDemo/Wavefront2GLInstanceGraphicsShape.cpp
|
||||||
|
|||||||
@@ -300,7 +300,6 @@ void MotionThreadFunc(void* userPtr,void* lsMemory)
|
|||||||
|
|
||||||
double deltaTimeInSeconds = 0;
|
double deltaTimeInSeconds = 0;
|
||||||
double sleepCounter = 0;
|
double sleepCounter = 0;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
BT_PROFILE("loop");
|
BT_PROFILE("loop");
|
||||||
@@ -310,6 +309,8 @@ void MotionThreadFunc(void* userPtr,void* lsMemory)
|
|||||||
b3Clock::usleep(0);
|
b3Clock::usleep(0);
|
||||||
}
|
}
|
||||||
double dt = double(clock.getTimeMicroseconds())/1000000.;
|
double dt = double(clock.getTimeMicroseconds())/1000000.;
|
||||||
|
clock.reset();
|
||||||
|
|
||||||
sleepCounter+=dt;
|
sleepCounter+=dt;
|
||||||
|
|
||||||
if (sleepCounter > sleepTimeThreshold)
|
if (sleepCounter > sleepTimeThreshold)
|
||||||
@@ -317,10 +318,18 @@ void MotionThreadFunc(void* userPtr,void* lsMemory)
|
|||||||
BT_PROFILE("usleep(100)");
|
BT_PROFILE("usleep(100)");
|
||||||
sleepCounter = 0;
|
sleepCounter = 0;
|
||||||
b3Clock::usleep(100);
|
b3Clock::usleep(100);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
if (gEnableRealTimeSimVR)
|
||||||
|
{
|
||||||
|
BT_PROFILE("usleep(1000)");
|
||||||
|
b3Clock::usleep(1000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
deltaTimeInSeconds+= dt;
|
deltaTimeInSeconds+= dt;
|
||||||
|
|
||||||
clock.reset();
|
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -77,6 +77,8 @@ myfiles =
|
|||||||
"../Importers/ImportMJCFDemo/BulletMJCFImporter.h",
|
"../Importers/ImportMJCFDemo/BulletMJCFImporter.h",
|
||||||
"../Utils/b3ResourcePath.cpp",
|
"../Utils/b3ResourcePath.cpp",
|
||||||
"../Utils/b3Clock.cpp",
|
"../Utils/b3Clock.cpp",
|
||||||
|
"../Utils/ChromeTraceUtil.cpp",
|
||||||
|
"../Utils/ChromeTraceUtil.h",
|
||||||
"../../Extras/Serialize/BulletWorldImporter/*",
|
"../../Extras/Serialize/BulletWorldImporter/*",
|
||||||
"../../Extras/Serialize/BulletFileLoader/*",
|
"../../Extras/Serialize/BulletFileLoader/*",
|
||||||
"../Importers/ImportURDFDemo/URDFImporterInterface.h",
|
"../Importers/ImportURDFDemo/URDFImporterInterface.h",
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include "Bullet3Common/b3CommandLineArgs.h"
|
#include "Bullet3Common/b3CommandLineArgs.h"
|
||||||
|
|
||||||
#include "../Utils/b3Clock.h"
|
#include "../Utils/b3Clock.h"
|
||||||
|
#include "../Utils/ChromeTraceUtil.h"
|
||||||
#include "../ExampleBrowser/OpenGLGuiHelper.h"
|
#include "../ExampleBrowser/OpenGLGuiHelper.h"
|
||||||
#include "../CommonInterfaces/CommonExampleInterface.h"
|
#include "../CommonInterfaces/CommonExampleInterface.h"
|
||||||
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
|
#include "../CommonInterfaces/CommonGUIHelperInterface.h"
|
||||||
@@ -344,6 +345,17 @@ b3KeyboardCallback prevKeyboardCallback = 0;
|
|||||||
|
|
||||||
void MyKeyboardCallback(int key, int state)
|
void MyKeyboardCallback(int key, int state)
|
||||||
{
|
{
|
||||||
|
if (key == 'p')
|
||||||
|
{
|
||||||
|
if (state)
|
||||||
|
{
|
||||||
|
b3ChromeUtilsStartTimings();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
b3ChromeUtilsStopTimingsAndWriteJsonFile();
|
||||||
|
}
|
||||||
|
}
|
||||||
if (sExample)
|
if (sExample)
|
||||||
{
|
{
|
||||||
sExample->keyboardCallback(key,state);
|
sExample->keyboardCallback(key,state);
|
||||||
@@ -794,6 +806,7 @@ void CMainApplication::RunMainLoop()
|
|||||||
|
|
||||||
while ( !bQuit && !m_app->m_window->requestedExit())
|
while ( !bQuit && !m_app->m_window->requestedExit())
|
||||||
{
|
{
|
||||||
|
b3ChromeUtilsEnableProfiling();
|
||||||
{
|
{
|
||||||
B3_PROFILE("main");
|
B3_PROFILE("main");
|
||||||
|
|
||||||
@@ -2241,6 +2254,12 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
gDisableDesktopGL = true;
|
gDisableDesktopGL = true;
|
||||||
}
|
}
|
||||||
|
if (args.CheckCmdLineFlag("tracing"))
|
||||||
|
{
|
||||||
|
b3ChromeUtilsStartTimings();
|
||||||
|
b3ChromeUtilsEnableProfiling();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef BT_USE_CUSTOM_PROFILER
|
#ifdef BT_USE_CUSTOM_PROFILER
|
||||||
b3SetCustomEnterProfileZoneFunc(dcEnter);
|
b3SetCustomEnterProfileZoneFunc(dcEnter);
|
||||||
@@ -2280,8 +2299,11 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
pMainApplication->Shutdown();
|
pMainApplication->Shutdown();
|
||||||
|
|
||||||
#ifdef BT_USE_CUSTOM_PROFILER
|
if (args.CheckCmdLineFlag("tracing"))
|
||||||
#endif
|
{
|
||||||
|
b3ChromeUtilsStopTimingsAndWriteJsonFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
272
examples/Utils/ChromeTraceUtil.cpp
Normal file
272
examples/Utils/ChromeTraceUtil.cpp
Normal file
@@ -0,0 +1,272 @@
|
|||||||
|
|
||||||
|
#include "ChromeTraceUtil.h"
|
||||||
|
#include "b3Clock.h"
|
||||||
|
#include "LinearMath/btQuickprof.h"
|
||||||
|
#include "LinearMath/btAlignedObjectArray.h"
|
||||||
|
#include "Bullet3Common/b3Logging.h"
|
||||||
|
|
||||||
|
struct btTiming
|
||||||
|
{
|
||||||
|
const char* m_name;
|
||||||
|
int m_threadId;
|
||||||
|
unsigned long long int m_usStartTime;
|
||||||
|
unsigned long long int m_usEndTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
FILE* gTimingFile = 0;
|
||||||
|
#ifndef __STDC_FORMAT_MACROS
|
||||||
|
#define __STDC_FORMAT_MACROS
|
||||||
|
#endif //__STDC_FORMAT_MACROS
|
||||||
|
|
||||||
|
//see http://stackoverflow.com/questions/18107426/printf-format-for-unsigned-int64-on-windows
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <inttypes.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define BT_TIMING_CAPACITY 16*65536
|
||||||
|
static bool m_firstTiming = true;
|
||||||
|
|
||||||
|
|
||||||
|
struct btTimings
|
||||||
|
{
|
||||||
|
btTimings()
|
||||||
|
:m_numTimings(0),
|
||||||
|
m_activeBuffer(0)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
void flush()
|
||||||
|
{
|
||||||
|
for (int i = 0; i<m_numTimings; i++)
|
||||||
|
{
|
||||||
|
const char* name = m_timings[m_activeBuffer][i].m_name;
|
||||||
|
int threadId = m_timings[m_activeBuffer][i].m_threadId;
|
||||||
|
unsigned long long int startTime = m_timings[m_activeBuffer][i].m_usStartTime;
|
||||||
|
unsigned long long int endTime = m_timings[m_activeBuffer][i].m_usEndTime;
|
||||||
|
|
||||||
|
if (!m_firstTiming)
|
||||||
|
{
|
||||||
|
fprintf(gTimingFile, ",\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_firstTiming = false;
|
||||||
|
|
||||||
|
unsigned long long int startTimeDiv1000 = startTime / 1000;
|
||||||
|
unsigned long long int endTimeDiv1000 = endTime / 1000;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
fprintf(gTimingFile, "{\"cat\":\"timing\",\"pid\":1,\"tid\":%d,\"ts\":%" PRIu64 ".123 ,\"ph\":\"B\",\"name\":\"%s\",\"args\":{}},\n",
|
||||||
|
threadId, startTimeDiv1000, name);
|
||||||
|
fprintf(gTimingFile, "{\"cat\":\"timing\",\"pid\":1,\"tid\":%d,\"ts\":%" PRIu64 ".234 ,\"ph\":\"E\",\"name\":\"%s\",\"args\":{}}",
|
||||||
|
threadId, endTimeDiv1000, name);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
|
||||||
|
if (startTime>endTime)
|
||||||
|
{
|
||||||
|
endTime = startTime;
|
||||||
|
}
|
||||||
|
unsigned int startTimeRem1000 = startTime % 1000;
|
||||||
|
unsigned int endTimeRem1000 = endTime % 1000;
|
||||||
|
|
||||||
|
char startTimeRem1000Str[16];
|
||||||
|
char endTimeRem1000Str[16];
|
||||||
|
|
||||||
|
if (startTimeRem1000<10)
|
||||||
|
{
|
||||||
|
sprintf(startTimeRem1000Str, "00%d", startTimeRem1000);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (startTimeRem1000<100)
|
||||||
|
{
|
||||||
|
sprintf(startTimeRem1000Str, "0%d", startTimeRem1000);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprintf(startTimeRem1000Str, "%d", startTimeRem1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (endTimeRem1000<10)
|
||||||
|
{
|
||||||
|
sprintf(endTimeRem1000Str, "00%d", endTimeRem1000);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (endTimeRem1000<100)
|
||||||
|
{
|
||||||
|
sprintf(endTimeRem1000Str, "0%d", endTimeRem1000);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprintf(endTimeRem1000Str, "%d", endTimeRem1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char newname[1024];
|
||||||
|
static int counter2 = 0;
|
||||||
|
sprintf(newname, "%s%d", name, counter2++);
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
fprintf(gTimingFile, "{\"cat\":\"timing\",\"pid\":1,\"tid\":%d,\"ts\":%I64d.%s ,\"ph\":\"B\",\"name\":\"%s\",\"args\":{}},\n",
|
||||||
|
threadId, startTimeDiv1000, startTimeRem1000Str, newname);
|
||||||
|
fprintf(gTimingFile, "{\"cat\":\"timing\",\"pid\":1,\"tid\":%d,\"ts\":%I64d.%s ,\"ph\":\"E\",\"name\":\"%s\",\"args\":{}}",
|
||||||
|
threadId, endTimeDiv1000, endTimeRem1000Str, newname);
|
||||||
|
|
||||||
|
#else
|
||||||
|
fprintf(gTimingFile, "{\"cat\":\"timing\",\"pid\":1,\"tid\":%d,\"ts\":%" PRIu64 ".%s ,\"ph\":\"B\",\"name\":\"%s\",\"args\":{}},\n",
|
||||||
|
threadId, startTimeDiv1000, startTimeRem1000Str, newname);
|
||||||
|
fprintf(gTimingFile, "{\"cat\":\"timing\",\"pid\":1,\"tid\":%d,\"ts\":%" PRIu64 ".%s ,\"ph\":\"E\",\"name\":\"%s\",\"args\":{}}",
|
||||||
|
threadId, endTimeDiv1000, endTimeRem1000Str, newname);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
m_numTimings = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void addTiming(const char* name, int threadId, unsigned long long int startTime, unsigned long long int endTime)
|
||||||
|
{
|
||||||
|
if (m_numTimings >= BT_TIMING_CAPACITY)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_timings[0].size() == 0)
|
||||||
|
{
|
||||||
|
m_timings[0].resize(BT_TIMING_CAPACITY);
|
||||||
|
}
|
||||||
|
|
||||||
|
int slot = m_numTimings++;
|
||||||
|
|
||||||
|
m_timings[m_activeBuffer][slot].m_name = name;
|
||||||
|
m_timings[m_activeBuffer][slot].m_threadId = threadId;
|
||||||
|
m_timings[m_activeBuffer][slot].m_usStartTime = startTime;
|
||||||
|
m_timings[m_activeBuffer][slot].m_usEndTime = endTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int m_numTimings;
|
||||||
|
int m_activeBuffer;
|
||||||
|
btAlignedObjectArray<btTiming> m_timings[1];
|
||||||
|
};
|
||||||
|
#ifndef BT_NO_PROFILE
|
||||||
|
btTimings gTimings[BT_QUICKPROF_MAX_THREAD_COUNT];
|
||||||
|
#define MAX_NESTING 1024
|
||||||
|
int gStackDepths[BT_QUICKPROF_MAX_THREAD_COUNT] = { 0 };
|
||||||
|
const char* gFuncNames[BT_QUICKPROF_MAX_THREAD_COUNT][MAX_NESTING];
|
||||||
|
unsigned long long int gStartTimes[BT_QUICKPROF_MAX_THREAD_COUNT][MAX_NESTING];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
btClock clk;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool gProfileDisabled = true;
|
||||||
|
|
||||||
|
|
||||||
|
void MyDummyEnterProfileZoneFunc(const char* msg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyDummyLeaveProfileZoneFunc()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyEnterProfileZoneFunc(const char* msg)
|
||||||
|
{
|
||||||
|
if (gProfileDisabled)
|
||||||
|
return;
|
||||||
|
#ifndef BT_NO_PROFILE
|
||||||
|
int threadId = btQuickprofGetCurrentThreadIndex2();
|
||||||
|
if (threadId<0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (gStackDepths[threadId] >= MAX_NESTING)
|
||||||
|
{
|
||||||
|
btAssert(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gFuncNames[threadId][gStackDepths[threadId]] = msg;
|
||||||
|
gStartTimes[threadId][gStackDepths[threadId]] = clk.getTimeNanoseconds();
|
||||||
|
if (gStartTimes[threadId][gStackDepths[threadId]] <= gStartTimes[threadId][gStackDepths[threadId] - 1])
|
||||||
|
{
|
||||||
|
gStartTimes[threadId][gStackDepths[threadId]] = 1 + gStartTimes[threadId][gStackDepths[threadId] - 1];
|
||||||
|
}
|
||||||
|
gStackDepths[threadId]++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
void MyLeaveProfileZoneFunc()
|
||||||
|
{
|
||||||
|
if (gProfileDisabled)
|
||||||
|
return;
|
||||||
|
#ifndef BT_NO_PROFILE
|
||||||
|
int threadId = btQuickprofGetCurrentThreadIndex2();
|
||||||
|
if (threadId<0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (gStackDepths[threadId] <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gStackDepths[threadId]--;
|
||||||
|
|
||||||
|
const char* name = gFuncNames[threadId][gStackDepths[threadId]];
|
||||||
|
unsigned long long int startTime = gStartTimes[threadId][gStackDepths[threadId]];
|
||||||
|
|
||||||
|
unsigned long long int endTime = clk.getTimeNanoseconds();
|
||||||
|
gTimings[threadId].addTiming(name, threadId, startTime, endTime);
|
||||||
|
#endif //BT_NO_PROFILE
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void b3ChromeUtilsStartTimings()
|
||||||
|
{
|
||||||
|
m_firstTiming = true;
|
||||||
|
gProfileDisabled = false;//true;
|
||||||
|
b3SetCustomEnterProfileZoneFunc(MyEnterProfileZoneFunc);
|
||||||
|
b3SetCustomLeaveProfileZoneFunc(MyLeaveProfileZoneFunc);
|
||||||
|
|
||||||
|
//also for Bullet 2.x API
|
||||||
|
btSetCustomEnterProfileZoneFunc(MyEnterProfileZoneFunc);
|
||||||
|
btSetCustomLeaveProfileZoneFunc(MyLeaveProfileZoneFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void b3ChromeUtilsStopTimingsAndWriteJsonFile()
|
||||||
|
{
|
||||||
|
b3SetCustomEnterProfileZoneFunc(MyDummyEnterProfileZoneFunc);
|
||||||
|
b3SetCustomLeaveProfileZoneFunc(MyDummyLeaveProfileZoneFunc);
|
||||||
|
//also for Bullet 2.x API
|
||||||
|
btSetCustomEnterProfileZoneFunc(MyDummyEnterProfileZoneFunc);
|
||||||
|
btSetCustomLeaveProfileZoneFunc(MyDummyLeaveProfileZoneFunc);
|
||||||
|
char fileName[1024];
|
||||||
|
static int fileCounter = 0;
|
||||||
|
sprintf(fileName,"timings_%d.json",fileCounter++);
|
||||||
|
gTimingFile = fopen(fileName,"w");
|
||||||
|
fprintf(gTimingFile,"{\"traceEvents\":[\n");
|
||||||
|
//dump the content to file
|
||||||
|
for (int i=0;i<BT_QUICKPROF_MAX_THREAD_COUNT;i++)
|
||||||
|
{
|
||||||
|
if (gTimings[i].m_numTimings)
|
||||||
|
{
|
||||||
|
printf("Writing %d timings for thread %d\n", gTimings[i].m_numTimings, i);
|
||||||
|
gTimings[i].flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf(gTimingFile,"\n],\n\"displayTimeUnit\": \"ns\"}");
|
||||||
|
fclose(gTimingFile);
|
||||||
|
gTimingFile = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void b3ChromeUtilsEnableProfiling()
|
||||||
|
{
|
||||||
|
gProfileDisabled = false;
|
||||||
|
}
|
||||||
9
examples/Utils/ChromeTraceUtil.h
Normal file
9
examples/Utils/ChromeTraceUtil.h
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
#ifndef B3_CHROME_TRACE_UTIL_H
|
||||||
|
#define B3_CHROME_TRACE_UTIL_H
|
||||||
|
|
||||||
|
void b3ChromeUtilsStartTimings();
|
||||||
|
void b3ChromeUtilsStopTimingsAndWriteJsonFile();
|
||||||
|
void b3ChromeUtilsEnableProfiling();
|
||||||
|
|
||||||
|
#endif//B3_CHROME_TRACE_UTIL_H
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import pybullet as p
|
import pybullet as p
|
||||||
|
#p.connect(p.UDP,"192.168.86.100")
|
||||||
p.connect(p.SHARED_MEMORY)
|
p.connect(p.SHARED_MEMORY)
|
||||||
p.resetSimulation()
|
p.resetSimulation()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user