Blender V5.0
progress.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#pragma once
6
7#include <functional>
8
9/* Progress
10 *
11 * Simple class to communicate progress status messages, timing information,
12 * update notifications from a job running in another thread. All methods
13 * except for the constructor/destructor are thread safe. */
14
15#include "util/string.h"
16#include "util/thread.h"
17#include "util/time.h"
18
20
21class Progress {
22 public:
24 {
27 status = "Initializing";
28 }
29
30 Progress(Progress &progress)
31 {
32 *this = progress;
33 }
34
36 {
38
39 progress.get_status(status, substatus);
40
44
45 return *this;
46 }
47
48 void reset()
49 {
50 pixel_samples = 0;
57 time_limit = 0.0;
58 end_time = 0.0;
59 status = "Initializing";
60 substatus = "";
61 sync_status = "";
62 sync_substatus = "";
63 cancel = false;
64 cancel_message = "";
65 error = false;
66 error_message = "";
67 }
68
69 /* cancel */
70 void set_cancel(const string &cancel_message_)
71 {
73 cancel_message = cancel_message_;
74 cancel = true;
75 }
76
77 bool get_cancel() const
78 {
79 if (!cancel && cancel_cb) {
80 cancel_cb();
81 }
82
83 return cancel;
84 }
85
86 string get_cancel_message() const
87 {
89 return cancel_message;
90 }
91
92 void set_cancel_callback(std::function<void()> function)
93 {
94 cancel_cb = function;
95 }
96
97 /* error */
98 void set_error(const string &error_message_)
99 {
101 error_message = error_message_;
102 error = true;
103 /* If error happens we also stop rendering. */
104 cancel_message = error_message_;
105 cancel = true;
106 }
107
108 bool get_error() const
109 {
110 return error;
111 }
112
113 string get_error_message() const
114 {
116 return error_message;
117 }
118
119 /* tile and timing information */
120
122 {
124
126 end_time = 0.0;
127 }
128
135
136 void set_time_limit(const double time_limit_)
137 {
139
140 time_limit = time_limit_;
141 }
142
143 void add_skip_time(const scoped_timer &start_timer, bool only_render)
144 {
145 const double skip_time = time_dt() - start_timer.get_start();
146
147 render_start_time += skip_time;
148 if (!only_render) {
149 start_time += skip_time;
150 }
151 }
152
153 void get_time(double &total_time_, double &render_time_) const
154 {
156
157 const double time = (end_time > 0) ? end_time : time_dt();
158
159 total_time_ = time - start_time;
160 render_time_ = time - render_start_time;
161 }
162
164 {
165 end_time = time_dt();
166 }
167
169 {
171
172 pixel_samples = 0;
174 rendered_tiles = 0;
175 denoised_tiles = 0;
176 }
177
178 void set_total_pixel_samples(const uint64_t total_pixel_samples_)
179 {
181
182 total_pixel_samples = total_pixel_samples_;
183 }
184
185 double get_progress() const
186 {
188
189 if (pixel_samples > 0) {
190 double progress_percent = (double)pixel_samples / (double)total_pixel_samples;
191 if (time_limit != 0.0) {
192 const double time_since_render_start = time_dt() - render_start_time;
193 progress_percent = fmax(progress_percent, time_since_render_start / time_limit);
194 }
195 return fmin(1.0, progress_percent);
196 }
197 return 0.0;
198 }
199
200 void add_samples(const uint64_t pixel_samples_, int tile_sample)
201 {
203
204 pixel_samples += pixel_samples_;
205 current_tile_sample = tile_sample;
206 }
207
208 void add_samples_update(const uint64_t pixel_samples_, int tile_sample)
209 {
210 add_samples(pixel_samples_, tile_sample);
211 set_update();
212 }
213
214 void add_finished_tile(bool denoised)
215 {
217
218 if (denoised) {
220 }
221 else {
223 }
224 }
225
227 {
229 /* Note that the value here always belongs to the last tile that updated,
230 * so it's only useful if there is only one active tile. */
231 return current_tile_sample;
232 }
233
235 {
237 return rendered_tiles;
238 }
239
241 {
243 return denoised_tiles;
244 }
245
246 /* status messages */
247
248 void set_status(const string &status_, const string &substatus_ = "")
249 {
250 {
252 status = status_;
253 substatus = substatus_;
254 }
255
256 set_update();
257 }
258
259 void set_substatus(const string &substatus_)
260 {
261 {
263 substatus = substatus_;
264 }
265
266 set_update();
267 }
268
269 void set_sync_status(const string &status_, const string &substatus_ = "")
270 {
271 {
273 sync_status = status_;
274 sync_substatus = substatus_;
275 }
276
277 set_update();
278 }
279
280 void set_sync_substatus(const string &substatus_)
281 {
282 {
284 sync_substatus = substatus_;
285 }
286
287 set_update();
288 }
289
290 void get_status(string &status_, string &substatus_) const
291 {
293
294 if (!sync_status.empty()) {
295 status_ = sync_status;
296 substatus_ = sync_substatus;
297 }
298 else {
299 status_ = status;
300 substatus_ = substatus;
301 }
302 }
303
304 /* callback */
305
307 {
308 if (update_cb) {
310 update_cb();
311 }
312 }
313
314 void set_update_callback(std::function<void()> function)
315 {
316 update_cb = function;
317 }
318
319 protected:
322 std::function<void()> update_cb = nullptr;
323 std::function<void()> cancel_cb = nullptr;
324
325 /* pixel_samples counts how many samples have been rendered over all pixel, not just per pixel.
326 * This makes the progress estimate more accurate when tiles with different sizes are used.
327 *
328 * total_pixel_samples is the total amount of pixel samples that will be rendered. */
330 /* Stores the current sample count of the last tile that called the update function.
331 * It's used to display the sample count if only one tile is active. */
333 /* Stores the number of tiles that's already finished.
334 * Used to determine whether all but the last tile are finished rendering,
335 * in which case the current_tile_sample is displayed. */
337
338 double start_time = 0.0, render_start_time = 0.0, time_limit = 0.0;
339 /* End time written when render is done, so it doesn't keep increasing on redraws. */
340 double end_time = 0.0;
341
342 string status;
343 string substatus;
344
347
348 volatile bool cancel = false;
350
351 volatile bool error = false;
353};
354
volatile int lock
unsigned long long int uint64_t
Progress()
Definition progress.h:23
double time_limit
Definition progress.h:338
void set_cancel_callback(std::function< void()> function)
Definition progress.h:92
int denoised_tiles
Definition progress.h:336
string sync_substatus
Definition progress.h:346
void get_status(string &status_, string &substatus_) const
Definition progress.h:290
std::function< void()> update_cb
Definition progress.h:322
int get_current_sample() const
Definition progress.h:226
Progress(Progress &progress)
Definition progress.h:30
void set_cancel(const string &cancel_message_)
Definition progress.h:70
string status
Definition progress.h:342
volatile bool error
Definition progress.h:351
int rendered_tiles
Definition progress.h:336
void set_end_time()
Definition progress.h:163
int current_tile_sample
Definition progress.h:332
string get_cancel_message() const
Definition progress.h:86
void set_substatus(const string &substatus_)
Definition progress.h:259
void set_total_pixel_samples(const uint64_t total_pixel_samples_)
Definition progress.h:178
void get_time(double &total_time_, double &render_time_) const
Definition progress.h:153
void set_sync_substatus(const string &substatus_)
Definition progress.h:280
bool get_cancel() const
Definition progress.h:77
std::function< void()> cancel_cb
Definition progress.h:323
double start_time
Definition progress.h:338
string error_message
Definition progress.h:352
thread_mutex update_mutex
Definition progress.h:321
void reset_sample()
Definition progress.h:168
void set_status(const string &status_, const string &substatus_="")
Definition progress.h:248
double render_start_time
Definition progress.h:338
string substatus
Definition progress.h:343
void set_update()
Definition progress.h:306
int get_denoised_tiles() const
Definition progress.h:240
string cancel_message
Definition progress.h:349
void add_samples(const uint64_t pixel_samples_, int tile_sample)
Definition progress.h:200
void set_sync_status(const string &status_, const string &substatus_="")
Definition progress.h:269
volatile bool cancel
Definition progress.h:348
void reset()
Definition progress.h:48
uint64_t total_pixel_samples
Definition progress.h:329
void set_error(const string &error_message_)
Definition progress.h:98
double get_progress() const
Definition progress.h:185
thread_mutex progress_mutex
Definition progress.h:320
bool get_error() const
Definition progress.h:108
double end_time
Definition progress.h:340
void set_render_start_time()
Definition progress.h:129
void add_samples_update(const uint64_t pixel_samples_, int tile_sample)
Definition progress.h:208
void add_finished_tile(bool denoised)
Definition progress.h:214
uint64_t pixel_samples
Definition progress.h:329
string get_error_message() const
Definition progress.h:113
string sync_status
Definition progress.h:345
void add_skip_time(const scoped_timer &start_timer, bool only_render)
Definition progress.h:143
int get_rendered_tiles() const
Definition progress.h:234
void set_update_callback(std::function< void()> function)
Definition progress.h:314
Progress & operator=(Progress &progress)
Definition progress.h:35
void set_time_limit(const double time_limit_)
Definition progress.h:136
void set_start_time()
Definition progress.h:121
double get_start() const
Definition time.h:47
#define CCL_NAMESPACE_END
std::mutex thread_mutex
Definition thread.h:27
std::unique_lock< std::mutex > thread_scoped_lock
Definition thread.h:28
CCL_NAMESPACE_BEGIN double time_dt()
Definition time.cpp:47