Browse Source

Start using the new tracer

Panagiotis Christopoulos Charitos 7 years ago
parent
commit
2e2aac2a39

+ 24 - 11
src/anki/core/App.cpp

@@ -336,12 +336,22 @@ void App::cleanup()
 		m_window = nullptr;
 		m_window = nullptr;
 	}
 	}
 
 
-	m_settingsDir.destroy(m_heapAlloc);
-	m_cacheDir.destroy(m_heapAlloc);
-
 #if ANKI_ENABLE_TRACE
 #if ANKI_ENABLE_TRACE
-	TraceManagerSingleton::destroy();
+	if(TracerSingleton::get().isInitialized())
+	{
+		StringAuto fname(m_heapAlloc);
+		fname.sprintf("%s/trace", m_settingsDir.cstr());
+		ANKI_CORE_LOGI("Will dump trace files: %s", fname.cstr());
+		if(TracerSingleton::get().flush(fname.toCString()))
+		{
+			ANKI_CORE_LOGE("Ignoring error from the tracer");
+		}
+		TracerSingleton::destroy();
+	}
 #endif
 #endif
+
+	m_settingsDir.destroy(m_heapAlloc);
+	m_cacheDir.destroy(m_heapAlloc);
 }
 }
 
 
 Error App::init(const ConfigSet& config, AllocAlignedCallback allocCb, void* allocCbUserData)
 Error App::init(const ConfigSet& config, AllocAlignedCallback allocCb, void* allocCbUserData)
@@ -364,6 +374,11 @@ Error App::initInternal(const ConfigSet& config_, AllocAlignedCallback allocCb,
 	initMemoryCallbacks(allocCb, allocCbUserData);
 	initMemoryCallbacks(allocCb, allocCbUserData);
 	m_heapAlloc = HeapAllocator<U8>(m_allocCb, m_allocCbData);
 	m_heapAlloc = HeapAllocator<U8>(m_allocCb, m_allocCbData);
 
 
+#if ANKI_ENABLE_TRACE
+	TracerSingleton::get().init(m_heapAlloc);
+	TracerSingleton::get().newFrame(0);
+#endif
+
 	ANKI_CHECK(initDirs(config));
 	ANKI_CHECK(initDirs(config));
 
 
 	// Print a message
 	// Print a message
@@ -408,10 +423,6 @@ Error App::initInternal(const ConfigSet& config_, AllocAlignedCallback allocCb,
 	}
 	}
 #endif
 #endif
 
 
-#if ANKI_ENABLE_TRACE
-	ANKI_CHECK(TraceManagerSingleton::get().create(m_heapAlloc, m_settingsDir.toCString()));
-#endif
-
 	ANKI_CORE_LOGI("Number of main threads: %u", U(config.getNumber("core.mainThreadCount")));
 	ANKI_CORE_LOGI("Number of main threads: %u", U(config.getNumber("core.mainThreadCount")));
 
 
 	//
 	//
@@ -533,6 +544,7 @@ Error App::initInternal(const ConfigSet& config_, AllocAlignedCallback allocCb,
 	m_script->setSceneGraph(m_scene);
 	m_script->setSceneGraph(m_scene);
 
 
 	ANKI_CORE_LOGI("Application initialized");
 	ANKI_CORE_LOGI("Application initialized");
+
 	return Error::NONE;
 	return Error::NONE;
 }
 }
 
 
@@ -606,7 +618,10 @@ Error App::mainLoop()
 
 
 	while(!quit)
 	while(!quit)
 	{
 	{
-		ANKI_TRACE_START_FRAME();
+#if ANKI_ENABLE_TRACE
+		static U64 frame = 1;
+		TracerSingleton::get().newFrame(frame++);
+#endif
 		const Second startTime = HighRezTimer::getCurrentTime();
 		const Second startTime = HighRezTimer::getCurrentTime();
 
 
 		prevUpdateTime = crntTime;
 		prevUpdateTime = crntTime;
@@ -675,8 +690,6 @@ Error App::mainLoop()
 		}
 		}
 
 
 		++m_globalTimestamp;
 		++m_globalTimestamp;
-
-		ANKI_TRACE_STOP_FRAME();
 	}
 	}
 
 
 	return Error::NONE;
 	return Error::NONE;

+ 1 - 1
src/anki/core/CMakeLists.txt

