// pbrt is Copyright(c) 1998-2020 Matt Pharr, Wenzel Jakob, and Greg Humphreys. // The pbrt source code is licensed under the Apache License, Version 2.0. // SPDX: Apache-2.0 #ifndef PBRT_UTIL_PROGRESSREPORTER_H #define PBRT_UTIL_PROGRESSREPORTER_H #include #include #include #include #include #include #ifdef PBRT_BUILD_GPU_RENDERER #include #include #include #endif namespace pbrt { // Timer Definition class Timer { public: Timer() { start = clock::now(); } double ElapsedSeconds() const { clock::time_point now = clock::now(); int64_t elapseduS = std::chrono::duration_cast(now - start).count(); return elapseduS / 1000000.; } std::string ToString() const; private: using clock = std::chrono::steady_clock; clock::time_point start; }; // ProgressReporter Definition class ProgressReporter { public: // ProgressReporter Public Methods ProgressReporter() : quiet(true) {} ProgressReporter(int64_t totalWork, const std::string &title, bool quiet, bool gpu = false); ~ProgressReporter(); void Update(int64_t num = 1); void Done(); double ElapsedSeconds() const; std::string ToString() const; private: // ProgressReporter Private Methods void launchThread(); void printBar(); // ProgressReporter Private Members int64_t totalWork; std::string title; bool quiet; Timer timer; std::atomic workDone; std::atomic exitThread; std::thread updateThread; #ifdef PBRT_BUILD_GPU_RENDERER std::vector gpuEvents; std::atomic gpuEventsLaunchedOffset; int gpuEventsFinishedOffset; #endif }; // ProgressReporter Inline Method Definitions inline double ProgressReporter::ElapsedSeconds() const { return timer.ElapsedSeconds(); } inline void ProgressReporter::Update(int64_t num) { #ifdef PBRT_BUILD_GPU_RENDERER if (gpuEvents.size() > 0) { if (gpuEventsLaunchedOffset + num <= gpuEvents.size()) { while (num-- > 0) { CHECK_EQ(cudaEventRecord(gpuEvents[gpuEventsLaunchedOffset]), cudaSuccess); ++gpuEventsLaunchedOffset; } } return; } #endif if (num == 0 || quiet) return; workDone += num; } } // namespace pbrt #endif // PBRT_UTIL_PROGRESSREPORTER_H