Blender  V2.93
util_progress.h
Go to the documentation of this file.
1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef __UTIL_PROGRESS_H__
18 #define __UTIL_PROGRESS_H__
19 
20 /* Progress
21  *
22  * Simple class to communicate progress status messages, timing information,
23  * update notifications from a job running in another thread. All methods
24  * except for the constructor/destructor are thread safe. */
25 
26 #include "util/util_function.h"
27 #include "util/util_string.h"
28 #include "util/util_thread.h"
29 #include "util/util_time.h"
30 
32 
33 class Progress {
34  public:
36  {
37  pixel_samples = 0;
40  rendered_tiles = 0;
41  denoised_tiles = 0;
42  start_time = time_dt();
44  end_time = 0.0;
45  status = "Initializing";
46  substatus = "";
47  sync_status = "";
48  sync_substatus = "";
49  kernel_status = "";
51  cancel = false;
52  cancel_message = "";
53  error = false;
54  error_message = "";
56  }
57 
58  Progress(Progress &progress)
59  {
60  *this = progress;
61  }
62 
64  {
65  thread_scoped_lock lock(progress.progress_mutex);
66 
67  progress.get_status(status, substatus);
68 
69  pixel_samples = progress.pixel_samples;
72 
73  return *this;
74  }
75 
76  void reset()
77  {
78  pixel_samples = 0;
81  rendered_tiles = 0;
82  denoised_tiles = 0;
83  start_time = time_dt();
85  end_time = 0.0;
86  status = "Initializing";
87  substatus = "";
88  sync_status = "";
89  sync_substatus = "";
90  kernel_status = "";
91  cancel = false;
92  cancel_message = "";
93  error = false;
94  error_message = "";
95  }
96 
97  /* cancel */
98  void set_cancel(const string &cancel_message_)
99  {
101  cancel_message = cancel_message_;
102  cancel = true;
103  }
104 
105  bool get_cancel()
106  {
107  if (!cancel && cancel_cb)
108  cancel_cb();
109 
110  return cancel;
111  }
112 
114  {
116  return cancel_message;
117  }
118 
119  void set_cancel_callback(function<void()> function)
120  {
121  cancel_cb = function;
122  }
123 
124  /* error */
125  void set_error(const string &error_message_)
126  {
128  error_message = error_message_;
129  error = true;
130  /* If error happens we also stop rendering. */
131  cancel_message = error_message_;
132  cancel = true;
133  }
134 
135  bool get_error()
136  {
137  return error;
138  }
139 
141  {
143  return error_message;
144  }
145 
146  /* tile and timing information */
147 
149  {
151 
152  start_time = time_dt();
153  end_time = 0.0;
154  }
155 
157  {
159 
161  }
162 
163  void add_skip_time(const scoped_timer &start_timer, bool only_render)
164  {
165  double skip_time = time_dt() - start_timer.get_start();
166 
167  render_start_time += skip_time;
168  if (!only_render) {
169  start_time += skip_time;
170  }
171  }
172 
173  void get_time(double &total_time_, double &render_time_)
174  {
176 
177  double time = (end_time > 0) ? end_time : time_dt();
178 
179  total_time_ = time - start_time;
180  render_time_ = time - render_start_time;
181  }
182 
184  {
185  end_time = time_dt();
186  }
187 
189  {
191 
192  pixel_samples = 0;
194  rendered_tiles = 0;
195  denoised_tiles = 0;
196  }
197 
198  void set_total_pixel_samples(uint64_t total_pixel_samples_)
199  {
201 
202  total_pixel_samples = total_pixel_samples_;
203  }
204 
205  float get_progress()
206  {
208 
209  if (total_pixel_samples > 0) {
210  return ((float)pixel_samples) / total_pixel_samples;
211  }
212  return 0.0f;
213  }
214 
215  void add_samples(uint64_t pixel_samples_, int tile_sample)
216  {
218 
219  pixel_samples += pixel_samples_;
220  current_tile_sample = tile_sample;
221  }
222 
223  void add_samples_update(uint64_t pixel_samples_, int tile_sample)
224  {
225  add_samples(pixel_samples_, tile_sample);
226  set_update();
227  }
228 
229  void add_finished_tile(bool denoised)
230  {
232 
233  if (denoised) {
234  denoised_tiles++;
235  }
236  else {
237  rendered_tiles++;
238  }
239  }
240 
242  {
244  /* Note that the value here always belongs to the last tile that updated,
245  * so it's only useful if there is only one active tile. */
246  return current_tile_sample;
247  }
248 
250  {
252  return rendered_tiles;
253  }
254 
256  {
258  return denoised_tiles;
259  }
260 
261  /* status messages */
262 
263  void set_status(const string &status_, const string &substatus_ = "")
264  {
265  {
267  status = status_;
268  substatus = substatus_;
269  }
270 
271  set_update();
272  }
273 
274  void set_substatus(const string &substatus_)
275  {
276  {
278  substatus = substatus_;
279  }
280 
281  set_update();
282  }
283 
284  void set_sync_status(const string &status_, const string &substatus_ = "")
285  {
286  {
288  sync_status = status_;
289  sync_substatus = substatus_;
290  }
291 
292  set_update();
293  }
294 
295  void set_sync_substatus(const string &substatus_)
296  {
297  {
299  sync_substatus = substatus_;
300  }
301 
302  set_update();
303  }
304 
305  void get_status(string &status_, string &substatus_)
306  {
308 
309  if (sync_status != "") {
310  status_ = sync_status;
311  substatus_ = sync_substatus;
312  }
313  else {
314  status_ = status;
315  substatus_ = substatus;
316  }
317  }
318 
319  /* kernel status */
320 
321  void set_kernel_status(const string &kernel_status_)
322  {
323  {
325  kernel_status = kernel_status_;
326  }
327 
328  set_update();
329  }
330 
331  void get_kernel_status(string &kernel_status_)
332  {
334  kernel_status_ = kernel_status;
335  }
336 
337  /* callback */
338 
339  void set_update()
340  {
341  if (update_cb) {
343  update_cb();
344  }
345  }
346 
347  void set_update_callback(function<void()> function)
348  {
349  update_cb = function;
350  }
351 
352  protected:
355  function<void()> update_cb;
356  function<void()> cancel_cb;
357 
358  /* pixel_samples counts how many samples have been rendered over all pixel, not just per pixel.
359  * This makes the progress estimate more accurate when tiles with different sizes are used.
360  *
361  * total_pixel_samples is the total amount of pixel samples that will be rendered. */
363  /* Stores the current sample count of the last tile that called the update function.
364  * It's used to display the sample count if only one tile is active. */
366  /* Stores the number of tiles that's already finished.
367  * Used to determine whether all but the last tile are finished rendering,
368  * in which case the current_tile_sample is displayed. */
370 
372  /* End time written when render is done, so it doesn't keep increasing on redraws. */
373  double end_time;
374 
375  string status;
376  string substatus;
377 
378  string sync_status;
380 
382 
383  volatile bool cancel;
385 
386  volatile bool error;
388 };
389 
391 
392 #endif /* __UTIL_PROGRESS_H__ */
Progress & operator=(Progress &progress)
Definition: util_progress.h:63
function< void()> update_cb
void set_cancel_callback(function< void()> function)
int denoised_tiles
string sync_substatus
float get_progress()
Progress(Progress &progress)
Definition: util_progress.h:58
void set_total_pixel_samples(uint64_t total_pixel_samples_)
void set_cancel(const string &cancel_message_)
Definition: util_progress.h:98
void get_status(string &status_, string &substatus_)
string status
int get_rendered_tiles()
bool get_cancel()
int get_denoised_tiles()
volatile bool error
int rendered_tiles
void set_end_time()
int current_tile_sample
void set_substatus(const string &substatus_)
void set_sync_substatus(const string &substatus_)
void set_kernel_status(const string &kernel_status_)
double start_time
string error_message
thread_mutex update_mutex
void reset_sample()
void set_status(const string &status_, const string &substatus_="")
double render_start_time
string substatus
void set_update()
string cancel_message
void set_sync_status(const string &status_, const string &substatus_="")
volatile bool cancel
int get_current_sample()
void get_time(double &total_time_, double &render_time_)
void reset()
Definition: util_progress.h:76
void add_samples(uint64_t pixel_samples_, int tile_sample)
uint64_t total_pixel_samples
void set_error(const string &error_message_)
thread_mutex progress_mutex
string get_error_message()
double end_time
void add_samples_update(uint64_t pixel_samples_, int tile_sample)
void set_render_start_time()
void add_finished_tile(bool denoised)
string get_cancel_message()
uint64_t pixel_samples
bool get_error()
string sync_status
void add_skip_time(const scoped_timer &start_timer, bool only_render)
string kernel_status
void set_start_time()
void get_kernel_status(string &kernel_status_)
function< void()> cancel_cb
void set_update_callback(function< void()> function)
double get_start() const
Definition: util_time.h:49
double time
#define CCL_NAMESPACE_END
unsigned __int64 uint64_t
Definition: stdint.h:93
#define function_null
Definition: util_function.h:25
std::unique_lock< std::mutex > thread_scoped_lock
Definition: util_thread.h:41
CCL_NAMESPACE_BEGIN typedef std::mutex thread_mutex
Definition: util_thread.h:40
CCL_NAMESPACE_BEGIN double time_dt()
Definition: util_time.cpp:48