@@ -1,4 +1,4 @@
-set(SOURCES App.cpp Config.cpp Trace.cpp StagingGpuMemoryManager.cpp)
+set(SOURCES App.cpp Config.cpp StagingGpuMemoryManager.cpp)
 
 
 if(SDL)
 if(SDL)
 	set(SOURCES ${SOURCES} NativeWindowSdl.cpp)
 	set(SOURCES ${SOURCES} NativeWindowSdl.cpp)

+ 0 - 278
src/anki/core/Trace.cpp

@@ -1,278 +0,0 @@
-// Copyright (C) 2009-2018, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <anki/core/Trace.h>
-#include <anki/util/HighRezTimer.h>
-#include <cstdlib>
-
-#if ANKI_ENABLE_TRACE
-
-namespace anki
-{
-
-static Array<const char*, U(TraceEventType::COUNT)> eventNames = {{"RESOURCE_ALLOCATE_TRANSFER",
-	"RESOURCE_ASYNC_TASK",
-	"RESOURCE_FILE_READ",
-	"SCENE_UPDATE",
-	"SCENE_DELETE_STUFF",
-	"SCENE_PHYSICS_UPDATE",
-	"SCENE_NODES_UPDATE",
-	"SCENE_VISIBILITY_TESTS",
-	"VIS_TEST",
-	"VIS_COMBINE_RESULTS",
-	"VIS_ITERATE_SECTORS",
-	"VIS_GATHER_TRIANGLES",
-	"VIS_RASTERIZE",
-	"VIS_RASTERIZER_TEST",
-	"RENDERER_INIT",
-	"RENDER",
-	"RENDER_MS",
-	"RENDER_IS",
-	"RENDER_SM",
-	"RENDER_IR",
-	"RENDER_DRAWER",
-	"RENDERER_COMMAND_BUFFER_BUILDING",
-	"RENDERER_LIGHT_BINNING",
-	"GR_RENDER_GRAPH",
-	"GR_COMMAND_BUFFER_RESET",
-	"GR_SHADER_COMPILE",
-	"GL_THREAD",
-	"GL_2ND_LEVEL_CMD_BUFFER",
-	"GL_BIND_RESOURCES",
-	"GL_BIND_PPLINE",
-	"GL_CMD_BUFFER_DESTROY",
-	"VK_ACQUIRE_IMAGE",
-	"VK_QUEUE_SUBMIT",
-	"VK_PIPELINE_CREATE",
-	"VK_BIND_OBJECT",
-	"VK_DESCRIPTOR_SET_GET_OR_CREATE",
-	"SWAP_BUFFERS",
-	"BARRIER_WAIT",
-	"LUA_EXEC",
-	"TIMER_TICK_SLEEP"}};
-
-static Array<const char*, U(TraceCounterType::COUNT)> counterNames = {{"GR_DRAWCALLS",
-	"GR_VERTICES",
-	"GL_PROGS_SKIPPED",
-	"VK_PIPELINE_BARRIERS",
-	"VK_CMD_BUFFER_CREATE",
-	"VK_FENCE_CREATE",
-	"VK_SEMAPHORE_CREATE",
-	"VK_DESCRIPTOR_POOL_CREATE",
-	"VK_DESCRIPTOR_SET_CREATE",
-	"VK_PIPELINE_CREATE",
-	"RENDERER_LIGHTS",
-	"RENDERER_SHADOW_PASSES",
-	"RENDERER_MERGED_DRAWCALLS",
-	"RENDERER_REFLECTIONS",
-	"RESOURCE_ASYNC_TASKS",
-	"SCENE_NODES_UPDATED",
-	"STAGING_UNIFORMS_SIZE",
-	"STAGING_STORAGE_SIZE"}};
-
-#	define ANKI_TRACE_FILE_ERROR() \
-		if(err) \
-		{ \
-			ANKI_CORE_LOGE("Error writing the trace file"); \
-		}
-
-const U MAX_EVENTS_DEPTH = 20;
-thread_local Second g_traceEventStartTime[MAX_EVENTS_DEPTH];
-thread_local I g_traceEventsInFlight = 0;
-
-TraceManager::~TraceManager()
-{
-	// No need to close the json (no need to add ']'). Chrome will take care of that
-}
-
-Error TraceManager::create(HeapAllocator<U8> alloc, const CString& cacheDir)
-{
-	if(getenv("ANKI_DISABLE_TRACE") && CString(getenv("ANKI_DISABLE_TRACE")) == "1")
-	{
-		m_disabled = true;
-		return Error::NONE;
-	}
-
-	memset(&m_perFrameCounters[0], 0, sizeof(m_perFrameCounters));
-	memset(&m_perRunCounters[0], 0, sizeof(m_perRunCounters));
-
-	// Create trace file
-	StringAuto fname(alloc);
-	fname.sprintf("%s/trace.json", &cacheDir[0]);
-
-	ANKI_CHECK(m_traceFile.open(fname.toCString(), FileOpenFlag::WRITE));
-	ANKI_CHECK(m_traceFile.writeText("["));
-
-	// Create per frame file
-	StringAuto perFrameFname(alloc);
-	perFrameFname.sprintf("%s/per_frame.csv", &cacheDir[0]);
-	ANKI_CHECK(m_perFrameFile.open(perFrameFname.toCString(), FileOpenFlag::WRITE));
-
-	ANKI_CHECK(m_perFrameFile.writeText("FPS, "));
-	for(U i = 0; i < U(TraceCounterType::COUNT); ++i)
-	{
-		ANKI_CHECK(m_perFrameFile.writeText("%s, ", counterNames[i]));
-	}
-
-	for(U i = 0; i < U(TraceEventType::COUNT); ++i)
-	{
-		const char* fmt = (i < U(TraceEventType::COUNT) - 1) ? "%s, " : "%s\n";
-		ANKI_CHECK(m_perFrameFile.writeText(fmt, eventNames[i]));
-	}
-
-	return Error::NONE;
-}
-
-void TraceManager::startEvent()
-{
-	if(ANKI_UNLIKELY(m_disabled))
-	{
-		return;
-	}
-
-	I i = ++g_traceEventsInFlight;
-	--i;
-	ANKI_ASSERT(i >= 0 && i <= I(MAX_EVENTS_DEPTH));
-
-	g_traceEventStartTime[i] = HighRezTimer::getCurrentTime();
-}
-
-void TraceManager::stopEvent(TraceEventType type)
-{
-	if(ANKI_UNLIKELY(m_disabled))
-	{
-		return;
-	}
-
-	ANKI_ASSERT(g_traceEventsInFlight > 0 && g_traceEventsInFlight < I(MAX_EVENTS_DEPTH));
-	I i = --g_traceEventsInFlight;
-	ANKI_ASSERT(i >= 0 && i < I(MAX_EVENTS_DEPTH));
-	auto startedTime = g_traceEventStartTime[i];
-
-	U id = m_count.fetchAdd(1);
-	if(id < BUFFERED_ENTRIES)
-	{
-		auto now = HighRezTimer::getCurrentTime();
-		auto dur = now - startedTime;
-
-		m_entries[id] = Entry{type, startedTime, dur, Thread::getCurrentThreadId()};
-
-		m_perFrameCounters[U(TraceCounterType::COUNT) + U(type)].fetchAdd(U64(dur * 1000000000.0));
-	}
-	else
-	{
-		ANKI_CORE_LOGW("Increase the buffered trace entries");
-		m_perFrameCounters[U(TraceCounterType::COUNT) + U(type)].fetchAdd(0);
-	}
-}
-
-Error TraceManager::flushCounters()
-{
-	if(ANKI_UNLIKELY(m_disabled))
-	{
-		return Error::NONE;
-	}
-
-	// Write the FPS counter
-	Second now = HighRezTimer::getCurrentTime();
-	Second time = now - m_startFrameTime;
-	F32 fps = 1.0 / time;
-	ANKI_CHECK(m_traceFile.writeText("{\"name\": \"FPS\", \"cat\": \"PERF\", \"ph\": \"C\", "
-									 "\"pid\": 1, \"ts\": %llu, \"args\": {\"val\": %f}},\n",
-		U64(m_startFrameTime * 1000000.0),
-		fps));
-
-	ANKI_CHECK(m_perFrameFile.writeText("%f, ", fps));
-
-	for(U i = 0; i < U(TraceCounterType::COUNT); ++i)
-	{
-		auto count = m_perFrameCounters[i].exchange(0);
-
-		ANKI_CHECK(m_traceFile.writeText("{\"name\": \"%s\", \"cat\": \"PERF\", \"ph\": \"C\", "
-										 "\"pid\": 1, \"ts\": %llu, \"args\": {\"val\": %llu}},\n",
-			counterNames[i],
-			U64(m_startFrameTime * 1000000.0),
-			count));
-
-		ANKI_CHECK(m_perFrameFile.writeText("%llu, ", count));
-	}
-
-	return Error::NONE;
-}
-
-Error TraceManager::flushEvents()
-{
-	if(ANKI_UNLIKELY(m_disabled))
-	{
-		return Error::NONE;
-	}
-
-	// Write the events
-	U count = m_count.exchange(0);
-	count = min<U>(count, BUFFERED_ENTRIES);
-
-	for(U i = 0; i < count; ++i)
-	{
-		const Entry& e = m_entries[i];
-
-		U64 startMicroSec = U64(e.m_timestamp * 1000000.0);
-		U64 durMicroSec = U64(e.m_duration * 1000000.0);
-
-		if(durMicroSec == 0)
-		{
-			continue;
-		}
-
-		ANKI_CHECK(m_traceFile.writeText("{\"name\": \"%s\", \"cat\": \"PERF\", \"ph\": \"X\", "
-										 "\"pid\": 1, \"tid\": %llu, \"ts\": %llu, \"dur\": %llu},\n",
-			eventNames[e.m_event],
-			e.m_tid,
-			startMicroSec,
-			durMicroSec));
-	}
-
-	for(U i = 0; i < U(TraceEventType::COUNT); ++i)
-	{
-		const char* fmt = (i < U(TraceEventType::COUNT) - 1) ? "%f, " : "%f\n";
-		U64 ns = m_perFrameCounters[i + U(TraceCounterType::COUNT)].exchange(0);
-		ANKI_CHECK(m_perFrameFile.writeText(fmt, F64(ns) / 1000000.0)); // Time in ms
-	}
-
-	return Error::NONE;
-}
-
-void TraceManager::startFrame()
-{
-	if(ANKI_UNLIKELY(m_disabled))
-	{
-		return;
-	}
-
-	m_startFrameTime = HighRezTimer::getCurrentTime();
-}
-
-void TraceManager::stopFrame()
-{
-	if(ANKI_UNLIKELY(m_disabled))
-	{
-		return;
-	}
-
-	Error err = flushCounters();
-
-	if(!err)
-	{
-		err = flushEvents();
-	}
-
-	if(err)
-	{
-		ANKI_CORE_LOGE("Error writing the trace file");
-	}
-}
-
-} // end namespace anki
-
-#endif

