/*********************************************************************************
** Copyright (c) 2019 MAK Technologies, Inc.
** All rights reserved.
*********************************************************************************/

//! \file OsgProfiler.h 
//! \brief Contains the classes allowing the profiler to work, OsgProfileManager, 
//! OsgProfileSample, and OsgProfileIterator
//! \ingroup vrvUtil

#pragma once

#include <osg/Export>

namespace osg
{
   class OSG_EXPORT ProfileManager
   {
      public:
         ProfileManager() : _CollectTracyStats(false), _TracyCallstackDepth(0) { ; }
         bool  _CollectTracyStats;
         int  _TracyCallstackDepth;

         static ProfileManager theProfileManager;
   };

};


//easy to use macro to profile a section
// should pass a "const char*" as name because the pointer is getting
// used to do the string compare (to be fast)
// if a std::string is passed instead it will cause a crashed when 
// loading/unloading terrain with the performance/stats displayed 

#ifdef _WIN32
#define TRACY_ENABLE
//#define OPTICK_ENABLE
#else 
#define OSG_NO_PROFILER
#endif 

///////////////////////////////////////
//optick
#ifdef OPTICK_ENABLE
#include <optick/optick.h>
#pragma comment(lib, "OptickCore.lib") 

// win32 creates macros that work with our stats and tracy
#define OsgProfile(name) OPTICK_EVENT(name); OsgProfile_X(name, __LINE__);
#define OsgProfileC(name, color) OPTICK_EVENT(name); OsgProfile_X(name, __LINE__);
#define OsgProfile_SECTION(name) {OPTICK_EVENT(name); OsgProfileSample _profileSample(name); 

#define OsgProfilerFrameMark OPTICK_FRAME("MainThread")
#define OsgProfilerThread(name) OPTICK_THREAD(name);

#define OsgProfilerPlot(x,y)

#endif

/////////////////////////////////////// 
//tracy
#ifdef TRACY_ENABLE

// Include MAK's Tracy defines so everything is consistent between all 3rdParty Libs
#include <tracy/MAKTracyDefines.h>

// TO DO include tracy on linux just to get it's macros for throwing things out
#include <tracy/Tracy.hpp>

// win32 creates macros that work with our stats and tracy
#define OsgProfileZone ZoneNamedS(___tracy_scoped_zone, osg::ProfileManager::theProfileManager._TracyCallstackDepth, osg::ProfileManager::theProfileManager._CollectTracyStats);
#define OsgProfile(name) ZoneNamedNS( ___tracy_scoped_zone, name, osg::ProfileManager::theProfileManager._TracyCallstackDepth, osg::ProfileManager::theProfileManager._CollectTracyStats); 
// extra per zone info
#define OsgProfileText(text, len) if(osg::ProfileManager::theProfileManager._CollectTracyStats){ZoneText( text, len );}
#define OsgProfileC(name, color) ZoneNamedNCS( ___tracy_scoped_zone, name, color, osg::ProfileManager::theProfileManager._TracyCallstackDepth, osg::ProfileManager::theProfileManager._CollectTracyStats); 

#define OsgProfilerFrameMark FrameMark
#define OsgProfilerPlot(x,y) TracyPlot(x,y)
#define OsgProfilerThread(name)

#endif

////////////////////////////////////
// linux
#ifdef OSG_NO_PROFILER
#define OsgProfile(name) 
#define OsgProfileC(name, color)
#define OsgProfile_SECTION(name) 
#define OsgProfileText(text, len);

#define TracyPlot(x,y)
#define TracyPlotConfig(x,y)

#define OsgProfilerFrameMark 
#define OsgProfilerThread(name)
#define OsgProfileGpuCollect TracyGpuCollect
#define OsgProfileGpuCreateContext TracyGpuContext

#endif

