2019-04-05 01:41:25 +01:00
|
|
|
#include "optick.h"
|
2018-10-04 01:24:45 +01:00
|
|
|
#include "TestEngine.h"
|
|
|
|
|
#include "TestImage.h"
|
2018-11-28 17:54:08 +00:00
|
|
|
#include <chrono>
|
2018-10-04 01:24:45 +01:00
|
|
|
#include <math.h>
|
|
|
|
|
#include <vector>
|
2018-11-30 12:21:05 +00:00
|
|
|
#include <cstring>
|
2018-10-04 01:24:45 +01:00
|
|
|
|
2019-03-24 21:31:54 +00:00
|
|
|
#if OPTICK_ENABLE_FIBERS
|
2018-11-28 17:54:08 +00:00
|
|
|
#include <MTProfilerEventListener.h>
|
2018-10-04 01:24:45 +01:00
|
|
|
static const size_t SCHEDULER_WORKERS_COUNT = 0;
|
2019-03-24 21:31:54 +00:00
|
|
|
#endif //OPTICK_ENABLE_FIBERS
|
2018-10-04 01:24:45 +01:00
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
namespace Test
|
|
|
|
|
{
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
2018-11-28 17:54:08 +00:00
|
|
|
inline void SpinSleep(uint32_t milliseconds)
|
|
|
|
|
{
|
|
|
|
|
auto start = std::chrono::system_clock::now();
|
|
|
|
|
auto finish = start + std::chrono::milliseconds(milliseconds);
|
|
|
|
|
while (std::chrono::system_clock::now() < finish) {}
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
2019-03-24 21:31:54 +00:00
|
|
|
bool OnOptickStateChanged(Optick::State::Type state)
|
2018-10-04 01:24:45 +01:00
|
|
|
{
|
2019-03-24 21:31:54 +00:00
|
|
|
if (state == Optick::State::DUMP_CAPTURE)
|
2018-10-04 01:24:45 +01:00
|
|
|
{
|
2019-03-24 21:31:54 +00:00
|
|
|
Optick::AttachSummary("Version", "v2.0");
|
|
|
|
|
Optick::AttachSummary("Build", __DATE__ " " __TIME__);
|
2018-10-04 01:24:45 +01:00
|
|
|
|
|
|
|
|
// Attach screenshot
|
2019-03-24 21:31:54 +00:00
|
|
|
Optick::AttachFile(Optick::File::OPTICK_IMAGE, Optick::TestImage::Name, Optick::TestImage::Data, Optick::TestImage::Size);
|
2018-10-21 19:12:48 +01:00
|
|
|
|
|
|
|
|
// Attach text file
|
2018-11-28 17:54:08 +00:00
|
|
|
const char* textFile = "You could attach custom text files!\nFor example you could add dxdiag.txt or current game settings.";
|
2019-03-24 21:31:54 +00:00
|
|
|
Optick::AttachFile(Optick::File::OPTICK_TEXT, "Test.txt", (uint8_t*)textFile, (uint32_t)strlen(textFile));
|
2018-10-04 01:24:45 +01:00
|
|
|
}
|
2019-01-09 20:06:28 +00:00
|
|
|
return true;
|
2018-10-04 01:24:45 +01:00
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
float randf()
|
|
|
|
|
{
|
|
|
|
|
return ((float)rand()) / (float)RAND_MAX;
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
2018-11-28 17:54:08 +00:00
|
|
|
void WorkerThread(Engine* engine)
|
2018-10-04 01:24:45 +01:00
|
|
|
{
|
2019-03-24 21:31:54 +00:00
|
|
|
OPTICK_THREAD("Worker")
|
2018-10-04 01:24:45 +01:00
|
|
|
|
|
|
|
|
while (engine->IsAlive())
|
|
|
|
|
{
|
|
|
|
|
// Emulate "wait for events" message
|
2018-11-28 17:54:08 +00:00
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
2018-10-04 01:24:45 +01:00
|
|
|
engine->UpdatePhysics();
|
|
|
|
|
engine->UpdateRecursive();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
static const unsigned long REPEAT_COUNT = 128 * 1024;
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
template<unsigned long N>
|
|
|
|
|
void SlowFunction()
|
|
|
|
|
{
|
2019-03-31 23:53:36 +01:00
|
|
|
OPTICK_EVENT();
|
2018-10-04 01:24:45 +01:00
|
|
|
// Make it static to fool compiler and prevent it from skipping
|
|
|
|
|
static float value = 0.0f;
|
|
|
|
|
|
2019-03-24 21:31:54 +00:00
|
|
|
OPTICK_TAG("Before", value);
|
2018-10-04 01:24:45 +01:00
|
|
|
|
|
|
|
|
for (unsigned long i = 0; i < N; ++i)
|
|
|
|
|
value = (value + sin((float)i)) * 0.5f;
|
|
|
|
|
|
2019-03-24 21:31:54 +00:00
|
|
|
OPTICK_TAG("After", value);
|
2018-10-04 01:24:45 +01:00
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
void SlowFunction2()
|
|
|
|
|
{
|
2019-03-31 23:53:36 +01:00
|
|
|
OPTICK_EVENT();
|
2018-10-04 01:24:45 +01:00
|
|
|
// Make it static to fool compiler and prevent it from skipping
|
2018-11-28 20:00:16 +00:00
|
|
|
static const size_t NUM_VALUES = 1024 * 1024;
|
|
|
|
|
static float values[NUM_VALUES] = { 0 };
|
2018-10-04 01:24:45 +01:00
|
|
|
|
2018-11-28 20:00:16 +00:00
|
|
|
for (size_t i = 1; i < NUM_VALUES; ++i)
|
2018-10-04 01:24:45 +01:00
|
|
|
{
|
|
|
|
|
values[i] += i;
|
|
|
|
|
values[i] *= i;
|
|
|
|
|
values[i] /= i;
|
|
|
|
|
values[i] -= i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
2019-03-24 21:31:54 +00:00
|
|
|
#if OPTICK_ENABLE_FIBERS
|
2018-10-04 01:24:45 +01:00
|
|
|
template<unsigned long N>
|
|
|
|
|
struct SimpleTask
|
|
|
|
|
{
|
|
|
|
|
MT_DECLARE_TASK(SimpleTask, MT::StackRequirements::STANDARD, MT::TaskPriority::NORMAL, MT::Color::LightBlue);
|
|
|
|
|
|
|
|
|
|
float value;
|
|
|
|
|
|
|
|
|
|
SimpleTask() : value(0.0f) {}
|
|
|
|
|
|
|
|
|
|
void Do(MT::FiberContext& ctx)
|
|
|
|
|
{
|
|
|
|
|
{
|
2019-03-31 23:53:36 +01:00
|
|
|
OPTICK_CATEGORY("BeforeYield", Optick::Category::AI);
|
2018-10-04 01:24:45 +01:00
|
|
|
|
|
|
|
|
for (unsigned long i = 0; i < N; ++i)
|
|
|
|
|
value = (value + sin((float)i)) * 0.5f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ctx.Yield();
|
|
|
|
|
|
|
|
|
|
{
|
2019-03-31 23:53:36 +01:00
|
|
|
OPTICK_CATEGORY("AfterYield", Optick::Category::AI);
|
2018-10-04 01:24:45 +01:00
|
|
|
|
|
|
|
|
for (unsigned long i = 0; i < N; ++i)
|
|
|
|
|
value = (value + cos((float)i)) * 0.5f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
template<unsigned long CHILDREN_COUNT>
|
|
|
|
|
struct RootTask
|
|
|
|
|
{
|
|
|
|
|
MT_DECLARE_TASK(RootTask, MT::StackRequirements::STANDARD, MT::TaskPriority::NORMAL, MT::Color::BurlyWood);
|
|
|
|
|
|
|
|
|
|
float value;
|
|
|
|
|
|
|
|
|
|
RootTask() : value(0.0f) {}
|
|
|
|
|
|
|
|
|
|
void Do(MT::FiberContext& context)
|
|
|
|
|
{
|
2018-11-28 17:54:08 +00:00
|
|
|
SpinSleep(1);
|
2018-10-04 01:24:45 +01:00
|
|
|
|
|
|
|
|
SimpleTask<REPEAT_COUNT> children[CHILDREN_COUNT];
|
|
|
|
|
context.RunSubtasksAndYield(MT::TaskGroup::Default(), children, CHILDREN_COUNT);
|
|
|
|
|
|
2018-11-28 17:54:08 +00:00
|
|
|
SpinSleep(1);
|
2018-10-04 01:24:45 +01:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct PriorityTask
|
|
|
|
|
{
|
|
|
|
|
MT_DECLARE_TASK(PriorityTask, MT::StackRequirements::STANDARD, MT::TaskPriority::HIGH, MT::Color::Orange);
|
|
|
|
|
|
|
|
|
|
float value;
|
|
|
|
|
|
|
|
|
|
PriorityTask() : value(0.0f) {}
|
|
|
|
|
|
|
|
|
|
void Do(MT::FiberContext&)
|
|
|
|
|
{
|
|
|
|
|
for (unsigned long i = 0; i < 8192; ++i)
|
|
|
|
|
{
|
|
|
|
|
value = (value + cos((float)i)) * 0.5f;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
2019-03-24 21:31:54 +00:00
|
|
|
#endif // OPTICK_ENABLE_FIBERS
|
2018-10-04 01:24:45 +01:00
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
bool Engine::Update()
|
|
|
|
|
{
|
2019-03-31 23:53:36 +01:00
|
|
|
OPTICK_EVENT();
|
2018-10-04 01:24:45 +01:00
|
|
|
|
|
|
|
|
UpdateInput();
|
|
|
|
|
|
|
|
|
|
UpdateMessages();
|
|
|
|
|
|
|
|
|
|
UpdateLogic();
|
|
|
|
|
|
|
|
|
|
UpdateTasks();
|
|
|
|
|
|
|
|
|
|
UpdateScene();
|
|
|
|
|
|
|
|
|
|
UpdatePhysics();
|
|
|
|
|
|
|
|
|
|
Draw();
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
void Engine::UpdateInput()
|
|
|
|
|
{
|
2019-03-30 19:45:27 +00:00
|
|
|
OPTICK_CATEGORY("UpdateInput", Optick::Category::Input);
|
2018-10-04 01:24:45 +01:00
|
|
|
SlowFunction2();
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
void Engine::UpdateMessages()
|
|
|
|
|
{
|
2019-03-30 19:45:27 +00:00
|
|
|
OPTICK_CATEGORY("UpdateMessages", Optick::Category::Network);
|
2018-10-04 01:24:45 +01:00
|
|
|
SlowFunction<REPEAT_COUNT>();
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
void Engine::UpdateLogic()
|
|
|
|
|
{
|
2019-03-30 19:45:27 +00:00
|
|
|
OPTICK_CATEGORY("UpdateLogic", Optick::Category::GameLogic);
|
2018-10-04 01:24:45 +01:00
|
|
|
|
|
|
|
|
static const char* name[3] = { "Alice", "Bob", "Craig" };
|
|
|
|
|
|
|
|
|
|
int index = rand() % 3;
|
|
|
|
|
|
2019-03-24 21:31:54 +00:00
|
|
|
OPTICK_TAG("PlayerName", name[index]);
|
|
|
|
|
OPTICK_TAG("Position", 123.0f, 456.0f, 789.0f);
|
|
|
|
|
OPTICK_TAG("Health", 100);
|
|
|
|
|
OPTICK_TAG("Score", 0x80000000u);
|
|
|
|
|
OPTICK_TAG("Height(cm)", 176.3f);
|
|
|
|
|
OPTICK_TAG("Address", (uint64_t)&name[index]);
|
2018-10-04 01:24:45 +01:00
|
|
|
|
|
|
|
|
SlowFunction<REPEAT_COUNT>();
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
void Engine::UpdateTasks()
|
|
|
|
|
{
|
2019-03-30 19:45:27 +00:00
|
|
|
OPTICK_CATEGORY("UpdateTasks", Optick::Category::Scene);
|
2018-11-28 17:54:08 +00:00
|
|
|
|
2019-03-24 21:31:54 +00:00
|
|
|
#if OPTICK_ENABLE_FIBERS
|
2018-10-04 01:24:45 +01:00
|
|
|
RootTask<16> task;
|
|
|
|
|
scheduler.RunAsync(MT::TaskGroup::Default(), &task, 1);
|
|
|
|
|
|
2018-11-28 17:54:08 +00:00
|
|
|
SpinSleep(1);
|
2018-10-04 01:24:45 +01:00
|
|
|
|
|
|
|
|
PriorityTask priorityTasks[128];
|
|
|
|
|
scheduler.RunAsync(MT::TaskGroup::Default(), &priorityTasks[0], MT_ARRAY_SIZE(priorityTasks));
|
|
|
|
|
|
|
|
|
|
scheduler.WaitAll(100000);
|
2019-03-24 21:31:54 +00:00
|
|
|
#endif //OPTICK_ENABLE_FIBERS
|
2018-10-04 01:24:45 +01:00
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
void Engine::UpdateScene()
|
|
|
|
|
{
|
2019-03-30 19:45:27 +00:00
|
|
|
OPTICK_CATEGORY("UpdateScene", Optick::Category::Scene);
|
2018-10-04 01:24:45 +01:00
|
|
|
SlowFunction<REPEAT_COUNT>();
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
void Engine::Draw()
|
|
|
|
|
{
|
2019-03-30 19:45:27 +00:00
|
|
|
OPTICK_CATEGORY("Draw", Optick::Category::Rendering);
|
2018-10-07 21:00:14 +01:00
|
|
|
|
2019-03-24 21:31:54 +00:00
|
|
|
int64_t cpuTimestampStart = Optick::GetHighPrecisionTime();
|
2018-10-04 01:24:45 +01:00
|
|
|
SlowFunction<REPEAT_COUNT>();
|
2019-03-24 21:31:54 +00:00
|
|
|
int64_t cpuTimestampFinish = Optick::GetHighPrecisionTime();
|
2018-10-07 21:00:14 +01:00
|
|
|
|
|
|
|
|
// Registering a storage - could be done in any place
|
2019-03-24 21:31:54 +00:00
|
|
|
static Optick::EventStorage* GPUStorage = Optick::RegisterStorage("GPU");
|
2018-10-07 21:00:14 +01:00
|
|
|
|
|
|
|
|
// Creating a shared event-description
|
2019-03-24 21:31:54 +00:00
|
|
|
static Optick::EventDescription* GPUFrame = Optick::EventDescription::CreateShared("GPU Frame");
|
2018-10-07 21:00:14 +01:00
|
|
|
|
|
|
|
|
// Adding GPUFrame event to the GPUStorage with specified start\stop timestamps
|
2019-03-24 21:31:54 +00:00
|
|
|
OPTICK_STORAGE_EVENT(GPUStorage, GPUFrame, cpuTimestampStart, cpuTimestampFinish);
|
2018-10-04 01:24:45 +01:00
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
void Engine::UpdatePhysics()
|
|
|
|
|
{
|
2019-03-30 19:45:27 +00:00
|
|
|
OPTICK_CATEGORY("UpdatePhysics", Optick::Category::Physics);
|
2019-03-24 21:31:54 +00:00
|
|
|
OPTICK_TAG("Position", 123.0f, 456.0f, 789.0f);
|
2018-11-28 17:54:08 +00:00
|
|
|
SpinSleep(20);
|
2018-10-04 01:24:45 +01:00
|
|
|
}
|
|
|
|
|
|
2019-03-24 21:31:54 +00:00
|
|
|
#if OPTICK_MSVC
|
2018-11-28 20:00:16 +00:00
|
|
|
#pragma warning( push )
|
|
|
|
|
//warning C4996 : 'sprintf' : This function or variable may be unsafe.Consider using sprintf_s instead.
|
|
|
|
|
#pragma warning( disable : 4996 )
|
|
|
|
|
#endif
|
|
|
|
|
|
2018-10-04 01:24:45 +01:00
|
|
|
template<int N>
|
|
|
|
|
void RecursiveUpdate(int sleep)
|
|
|
|
|
{
|
|
|
|
|
const char* scenes[4] = { "Earth", "Mars", "Moon", "Pluto" };
|
|
|
|
|
char label[64] = { 0 };
|
2018-11-28 17:54:08 +00:00
|
|
|
sprintf(label, "UpdateScene - %s", scenes[rand() % 4]);
|
2018-10-04 01:24:45 +01:00
|
|
|
|
2019-03-24 21:31:54 +00:00
|
|
|
OPTICK_PUSH_DYNAMIC(label);
|
2018-10-04 01:24:45 +01:00
|
|
|
|
2018-11-28 17:54:08 +00:00
|
|
|
SpinSleep(sleep);
|
2018-10-04 01:24:45 +01:00
|
|
|
RecursiveUpdate<N - 1>(sleep);
|
|
|
|
|
RecursiveUpdate<N - 1>(sleep);
|
|
|
|
|
|
2019-03-24 21:31:54 +00:00
|
|
|
OPTICK_POP();
|
2018-10-04 01:24:45 +01:00
|
|
|
}
|
|
|
|
|
|
2019-03-24 21:31:54 +00:00
|
|
|
#if OPTICK_MSVC
|
2018-11-28 20:00:16 +00:00
|
|
|
#pragma warning( pop )
|
|
|
|
|
#endif
|
|
|
|
|
|
2018-10-04 01:24:45 +01:00
|
|
|
template<>
|
|
|
|
|
void RecursiveUpdate<0>(int) {}
|
|
|
|
|
|
|
|
|
|
void Engine::UpdateRecursive()
|
|
|
|
|
{
|
2019-03-31 23:53:36 +01:00
|
|
|
OPTICK_EVENT();
|
2018-11-28 20:00:16 +00:00
|
|
|
RecursiveUpdate<4>(1);
|
2018-10-04 01:24:45 +01:00
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2019-03-24 21:31:54 +00:00
|
|
|
#if OPTICK_MSVC
|
2018-10-04 01:24:45 +01:00
|
|
|
#pragma warning( push )
|
|
|
|
|
|
|
|
|
|
//C4481. nonstandard extension used: override specifier 'override'
|
|
|
|
|
#pragma warning( disable : 4481 )
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
2019-03-24 21:31:54 +00:00
|
|
|
#if OPTICK_ENABLE_FIBERS
|
2018-10-04 01:24:45 +01:00
|
|
|
class Profiler : public MT::IProfilerEventListener
|
|
|
|
|
{
|
2019-03-24 21:31:54 +00:00
|
|
|
Optick::EventStorage* fiberEventStorages[MT::MT_MAX_STANDART_FIBERS_COUNT + MT::MT_MAX_EXTENDED_FIBERS_COUNT];
|
2018-10-04 01:24:45 +01:00
|
|
|
uint32 totalFibersCount;
|
|
|
|
|
|
2019-03-24 21:31:54 +00:00
|
|
|
static mt_thread_local Optick::EventStorage* originalThreadStorage;
|
|
|
|
|
static mt_thread_local Optick::EventStorage* activeThreadStorage;
|
2018-10-04 01:24:45 +01:00
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
Profiler()
|
|
|
|
|
: totalFibersCount(0)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void OnFibersCreated(uint32 fibersCount) override
|
|
|
|
|
{
|
|
|
|
|
totalFibersCount = fibersCount;
|
|
|
|
|
MT_ASSERT(fibersCount <= MT_ARRAY_SIZE(fiberEventStorages), "Too many fibers!");
|
|
|
|
|
for(uint32 fiberIndex = 0; fiberIndex < fibersCount; fiberIndex++)
|
|
|
|
|
{
|
2019-03-24 21:31:54 +00:00
|
|
|
Optick::RegisterFiber(fiberIndex, &fiberEventStorages[fiberIndex]);
|
2018-10-04 01:24:45 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void OnThreadsCreated(uint32 threadsCount) override
|
|
|
|
|
{
|
|
|
|
|
MT_UNUSED(threadsCount);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
virtual void OnTemporaryWorkerThreadLeave() override
|
|
|
|
|
{
|
2019-03-24 21:31:54 +00:00
|
|
|
Optick::EventStorage** currentThreadStorageSlot = Optick::GetEventStorageSlotForCurrentThread();
|
2018-10-04 01:24:45 +01:00
|
|
|
MT_ASSERT(currentThreadStorageSlot, "Sanity check failed");
|
2019-03-24 21:31:54 +00:00
|
|
|
Optick::EventStorage* storage = *currentThreadStorageSlot;
|
2018-10-04 01:24:45 +01:00
|
|
|
|
|
|
|
|
// if profile session is not active
|
|
|
|
|
if (storage == nullptr)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MT_ASSERT(IsFiberStorage(storage) == false, "Sanity check failed");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void OnTemporaryWorkerThreadJoin() override
|
|
|
|
|
{
|
2019-03-24 21:31:54 +00:00
|
|
|
Optick::EventStorage** currentThreadStorageSlot = Optick::GetEventStorageSlotForCurrentThread();
|
2018-10-04 01:24:45 +01:00
|
|
|
MT_ASSERT(currentThreadStorageSlot, "Sanity check failed");
|
2019-03-24 21:31:54 +00:00
|
|
|
Optick::EventStorage* storage = *currentThreadStorageSlot;
|
2018-10-04 01:24:45 +01:00
|
|
|
|
|
|
|
|
// if profile session is not active
|
|
|
|
|
if (storage == nullptr)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MT_ASSERT(IsFiberStorage(storage) == false, "Sanity check failed");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
virtual void OnThreadCreated(uint32 workerIndex) override
|
|
|
|
|
{
|
2019-03-24 21:31:54 +00:00
|
|
|
OPTICK_START_THREAD("FiberWorker");
|
2018-10-04 01:24:45 +01:00
|
|
|
MT_UNUSED(workerIndex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void OnThreadStarted(uint32 workerIndex) override
|
|
|
|
|
{
|
|
|
|
|
MT_UNUSED(workerIndex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void OnThreadStoped(uint32 workerIndex) override
|
|
|
|
|
{
|
|
|
|
|
MT_UNUSED(workerIndex);
|
2019-03-24 21:31:54 +00:00
|
|
|
OPTICK_STOP_THREAD();
|
2018-10-04 01:24:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void OnThreadIdleStarted(uint32 workerIndex) override
|
|
|
|
|
{
|
|
|
|
|
MT_UNUSED(workerIndex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void OnThreadIdleFinished(uint32 workerIndex) override
|
|
|
|
|
{
|
|
|
|
|
MT_UNUSED(workerIndex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void OnThreadWaitStarted() override
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void OnThreadWaitFinished() override
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void OnTaskExecuteStateChanged(MT::Color::Type debugColor, const mt_char* debugID, MT::TaskExecuteState::Type type, int32 fiberIndex) override
|
|
|
|
|
{
|
|
|
|
|
MT_ASSERT(fiberIndex < (int32)totalFibersCount, "Sanity check failed");
|
|
|
|
|
|
2019-03-24 21:31:54 +00:00
|
|
|
Optick::EventStorage** currentThreadStorageSlot = Optick::GetEventStorageSlotForCurrentThread();
|
2018-10-04 01:24:45 +01:00
|
|
|
MT_ASSERT(currentThreadStorageSlot, "Sanity check failed");
|
|
|
|
|
|
|
|
|
|
// if profile session is not active
|
|
|
|
|
if (*currentThreadStorageSlot == nullptr)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if actual fiber is scheduler internal fiber (don't have event storage for internal scheduler fibers)
|
|
|
|
|
if (fiberIndex < 0)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch(type)
|
|
|
|
|
{
|
|
|
|
|
case MT::TaskExecuteState::START:
|
|
|
|
|
case MT::TaskExecuteState::RESUME:
|
|
|
|
|
{
|
|
|
|
|
MT_ASSERT(originalThreadStorage == nullptr, "Sanity check failed");
|
|
|
|
|
|
|
|
|
|
originalThreadStorage = *currentThreadStorageSlot;
|
|
|
|
|
|
|
|
|
|
MT_ASSERT(IsFiberStorage(originalThreadStorage) == false, "Sanity check failed");
|
|
|
|
|
|
2019-03-24 21:31:54 +00:00
|
|
|
Optick::EventStorage* currentFiberStorage = nullptr;
|
2018-10-04 01:24:45 +01:00
|
|
|
if (fiberIndex >= (int32)0)
|
|
|
|
|
{
|
|
|
|
|
currentFiberStorage = fiberEventStorages[fiberIndex];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*currentThreadStorageSlot = currentFiberStorage;
|
|
|
|
|
activeThreadStorage = currentFiberStorage;
|
2019-03-24 21:31:54 +00:00
|
|
|
Optick::FiberSyncData::AttachToThread(currentFiberStorage, MT::ThreadId::Self().AsUInt64());
|
2018-10-04 01:24:45 +01:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case MT::TaskExecuteState::STOP:
|
|
|
|
|
case MT::TaskExecuteState::SUSPEND:
|
|
|
|
|
{
|
2019-03-24 21:31:54 +00:00
|
|
|
Optick::EventStorage* currentFiberStorage = *currentThreadStorageSlot;
|
2018-10-04 01:24:45 +01:00
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
2019-03-24 21:31:54 +00:00
|
|
|
Optick::EventStorage* checkFiberStorage = nullptr;
|
2018-10-04 01:24:45 +01:00
|
|
|
if (fiberIndex >= (int32)0)
|
|
|
|
|
{
|
|
|
|
|
checkFiberStorage = fiberEventStorages[fiberIndex];
|
|
|
|
|
}
|
|
|
|
|
MT_ASSERT(checkFiberStorage == currentFiberStorage, "Sanity check failed");
|
|
|
|
|
|
|
|
|
|
MT_ASSERT(activeThreadStorage == currentFiberStorage, "Sanity check failed");
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
MT_ASSERT(IsFiberStorage(currentFiberStorage) == true, "Sanity check failed");
|
|
|
|
|
|
2019-03-24 21:31:54 +00:00
|
|
|
Optick::FiberSyncData::DetachFromThread(currentFiberStorage);
|
2018-10-04 01:24:45 +01:00
|
|
|
|
|
|
|
|
*currentThreadStorageSlot = originalThreadStorage;
|
|
|
|
|
originalThreadStorage = nullptr;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MT_UNUSED(debugColor);
|
|
|
|
|
MT_UNUSED(debugID);
|
|
|
|
|
MT_UNUSED(type);
|
|
|
|
|
}
|
|
|
|
|
};
|
2018-11-28 17:54:08 +00:00
|
|
|
|
|
|
|
|
MT::IProfilerEventListener* GetProfiler()
|
|
|
|
|
{
|
|
|
|
|
static Profiler profiler;
|
|
|
|
|
return &profiler;
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-24 21:31:54 +00:00
|
|
|
mt_thread_local Optick::EventStorage* Profiler::originalThreadStorage = nullptr;
|
|
|
|
|
mt_thread_local Optick::EventStorage* Profiler::activeThreadStorage = 0;
|
|
|
|
|
#endif //OPTICK_ENABLE_FIBERS
|
2018-10-04 01:24:45 +01:00
|
|
|
|
2019-03-24 21:31:54 +00:00
|
|
|
#if OPTICK_MSVC
|
2018-10-04 01:24:45 +01:00
|
|
|
#pragma warning( pop )
|
|
|
|
|
#endif
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
2018-11-28 17:54:08 +00:00
|
|
|
Engine::Engine() : isAlive(true)
|
2019-03-24 21:31:54 +00:00
|
|
|
#if OPTICK_ENABLE_FIBERS
|
2018-11-28 17:54:08 +00:00
|
|
|
, scheduler(SCHEDULER_WORKERS_COUNT, nullptr, GetProfiler())
|
|
|
|
|
#endif
|
2018-10-04 01:24:45 +01:00
|
|
|
{
|
2019-03-24 21:31:54 +00:00
|
|
|
OPTICK_SET_STATE_CHANGED_CALLBACK(OnOptickStateChanged);
|
2018-10-04 01:24:45 +01:00
|
|
|
|
|
|
|
|
for (size_t i = 0; i < WORKER_THREAD_COUNT; ++i)
|
|
|
|
|
{
|
2018-11-28 17:54:08 +00:00
|
|
|
workers[i] = std::thread(WorkerThread, this);
|
2018-10-04 01:24:45 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
Engine::~Engine()
|
|
|
|
|
{
|
|
|
|
|
isAlive = false;
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < workers.size(); ++i)
|
2018-11-28 17:54:08 +00:00
|
|
|
workers[i].join();
|
2018-10-04 01:24:45 +01:00
|
|
|
}
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
2018-11-28 17:54:08 +00:00
|
|
|
}
|