+ 5 - 173
src/anki/core/Trace.h

@@ -6,187 +6,19 @@
 #pragma once
 #pragma once
 
 
 #include <anki/core/Common.h>
 #include <anki/core/Common.h>
-#include <anki/util/StdTypes.h>
-#include <anki/util/Singleton.h>
-#include <anki/util/Array.h>
-#include <anki/util/Thread.h>
-#include <anki/util/Atomic.h>
-#include <anki/util/Logger.h>
-#include <anki/util/File.h>
-
-namespace anki
-{
-
-/// @addtogroup core
-/// @{
-
-/// Trace event type.
-enum class TraceEventType
-{
-	RESOURCE_ALLOCATE_TRANSFER,
-	RESOURCE_ASYNC_TASK,
-	RESOURCE_FILE_READ,
-	SCENE_UPDATE,
-	SCENE_DELETE_STUFF,
-	SCENE_PHYSICS_UPDATE,
-	SCENE_NODES_UPDATE,
-	SCENE_VISIBILITY_TESTS,
-	SCENE_VISIBILITY_TEST,
-	SCENE_VISIBILITY_COMBINE_RESULTS,
-	SCENE_VISIBILITY_ITERATE_SECTORS,
-	SCENE_VISIBILITY_GATHER_TRIANGLES,
-	SCENE_VISIBILITY_RASTERIZE,
-	SCENE_RASTERIZER_TEST,
-	RENDERER_INIT,
-	RENDER,
-	RENDER_MS,
-	RENDER_IS,
-	RENDER_SM,
-	RENDER_IR,
-	RENDER_DRAWER,
-	RENDERER_COMMAND_BUFFER_BUILDING,
-	RENDERER_LIGHT_BINNING,
-	GR_RENDER_GRAPH,
-	GR_COMMAND_BUFFER_RESET,
-	GR_SHADER_COMPILE,
-	GL_THREAD,
-	GL_2ND_LEVEL_CMD_BUFFER,
-	GL_BIND_RESOURCES,
-	GL_BIND_PPLINE,
-	GL_CMD_BUFFER_DESTROY,
-	VK_ACQUIRE_IMAGE,
-	VK_QUEUE_SUBMIT,
-	VK_PIPELINE_CREATE,
-	VK_BIND_OBJECT,
-	VK_DESCRIPTOR_SET_GET_OR_CREATE,
-	SWAP_BUFFERS,
-	BARRIER_WAIT,
-	LUA_EXEC,
-	TIMER_TICK_SLEEP,
-
-	COUNT
-};
-
-/// Trace counter type.
-enum class TraceCounterType
-{
-	GR_DRAWCALLS,
-	GR_VERTICES,
-	GL_PROGS_SKIPPED,
-	VK_PIPELINE_BARRIERS,
-	VK_CMD_BUFFER_CREATE,
-	VK_FENCE_CREATE,
-	VK_SEMAPHORE_CREATE,
-	VK_DESCRIPTOR_POOL_CREATE,
-	VK_DESCRIPTOR_SET_CREATE,
-	VK_PIPELINE_CREATE,
-	RENDERER_LIGHTS,
-	RENDERER_SHADOW_PASSES,
-	RENDERER_MERGED_DRAWCALLS,
-	RENDERER_REFLECTIONS,
-	RESOURCE_ASYNC_TASKS,
-	SCENE_NODES_UPDATED,
-	STAGING_UNIFORMS_SIZE,
-	STAGING_STORAGE_SIZE,
-
-	COUNT
-};
-
-/// Trace manager.
-class TraceManager
-{
-public:
-	TraceManager()
-	{
-	}
-
-	~TraceManager();
-
-	ANKI_USE_RESULT Error create(HeapAllocator<U8> alloc, const CString& cacheDir);
-
-	void startEvent();
-
-	void stopEvent(TraceEventType type);
-
-	void incCounter(TraceCounterType c, U64 val)
-	{
-		if(!m_disabled)
-		{
-			m_perFrameCounters[U(c)].fetchAdd(val);
-		}
-	}
-
-	void startFrame();
-
-	void stopFrame();
-
-private:
-	class Entry
-	{
-	public:
-		TraceEventType m_event;
-		Second m_timestamp; ///< When it started.
-		Second m_duration;
-		ThreadId m_tid;
-	};
-
-	static const U BUFFERED_ENTRIES = 1024 * 20;
-	Array<Entry, BUFFERED_ENTRIES> m_entries;
-	Atomic<U32> m_count = {0};
-	File m_traceFile;
-	File m_perFrameFile;
-	File m_perRunFile;
-	Second m_startFrameTime;
-
-	Array<Atomic<U64>, U(TraceEventType::COUNT) + U(TraceCounterType::COUNT)> m_perFrameCounters = {{}};
-	Array<Atomic<U64>, U(TraceEventType::COUNT) + U(TraceCounterType::COUNT)> m_perRunCounters = {{}};
-
-	Bool m_disabled = false;
-
-	ANKI_USE_RESULT Error flushCounters();
-	ANKI_USE_RESULT Error flushEvents();
-};
-
-class ScopedTraceManagerEvent
-{
-public:
-	ScopedTraceManagerEvent(TraceManager* manager, TraceEventType type)
-		: m_manager(manager)
-		, m_type(type)
-	{
-		m_manager->startEvent();
-	}
-
-	~ScopedTraceManagerEvent()
-	{
-		m_manager->stopEvent(m_type);
-	}
-
-private:
-	TraceManager* m_manager;
-	TraceEventType m_type;
-};
-
-using TraceManagerSingleton = Singleton<TraceManager>;
+#include <anki/util/Tracer.h>
 
 
 /// @name Trace macros.
 /// @name Trace macros.
 /// @{
 /// @{
 #if ANKI_ENABLE_TRACE
 #if ANKI_ENABLE_TRACE
-#	define ANKI_TRACE_START_EVENT(name_) TraceManagerSingleton::get().startEvent()
-#	define ANKI_TRACE_STOP_EVENT(name_) TraceManagerSingleton::get().stopEvent(TraceEventType::name_)
-#	define ANKI_TRACE_SCOPED_EVENT(name_) \
-		ScopedTraceManagerEvent _tse##name_(&TraceManagerSingleton::get(), TraceEventType::name_)
-#	define ANKI_TRACE_INC_COUNTER(name_, val_) TraceManagerSingleton::get().incCounter(TraceCounterType::name_, val_)
-#	define ANKI_TRACE_START_FRAME() TraceManagerSingleton::get().startFrame()
-#	define ANKI_TRACE_STOP_FRAME() TraceManagerSingleton::get().stopFrame()
+#	define ANKI_TRACE_START_EVENT(name_) TracerSingleton::get().beginEvent()
+#	define ANKI_TRACE_STOP_EVENT(name_) TracerSingleton::get().endEvent(#	name_)
+#	define ANKI_TRACE_SCOPED_EVENT(name_) TraceScopedEvent _tse##name_(#	name_)
+#	define ANKI_TRACE_INC_COUNTER(name_, val_) TracerSingleton::get().increaseCounter(#	name_, val_)
 #else
 #else
 #	define ANKI_TRACE_START_EVENT(name_) ((void)0)
 #	define ANKI_TRACE_START_EVENT(name_) ((void)0)
 #	define ANKI_TRACE_STOP_EVENT(name_) ((void)0)
 #	define ANKI_TRACE_STOP_EVENT(name_) ((void)0)
 #	define ANKI_TRACE_SCOPED_EVENT(name_) ((void)0)
 #	define ANKI_TRACE_SCOPED_EVENT(name_) ((void)0)
 #	define ANKI_TRACE_INC_COUNTER(name_, val_) ((void)0)
 #	define ANKI_TRACE_INC_COUNTER(name_, val_) ((void)0)
-#	define ANKI_TRACE_START_FRAME() ((void)0)
-#	define ANKI_TRACE_STOP_FRAME() ((void)0)
 #endif
 #endif
 /// @}
 /// @}
-
-} // end namespace anki

+ 6 - 0
src/anki/util/Allocator.h

@@ -117,6 +117,12 @@ public:
 		return *this;
 		return *this;
 	}
 	}
 
 
+	/// Check if it's initialized.
+	operator bool() const
+	{
+		return m_pool != nullptr;
+	}
+
 	/// Get the address of a reference
 	/// Get the address of a reference
 	pointer address(reference x) const
 	pointer address(reference x) const
 	{
 	{

+ 3 - 21
src/anki/util/Tracer.cpp

@@ -66,7 +66,7 @@ Tracer::~Tracer()
 	m_frames.destroy(m_alloc);
 	m_frames.destroy(m_alloc);
 }
 }
 
 
-void Tracer::beginFrame(U64 frame)
+void Tracer::newFrame(U64 frame)
 {
 {
 #if ANKI_ASSERTS_ENABLED
 #if ANKI_ASSERTS_ENABLED
 	if(m_frames.getSize() > 0)
 	if(m_frames.getSize() > 0)
@@ -75,25 +75,12 @@ void Tracer::beginFrame(U64 frame)
 	}
 	}
 #endif
 #endif
 
 
-	ANKI_ASSERT(!isInsideBeginEndFrame());
-
 	Frame f;
 	Frame f;
 	f.m_startFrameTime = HighRezTimer::getCurrentTime();
 	f.m_startFrameTime = HighRezTimer::getCurrentTime();
-	f.m_endFrameTime = 0.0;
 	f.m_frame = frame;
 	f.m_frame = frame;
-#if ANKI_ASSERTS_ENABLED
-	f.m_canRecord = true;
-#endif
 	m_frames.emplaceBack(m_alloc, f);
 	m_frames.emplaceBack(m_alloc, f);
 }
 }
 
 
-void Tracer::endFrame()
-{
-	ANKI_ASSERT(isInsideBeginEndFrame());
-	m_frames.getBack().m_canRecord = false;
-	m_frames.getBack().m_endFrameTime = HighRezTimer::getCurrentTime();
-}
-
 Tracer::ThreadLocal& Tracer::getThreadLocal()
 Tracer::ThreadLocal& Tracer::getThreadLocal()
 {
 {
 	ThreadLocal& out = m_threadLocal;
 	ThreadLocal& out = m_threadLocal;
@@ -110,8 +97,6 @@ Tracer::ThreadLocal& Tracer::getThreadLocal()
 
 
 void Tracer::beginEvent()
 void Tracer::beginEvent()
 {
 {
-	ANKI_ASSERT(isInsideBeginEndFrame());
-
 	ThreadLocal& threadLocal = getThreadLocal();
 	ThreadLocal& threadLocal = getThreadLocal();
 	Event* event = threadLocal.m_eventAlloc.newInstance(m_alloc);
 	Event* event = threadLocal.m_eventAlloc.newInstance(m_alloc);
 	event->m_timestamp = HighRezTimer::getCurrentTime();
 	event->m_timestamp = HighRezTimer::getCurrentTime();
@@ -121,7 +106,6 @@ void Tracer::beginEvent()
 void Tracer::endEvent(const char* eventName)
 void Tracer::endEvent(const char* eventName)
 {
 {
 	ANKI_ASSERT(eventName);
 	ANKI_ASSERT(eventName);
-	ANKI_ASSERT(isInsideBeginEndFrame());
 
 
 	// Set the time in the event
 	// Set the time in the event
 	ThreadLocal& threadLocal = getThreadLocal();
 	ThreadLocal& threadLocal = getThreadLocal();
@@ -137,7 +121,6 @@ void Tracer::endEvent(const char* eventName)
 void Tracer::increaseCounter(const char* counterName, U64 value)
 void Tracer::increaseCounter(const char* counterName, U64 value)
 {
 {
 	ANKI_ASSERT(counterName);
 	ANKI_ASSERT(counterName);
-	ANKI_ASSERT(isInsideBeginEndFrame());
 
 
 	ThreadLocal& threadLocal = getThreadLocal();
 	ThreadLocal& threadLocal = getThreadLocal();
 	Counter* counter = threadLocal.m_counterAlloc.newInstance(m_alloc);
 	Counter* counter = threadLocal.m_counterAlloc.newInstance(m_alloc);
@@ -342,9 +325,9 @@ Error Tracer::writeTraceJson(const FlushCtx& ctx)
 	{
 	{
 		const PerFrameCounters& frame = ctx.m_counters[i];
 		const PerFrameCounters& frame = ctx.m_counters[i];
 		const Second startFrameTime = m_frames[frame.m_frameIdx].m_startFrameTime;
 		const Second startFrameTime = m_frames[frame.m_frameIdx].m_startFrameTime;
-		const Second endFrameTime = m_frames[frame.m_frameIdx].m_endFrameTime;
 
 
-		const Array<Second, 2> timestamps = {{startFrameTime, endFrameTime}};
+		// TODO
+		const Array<Second, 2> timestamps = {{startFrameTime, startFrameTime + 1.0}};
 		const U timestampCount = (i < ctx.m_counters.getSize() - 1) ? 1 : 2;
 		const U timestampCount = (i < ctx.m_counters.getSize() - 1) ? 1 : 2;
 
 
 		for(const Counter& counter : frame.m_counters)
 		for(const Counter& counter : frame.m_counters)
@@ -405,7 +388,6 @@ Error Tracer::writeCounterCsv(const FlushCtx& ctx)
 
 
 Error Tracer::flush(CString filename)
 Error Tracer::flush(CString filename)
 {
 {
-	ANKI_ASSERT(!isInsideBeginEndFrame());
 	FlushCtx ctx(m_alloc, filename);
 	FlushCtx ctx(m_alloc, filename);
 
 
 	gatherCounters(ctx);
 	gatherCounters(ctx);

+ 6 - 23
src/anki/util/Tracer.h

@@ -31,6 +31,11 @@ public:
 		m_alloc = alloc;
 		m_alloc = alloc;
 	}
 	}
 
 
+	Bool isInitialized() const
+	{
+		return !!m_alloc;
+	}
+
 	/// Begin a new event.
 	/// Begin a new event.
 	void beginEvent();
 	void beginEvent();
 
 
@@ -41,10 +46,7 @@ public:
 	void increaseCounter(const char* counterName, U64 value);
 	void increaseCounter(const char* counterName, U64 value);
 
 
 	/// Begin a new frame.
 	/// Begin a new frame.
-	void beginFrame(U64 frame);
-
-	/// Call it to end the frame.
-	void endFrame();
+	void newFrame(U64 frame);
 
 
 	/// Flush all results to a file. Don't call that more than once.
 	/// Flush all results to a file. Don't call that more than once.
 	ANKI_USE_RESULT Error flush(CString filename);
 	ANKI_USE_RESULT Error flush(CString filename);
@@ -57,10 +59,6 @@ private:
 	public:
 	public:
 		U64 m_frame;
 		U64 m_frame;
 		Second m_startFrameTime; ///< When the frame started
 		Second m_startFrameTime; ///< When the frame started
-		Second m_endFrameTime; ///< When it ended
-#if ANKI_ASSERTS_ENABLED
-		Bool8 m_canRecord;
-#endif
 	};
 	};
 
 
 	DynamicArray<Frame> m_frames;
 	DynamicArray<Frame> m_frames;
@@ -102,11 +100,6 @@ private:
 	class FlushCtx;
 	class FlushCtx;
 	class PerFrameCounters;
 	class PerFrameCounters;
 
 
-	Bool isInsideBeginEndFrame() const
-	{
-		return m_frames.getSize() > 0 && m_frames.getBack().m_canRecord;
-	}
-
 	/// Get the thread local ThreadLocal structure.
 	/// Get the thread local ThreadLocal structure.
 	ThreadLocal& getThreadLocal();
 	ThreadLocal& getThreadLocal();
 
 
@@ -146,16 +139,6 @@ private:
 	const char* m_name;
 	const char* m_name;
 	Tracer* m_tracer;
 	Tracer* m_tracer;
 };
 };
-
-/// Convenience class to increase a trace counter.
-class TraceIncreaseCounter
-{
-public:
-	TraceIncreaseCounter(const char* name, U64 value)
-	{
-		TracerSingleton::get().increaseCounter(name, value);
-	}
-};
 /// @}
 /// @}
 
 
 } // end namespace anki
 } // end namespace anki

+ 4 - 10
tests/util/Tracer.cpp

@@ -14,13 +14,12 @@ ANKI_TEST(Util, Tracer)
 	tracer.init(alloc);
 	tracer.init(alloc);
 
 
 	// 1st frame
 	// 1st frame
-	tracer.beginFrame(0);
-	tracer.endFrame();
+	tracer.newFrame(0);
 	ANKI_TEST_EXPECT_NO_ERR(tracer.flush("./0"));
 	ANKI_TEST_EXPECT_NO_ERR(tracer.flush("./0"));
 
 
 	// 2nd frame
 	// 2nd frame
 	// 2 same events
 	// 2 same events
-	tracer.beginFrame(1);
+	tracer.newFrame(1);
 
 
 	tracer.beginEvent();
 	tracer.beginEvent();
 	HighRezTimer::sleep(0.5);
 	HighRezTimer::sleep(0.5);
@@ -30,11 +29,9 @@ ANKI_TEST(Util, Tracer)
 	HighRezTimer::sleep(0.5);
 	HighRezTimer::sleep(0.5);
 	tracer.endEvent("event");
 	tracer.endEvent("event");
 
 
-	tracer.endFrame();
-
 	// 4rd frame
 	// 4rd frame
 	// 2 different events & non zero counter
 	// 2 different events & non zero counter
-	tracer.beginFrame(3);
+	tracer.newFrame(3);
 
 
 	tracer.beginEvent();
 	tracer.beginEvent();
 	HighRezTimer::sleep(0.5);
 	HighRezTimer::sleep(0.5);
@@ -46,13 +43,10 @@ ANKI_TEST(Util, Tracer)
 
 
 	tracer.increaseCounter("counter", 100);
 	tracer.increaseCounter("counter", 100);
 
 
-	tracer.endFrame();
-
 	// 5th frame
 	// 5th frame
-	tracer.beginFrame(4);
+	tracer.newFrame(4);
 	tracer.increaseCounter("counter", 150);
 	tracer.increaseCounter("counter", 150);
 	HighRezTimer::sleep(0.1);
 	HighRezTimer::sleep(0.1);
-	tracer.endFrame();
 
 
 	ANKI_TEST_EXPECT_NO_ERR(tracer.flush("./1"));
 	ANKI_TEST_EXPECT_NO_ERR(tracer.flush("./1"));
 }
 }