Blender V4.5
render_internal.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2008 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <cstddef>
10#include <cstring>
11
12#include "MEM_guardedalloc.h"
13
14#include "BLI_listbase.h"
15#include "BLI_rect.h"
16#include "BLI_string.h"
17#include "BLI_string_utils.hh"
18#include "BLI_time.h"
19#include "BLI_timecode.h"
20#include "BLI_utildefines.h"
21
22#include "BLT_translation.hh"
23
24#include "DNA_object_types.h"
25#include "DNA_scene_types.h"
26#include "DNA_userdef_types.h"
27#include "DNA_view3d_types.h"
28
29#include "BKE_colortools.hh"
30#include "BKE_context.hh"
31#include "BKE_global.hh"
32#include "BKE_image.hh"
33#include "BKE_image_format.hh"
34#include "BKE_layer.hh"
35#include "BKE_lib_id.hh"
36#include "BKE_main.hh"
38#include "BKE_object.hh"
39#include "BKE_report.hh"
40#include "BKE_scene.hh"
41#include "BKE_screen.hh"
42
43#include "NOD_composite.hh"
44
45#include "DEG_depsgraph.hh"
46
47#include "WM_api.hh"
48#include "WM_types.hh"
49
50#include "ED_render.hh"
51#include "ED_screen.hh"
52#include "ED_util.hh"
53
54#include "BIF_glutil.hh"
55
56#include "RE_engine.h"
57#include "RE_pipeline.h"
58
60#include "IMB_imbuf_types.hh"
61
62#include "RNA_access.hh"
63#include "RNA_define.hh"
64
65#include "SEQ_relations.hh"
66
67#include "render_intern.hh"
68
69/* Render Callbacks */
70static bool render_break(void *rjv);
71
94
95/* called inside thread! */
97 const ImBuf *ibuf,
98 rcti *renrect,
99 rcti *r_ibuf_rect,
100 int *r_offset_x,
101 int *r_offset_y)
102{
103 int tile_y, tile_height, tile_x, tile_width;
104
105 /* When `renrect` argument is not nullptr, we only refresh scan-lines. */
106 if (renrect) {
107 /* `if (tile_height == recty)`, rendering of layer is ready,
108 * we should not draw, other things happen... */
109 if (rr->renlay == nullptr || renrect->ymax >= rr->recty) {
110 return false;
111 }
112
113 /* `tile_x` here is first sub-rectangle x coord, tile_width defines sub-rectangle width. */
114 tile_x = renrect->xmin;
115 tile_width = renrect->xmax - tile_x;
116 if (tile_width < 2) {
117 return false;
118 }
119
120 tile_y = renrect->ymin;
121 tile_height = renrect->ymax - tile_y;
122 if (tile_height < 2) {
123 return false;
124 }
125 renrect->ymin = renrect->ymax;
126 }
127 else {
128 tile_x = tile_y = 0;
129 tile_width = rr->rectx;
130 tile_height = rr->recty;
131 }
132
133 /* tile_x tile_y is in tile coords. transform to ibuf */
134 int offset_x = rr->tilerect.xmin;
135 if (offset_x >= ibuf->x) {
136 return false;
137 }
138 int offset_y = rr->tilerect.ymin;
139 if (offset_y >= ibuf->y) {
140 return false;
141 }
142
143 if (offset_x + tile_width > ibuf->x) {
144 tile_width = ibuf->x - offset_x;
145 }
146 if (offset_y + tile_height > ibuf->y) {
147 tile_height = ibuf->y - offset_y;
148 }
149
150 if (tile_width < 1 || tile_height < 1) {
151 return false;
152 }
153
154 r_ibuf_rect->xmax = tile_x + tile_width;
155 r_ibuf_rect->ymax = tile_y + tile_height;
156 r_ibuf_rect->xmin = tile_x;
157 r_ibuf_rect->ymin = tile_y;
158 *r_offset_x = offset_x;
159 *r_offset_y = offset_y;
160 return true;
161}
162
164 RenderResult *rr,
165 ImBuf *ibuf,
166 ImageUser *iuser,
167 const rcti *tile_rect,
168 int offset_x,
169 int offset_y,
170 const char *viewname)
171{
172 Scene *scene = rj->scene;
173 const float *rectf = nullptr;
174 int linear_stride, linear_offset_x, linear_offset_y;
175 const ColorManagedViewSettings *view_settings;
176 const ColorManagedDisplaySettings *display_settings;
177
179 /* The whole image buffer is to be color managed again anyway. */
180 return;
181 }
182
183 /* The thing here is, the logic below (which was default behavior
184 * of how rectf is acquiring since forever) gives float buffer for
185 * composite output only. This buffer can not be used for other
186 * passes obviously.
187 *
188 * We might try finding corresponding for pass buffer in render result
189 * (which is actually missing when rendering with Cycles, who only
190 * writes all the passes when the tile is finished) or use float
191 * buffer from image buffer as reference, which is easier to use and
192 * contains all the data we need anyway.
193 * - sergey -
194 */
195 /* TODO(sergey): Need to check has_combined here? */
196 if (iuser->pass == 0) {
197 const int view_id = BKE_scene_multiview_view_id_get(&scene->r, viewname);
198 const RenderView *rv = RE_RenderViewGetById(rr, view_id);
199
200 if (rv->ibuf == nullptr) {
201 return;
202 }
203
204 /* find current float rect for display, first case is after composite... still weak */
205 if (rv->ibuf->float_buffer.data) {
206 rectf = rv->ibuf->float_buffer.data;
207 }
208 else {
209 if (rv->ibuf->byte_buffer.data) {
210 /* special case, currently only happens with sequencer rendering,
211 * which updates the whole frame, so we can only mark display buffer
212 * as invalid here (sergey)
213 */
215 return;
216 }
217 if (rr->renlay == nullptr) {
218 return;
219 }
220 rectf = RE_RenderLayerGetPass(rr->renlay, RE_PASSNAME_COMBINED, viewname);
221 }
222 if (rectf == nullptr) {
223 return;
224 }
225
226 rectf += 4 * (rr->rectx * tile_rect->ymin + tile_rect->xmin);
227 linear_stride = rr->rectx;
228 linear_offset_x = offset_x;
229 linear_offset_y = offset_y;
230 }
231 else {
232 rectf = ibuf->float_buffer.data;
233 linear_stride = ibuf->x;
234 linear_offset_x = 0;
235 linear_offset_y = 0;
236 }
237
238 view_settings = &scene->view_settings;
239 display_settings = &scene->display_settings;
240
242 rectf,
243 nullptr,
244 linear_stride,
245 linear_offset_x,
246 linear_offset_y,
247 view_settings,
248 display_settings,
249 offset_x,
250 offset_y,
251 offset_x + BLI_rcti_size_x(tile_rect),
252 offset_y + BLI_rcti_size_y(tile_rect));
253}
254
255/* ****************************** render invoking ***************** */
256
257/* set callbacks, exported to sequence render too.
258 * Only call in foreground (UI) renders. */
259
261 wmOperator *op, Main *mainp, ViewLayer *active_layer, Scene **scene, ViewLayer **single_layer)
262{
263 /* single layer re-render */
264 if (RNA_struct_property_is_set(op->ptr, "scene")) {
265 Scene *scn;
266 char scene_name[MAX_ID_NAME - 2];
267
268 RNA_string_get(op->ptr, "scene", scene_name);
269 scn = (Scene *)BLI_findstring(&mainp->scenes, scene_name, offsetof(ID, name) + 2);
270
271 if (scn) {
272 /* camera switch won't have updated */
273 scn->r.cfra = (*scene)->r.cfra;
275
276 *scene = scn;
277 }
278 }
279
280 if (RNA_struct_property_is_set(op->ptr, "layer")) {
281 ViewLayer *rl;
282 char rl_name[RE_MAXNAME];
283
284 RNA_string_get(op->ptr, "layer", rl_name);
285 rl = (ViewLayer *)BLI_findstring(&(*scene)->view_layers, rl_name, offsetof(ViewLayer, name));
286
287 if (rl) {
288 *single_layer = rl;
289 }
290 }
291 else if (((*scene)->r.scemode & R_SINGLE_LAYER) && active_layer) {
292 *single_layer = active_layer;
293 }
294}
295
296/* executes blocking render */
298{
299 Scene *scene = CTX_data_scene(C);
300 RenderEngineType *re_type = RE_engines_find(scene->r.engine);
301 ViewLayer *active_layer = CTX_data_view_layer(C);
302 ViewLayer *single_layer = nullptr;
303 Render *re;
304 Image *ima;
305 View3D *v3d = CTX_wm_view3d(C);
306 Main *mainp = CTX_data_main(C);
307 const bool is_animation = RNA_boolean_get(op->ptr, "animation");
308 const bool is_write_still = RNA_boolean_get(op->ptr, "write_still");
309 Object *camera_override = v3d ? V3D_CAMERA_LOCAL(v3d) : nullptr;
310
311 /* Cannot do render if there is not this function. */
312 if (re_type->render == nullptr) {
313 return OPERATOR_CANCELLED;
314 }
315
316 /* custom scene and single layer re-render */
317 screen_render_single_layer_set(op, mainp, active_layer, &scene, &single_layer);
318
319 if (!is_animation && is_write_still && BKE_imtype_is_movie(scene->r.im_format.imtype)) {
321 op->reports, RPT_ERROR, "Cannot write a single file with an animation format selected");
322 return OPERATOR_CANCELLED;
323 }
324
325 re = RE_NewSceneRender(scene);
326
327 G.is_break = false;
328
329 RE_draw_lock_cb(re, nullptr, nullptr);
330 RE_test_break_cb(re, nullptr, render_break);
331
332 ima = BKE_image_ensure_viewer(mainp, IMA_TYPE_R_RESULT, "Render Result");
333 BKE_image_signal(mainp, ima, nullptr, IMA_SIGNAL_FREE);
334 BKE_image_backup_render(scene, ima, true);
335
336 /* cleanup sequencer caches before starting user triggered render.
337 * otherwise, invalidated cache entries can make their way into
338 * the output rendering. We can't put that into RE_RenderFrame,
339 * since sequence rendering can call that recursively... (peter) */
341
342 RE_SetReports(re, op->reports);
343
344 if (is_animation) {
345 RE_RenderAnim(re,
346 mainp,
347 scene,
348 single_layer,
349 camera_override,
350 scene->r.sfra,
351 scene->r.efra,
352 scene->r.frame_step);
353 }
354 else {
356 mainp,
357 scene,
358 single_layer,
359 camera_override,
360 scene->r.cfra,
361 scene->r.subframe,
362 is_write_still);
363 }
364
365 RE_SetReports(re, nullptr);
366
367 const bool cancelled = G.is_break;
368
369 if (cancelled) {
371 if (rr && rr->error) {
372 /* NOTE(@ideasman42): Report, otherwise the error is entirely hidden from script authors.
373 * This is only done for the #wmOperatorType::exec function because it's assumed users
374 * rendering interactively will view the render and see the error message there. */
376 }
378 }
379
380 /* No redraw needed, we leave state as we entered it. */
382
384
385 if (cancelled) {
386 return OPERATOR_CANCELLED;
387 }
388 return OPERATOR_FINISHED;
389}
390
391static void render_freejob(void *rjv)
392{
393 RenderJob *rj = static_cast<RenderJob *>(rjv);
394
396 MEM_delete(rj);
397}
398
400 const Scene *scene,
401 const bool v3d_override,
402 const char *error,
404{
405 const char *info_space = " ";
406 const char *info_sep = "| ";
407 struct {
408 char time_last[32];
409 char time_elapsed[32];
410 char frame[16];
411 char statistics[64];
412 } info_buffers;
413
414 const char *ret_array[32];
415 int i = 0;
416
417 const uintptr_t mem_in_use = MEM_get_memory_in_use();
418 const uintptr_t peak_memory = MEM_get_peak_memory();
419
420 const float megs_used_memory = (mem_in_use) / (1024.0 * 1024.0);
421 const float megs_peak_memory = (peak_memory) / (1024.0 * 1024.0);
422
423 /* local view */
424 if (rs->localview) {
425 ret_array[i++] = RPT_("3D Local View ");
426 ret_array[i++] = info_sep;
427 }
428 else if (v3d_override) {
429 ret_array[i++] = RPT_("3D View ");
430 ret_array[i++] = info_sep;
431 }
432
433 /* frame number */
434 SNPRINTF(info_buffers.frame, "%d ", scene->r.cfra);
435 ret_array[i++] = RPT_("Frame:");
436 ret_array[i++] = info_buffers.frame;
437
438 /* Previous and elapsed time. */
439 const char *info_time = info_buffers.time_last;
441 info_buffers.time_last, sizeof(info_buffers.time_last), rs->lastframetime);
442
443 ret_array[i++] = info_sep;
444 if (rs->infostr && rs->infostr[0]) {
445 if (rs->lastframetime != 0.0) {
446 ret_array[i++] = "Last:";
447 ret_array[i++] = info_buffers.time_last;
448 ret_array[i++] = info_space;
449 }
450
451 info_time = info_buffers.time_elapsed;
452 BLI_timecode_string_from_time_simple(info_buffers.time_elapsed,
453 sizeof(info_buffers.time_elapsed),
455 }
456
457 ret_array[i++] = RPT_("Time:");
458 ret_array[i++] = info_time;
459 ret_array[i++] = info_space;
460
461 /* Statistics. */
462 {
463 const char *info_statistics = nullptr;
464 if (rs->statstr) {
465 if (rs->statstr[0]) {
466 info_statistics = rs->statstr;
467 }
468 }
469 else {
470 if (rs->mem_peak == 0.0f) {
471 SNPRINTF(info_buffers.statistics,
472 RPT_("Mem:%.2fM (Peak %.2fM)"),
473 megs_used_memory,
474 megs_peak_memory);
475 }
476 else {
477 SNPRINTF(
478 info_buffers.statistics, RPT_("Mem:%.2fM, Peak: %.2fM"), rs->mem_used, rs->mem_peak);
479 }
480 info_statistics = info_buffers.statistics;
481 }
482
483 if (info_statistics) {
484 ret_array[i++] = info_sep;
485 ret_array[i++] = info_statistics;
486 ret_array[i++] = info_space;
487 }
488 }
489
490 /* Extra info. */
491 {
492 const char *info_extra = nullptr;
493 if (rs->infostr && rs->infostr[0]) {
494 info_extra = rs->infostr;
495 }
496 else if (error && error[0]) {
497 info_extra = error;
498 }
499
500 if (info_extra) {
501 ret_array[i++] = info_sep;
502 ret_array[i++] = info_extra;
503 ret_array[i++] = info_space;
504 }
505 }
506
507 if (G.debug & G_DEBUG) {
509 printf("WARNING! renderwin text beyond limit\n");
510 }
511 }
512
513 BLI_assert(i < int(BOUNDED_ARRAY_TYPE_SIZE<decltype(ret_array)>()));
515}
516
517static void image_renderinfo_cb(void *rjv, RenderStats *rs)
518{
519 RenderJob *rj = static_cast<RenderJob *>(rjv);
520 RenderResult *rr;
521
522 rr = RE_AcquireResultRead(rj->re);
523
524 if (rr) {
525 /* `malloc` is OK here, `stats_draw` is not in tile threads. */
526 if (rr->text == nullptr) {
528 }
529
530 make_renderinfo_string(rs, rj->scene, rj->v3d_override, rr->error, rr->text);
531 }
532
533 RE_ReleaseResult(rj->re);
534
535 /* make jobs timer to send notifier */
536 *(rj->do_update) = true;
537}
538
539static void render_progress_update(void *rjv, float progress)
540{
541 RenderJob *rj = static_cast<RenderJob *>(rjv);
542
543 if (rj->progress && *rj->progress != progress) {
544 *rj->progress = progress;
545
546 /* make jobs timer to send notifier */
547 *(rj->do_update) = true;
548 }
549}
550
551/* Not totally reliable, but works fine in most of cases and
552 * in worst case would just make it so extra color management
553 * for the whole render result is applied (which was already
554 * happening already).
555 */
557{
558 ScrArea *first_area = nullptr, *matched_area = nullptr;
559
560 /* image window, compo node users */
561
562 /* Only ever 1 `wm`. */
563 for (wmWindowManager *wm = static_cast<wmWindowManager *>(rj->main->wm.first);
564 wm && matched_area == nullptr;
565 wm = static_cast<wmWindowManager *>(wm->id.next))
566 {
567 wmWindow *win;
568 for (win = static_cast<wmWindow *>(wm->windows.first); win && matched_area == nullptr;
569 win = win->next)
570 {
571 const bScreen *screen = WM_window_get_active_screen(win);
572
573 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
574 if (area->spacetype == SPACE_IMAGE) {
575 SpaceImage *sima = static_cast<SpaceImage *>(area->spacedata.first);
576 /* area->spacedata might be empty when toggling full-screen mode. */
577 if (sima != nullptr && sima->image == rj->image) {
578 if (first_area == nullptr) {
579 first_area = area;
580 }
581 if (area == rj->area) {
582 matched_area = area;
583 break;
584 }
585 }
586 }
587 }
588 }
589 }
590
591 if (matched_area == nullptr) {
592 matched_area = first_area;
593 }
594
595 if (matched_area) {
596 SpaceImage *sima = static_cast<SpaceImage *>(matched_area->spacedata.first);
597 RenderResult *main_rr = RE_AcquireResultRead(rj->re);
598
599 /* TODO(sergey): is there faster way to get the layer index? */
600 if (rr->renlay) {
601 int layer = BLI_findstringindex(
602 &main_rr->layers, (char *)rr->renlay->name, offsetof(RenderLayer, name));
603 sima->iuser.layer = layer;
604 rj->last_layer = layer;
605 }
606
607 iuser->pass = sima->iuser.pass;
608 iuser->layer = sima->iuser.layer;
609
610 RE_ReleaseResult(rj->re);
611 }
612}
613
614static void image_rect_update(void *rjv, RenderResult *rr, rcti *renrect)
615{
616 RenderJob *rj = static_cast<RenderJob *>(rjv);
617 Image *ima = rj->image;
618 ImBuf *ibuf;
619 void *lock;
620 const char *viewname = RE_GetActiveRenderView(rj->re);
621
622 /* only update if we are displaying the slot being rendered */
623 if (ima->render_slot != ima->last_render_slot) {
624 rj->image_outdated = true;
625 return;
626 }
627 if (rj->image_outdated) {
628 /* Free all render buffer caches when switching slots, with lock to ensure main
629 * thread is not drawing the buffer at the same time. */
630 rj->image_outdated = false;
631 ibuf = BKE_image_acquire_ibuf(ima, &rj->iuser, &lock);
633 BKE_image_release_ibuf(ima, ibuf, lock);
634 *(rj->do_update) = true;
635 return;
636 }
637
638 if (rr == nullptr) {
639 return;
640 }
641
642 /* update part of render */
644 rcti tile_rect;
645 int offset_x;
646 int offset_y;
647 ibuf = BKE_image_acquire_ibuf(ima, &rj->iuser, &lock);
648 if (ibuf) {
649 if (!image_buffer_calc_tile_rect(rr, ibuf, renrect, &tile_rect, &offset_x, &offset_y)) {
650 BKE_image_release_ibuf(ima, ibuf, lock);
651 return;
652 }
653
654 /* Don't waste time on CPU side color management if
655 * image will be displayed using GLSL.
656 *
657 * Need to update rect if Save Buffers enabled because in
658 * this case GLSL doesn't have original float buffer to
659 * operate with.
660 */
661 if (ibuf->channels == 1 || ED_draw_imbuf_method(ibuf) != IMAGE_DRAW_METHOD_GLSL) {
662 image_buffer_rect_update(rj, rr, ibuf, &rj->iuser, &tile_rect, offset_x, offset_y, viewname);
663 }
664 ImageTile *image_tile = BKE_image_get_tile(ima, 0);
666 image_tile,
667 ibuf,
668 offset_x,
669 offset_y,
670 BLI_rcti_size_x(&tile_rect),
671 BLI_rcti_size_y(&tile_rect));
672
673 /* make jobs timer to send notifier */
674 *(rj->do_update) = true;
675 }
676 BKE_image_release_ibuf(ima, ibuf, lock);
677}
678
679static void current_scene_update(void *rjv, Scene *scene)
680{
681 RenderJob *rj = static_cast<RenderJob *>(rjv);
682
683 if (rj->current_scene != scene) {
684 /* Image must be updated when rendered scene changes. */
686 }
687
688 rj->current_scene = scene;
689 rj->iuser.scene = scene;
690}
691
692static void render_startjob(void *rjv, wmJobWorkerStatus *worker_status)
693{
694 RenderJob *rj = static_cast<RenderJob *>(rjv);
695
696 rj->stop = &worker_status->stop;
697 rj->do_update = &worker_status->do_update;
698 rj->progress = &worker_status->progress;
699
700 RE_SetReports(rj->re, rj->reports);
701
702 if (rj->anim) {
703 RE_RenderAnim(rj->re,
704 rj->main,
705 rj->scene,
706 rj->single_layer,
707 rj->camera_override,
708 rj->scene->r.sfra,
709 rj->scene->r.efra,
710 rj->scene->r.frame_step);
711 }
712 else {
713 RE_RenderFrame(rj->re,
714 rj->main,
715 rj->scene,
716 rj->single_layer,
717 rj->camera_override,
718 rj->scene->r.cfra,
719 rj->scene->r.subframe,
720 rj->write_still);
721 }
722
723 RE_SetReports(rj->re, nullptr);
724}
725
727{
728 /* image window, compo node users */
729
730 /* Only ever 1 `wm`. */
731 LISTBASE_FOREACH (wmWindowManager *, wm, &rj->main->wm) {
732 LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
733 const bScreen *screen = WM_window_get_active_screen(win);
734
735 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
736 if (area == rj->area) {
737 if (area->spacetype == SPACE_IMAGE) {
738 SpaceImage *sima = static_cast<SpaceImage *>(area->spacedata.first);
739
740 if (RE_HasSingleLayer(rj->re)) {
741 /* For single layer renders keep the active layer
742 * visible, or show the compositing result. */
744 if (RE_HasCombinedLayer(rr)) {
745 sima->iuser.layer = 0;
746 }
747 RE_ReleaseResult(rj->re);
748 }
749 else {
750 /* For multiple layer render, set back the layer
751 * that was set at the start of rendering. */
752 sima->iuser.layer = rj->orig_layer;
753 }
754 }
755 return;
756 }
757 }
758 }
759 }
760}
761
762static void render_endjob(void *rjv)
763{
764 RenderJob *rj = static_cast<RenderJob *>(rjv);
765
766 /* This render may be used again by the sequencer without the active
767 * 'Render' where the callbacks would be re-assigned. assign dummy callbacks
768 * to avoid referencing freed render-jobs bug #24508. */
769 RE_InitRenderCB(rj->re);
770
771 if (rj->main != G_MAIN) {
772 BKE_main_free(rj->main);
773 }
774
775 /* Update depsgraph for returning to the original frame before animation render job. */
776 if (rj->anim && !(rj->scene->r.scemode & R_NO_FRAME_UPDATE)) {
777 /* Possible this fails when loading new file while rendering. */
778 if (G_MAIN->wm.first) {
779 /* Check view layer was not deleted during render. Technically another view layer
780 * may get allocated with the same pointer, but worst case it will cause an
781 * unnecessary update. */
782 if (BLI_findindex(&rj->scene->view_layers, rj->view_layer) != -1) {
783 Depsgraph *depsgraph = BKE_scene_get_depsgraph(rj->scene, rj->view_layer);
784 if (depsgraph) {
786 }
787 }
788 }
789 }
790
791 /* XXX above function sets all tags in nodes */
793
794 /* potentially set by caller */
796
797 if (rj->single_layer) {
801 }
802
803 if (rj->area) {
805 }
806
807 /* XXX render stability hack */
808 G.is_rendering = false;
810
811 /* Partial render result will always update display buffer
812 * for first render layer only. This is nice because you'll
813 * see render progress during rendering, but it ends up in
814 * wrong display buffer shown after rendering.
815 *
816 * The code below will mark display buffer as invalid after
817 * rendering in case multiple layers were rendered, which
818 * ensures display buffer matches render layer after
819 * rendering.
820 *
821 * Perhaps proper way would be to toggle active render
822 * layer in image editor and job, so we always display
823 * layer being currently rendered. But this is not so much
824 * trivial at this moment, especially because of external
825 * engine API, so lets use simple and robust way for now
826 * - sergey -
827 */
828 if (rj->scene->view_layers.first != rj->scene->view_layers.last || rj->image_outdated) {
829 void *lock;
830 Image *ima = rj->image;
831 ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &rj->iuser, &lock);
832
833 if (ibuf) {
835 }
836
837 BKE_image_release_ibuf(ima, ibuf, lock);
838 }
839
840 /* Finally unlock the user interface (if it was locked). */
841 if (rj->interface_locked) {
842 /* Interface was locked, so window manager couldn't have been changed
843 * and using one from Global will unlock exactly the same manager as
844 * was locked before running the job.
845 */
846 WM_set_locked_interface(static_cast<wmWindowManager *>(G_MAIN->wm.first), false);
848 }
849}
850
851/* called by render, check job 'stop' value or the global */
852static bool render_breakjob(void *rjv)
853{
854 RenderJob *rj = static_cast<RenderJob *>(rjv);
855
856 if (G.is_break) {
857 return true;
858 }
859 if (rj->stop && *(rj->stop)) {
860 return true;
861 }
862 return false;
863}
864
869static bool render_break(void * /*rjv*/)
870{
871 if (G.is_break) {
872 return true;
873 }
874 return false;
875}
876
877/* runs in thread, no cursor setting here works. careful with notifiers too (`malloc` conflicts) */
878/* maybe need a way to get job send notifier? */
879static void render_drawlock(void *rjv, bool lock)
880{
881 RenderJob *rj = static_cast<RenderJob *>(rjv);
882
883 /* If interface is locked, renderer callback shall do nothing. */
884 if (!rj->interface_locked) {
886 }
887}
888
891{
892 Scene *scene = (Scene *)op->customdata;
893
894 /* no running blender, remove handler and pass through */
895 if (0 == WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_RENDER)) {
897 }
898
899 /* running render */
901}
902
904{
906 Scene *scene = (Scene *)op->customdata;
907
908 /* kill on cancel, because job is using op->reports */
910}
911
913{
915 return;
916 }
917
918 Object *object = base->object;
919
920 if (object->id.tag & ID_TAG_DOIT) {
921 return;
922 }
923
924 object->id.tag &= ~ID_TAG_DOIT;
925 if (RE_allow_render_generic_object(object)) {
927 }
928}
929
930static void clean_viewport_memory(Main *bmain, Scene *scene)
931{
932 Scene *sce_iter;
933 Base *base;
934
935 /* Tag all the available objects. */
937
938 /* Go over all the visible objects. */
939
940 /* Only ever 1 `wm`. */
941 LISTBASE_FOREACH (wmWindowManager *, wm, &bmain->wm) {
942 LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
944 BKE_view_layer_synced_ensure(scene, view_layer);
945
948 }
949 }
950 }
951
952 for (SETLOOPER_SET_ONLY(scene, sce_iter, base)) {
954 }
955}
956
957/* using context, starts job */
959{
960 /* new render clears all callbacks */
961 Main *bmain = CTX_data_main(C);
962 Scene *scene = CTX_data_scene(C);
963 ViewLayer *active_layer = CTX_data_view_layer(C);
964 ViewLayer *single_layer = nullptr;
965 RenderEngineType *re_type = RE_engines_find(scene->r.engine);
966 Render *re;
967 wmJob *wm_job;
968 RenderJob *rj;
969 Image *ima;
970 const bool is_animation = RNA_boolean_get(op->ptr, "animation");
971 const bool is_write_still = RNA_boolean_get(op->ptr, "write_still");
972 const bool use_viewport = RNA_boolean_get(op->ptr, "use_viewport");
973 View3D *v3d = use_viewport ? CTX_wm_view3d(C) : nullptr;
974 Object *camera_override = v3d ? V3D_CAMERA_LOCAL(v3d) : nullptr;
975 const char *name;
976 ScrArea *area;
977
978 /* Cannot do render if there is not this function. */
979 if (re_type->render == nullptr) {
980 return OPERATOR_CANCELLED;
981 }
982
983 /* custom scene and single layer re-render */
984 screen_render_single_layer_set(op, bmain, active_layer, &scene, &single_layer);
985
986 /* only one render job at a time */
988 return OPERATOR_CANCELLED;
989 }
990
991 if (!RE_is_rendering_allowed(scene, single_layer, camera_override, op->reports)) {
992 return OPERATOR_CANCELLED;
993 }
994
995 if (!is_animation && is_write_still && BKE_imtype_is_movie(scene->r.im_format.imtype)) {
997 op->reports, RPT_ERROR, "Cannot write a single file with an animation format selected");
998 return OPERATOR_CANCELLED;
999 }
1000
1001 /* Reports are done inside check function, and it will return false if there are other strips to
1002 * render. */
1003 if ((scene->r.scemode & R_DOSEQ) &&
1005 {
1006 return OPERATOR_CANCELLED;
1007 }
1008
1009 /* stop all running jobs, except screen one. currently previews frustrate Render */
1011
1012 /* cancel animation playback */
1015 }
1016
1017 /* handle UI stuff */
1018 WM_cursor_wait(true);
1019
1020 /* flush sculpt and editmode changes */
1021 ED_editors_flush_edits_ex(bmain, true, false);
1022
1023 /* Cleanup VSE cache, since it is not guaranteed that stored images are invalid. */
1025
1026 /* store spare
1027 * get view3d layer, local layer, make this nice API call to render
1028 * store spare */
1029
1030 /* ensure at least 1 area shows result */
1031 area = render_view_open(C, event->xy[0], event->xy[1], op->reports);
1032
1033 /* job custom data */
1034 rj = MEM_new<RenderJob>("render job");
1035 rj->main = bmain;
1036 rj->scene = scene;
1037 rj->current_scene = rj->scene;
1039 rj->single_layer = single_layer;
1040 rj->camera_override = camera_override;
1041 rj->anim = is_animation;
1042 rj->write_still = is_write_still && !is_animation;
1043 rj->iuser.scene = scene;
1044 rj->reports = op->reports;
1045 rj->orig_layer = 0;
1046 rj->last_layer = 0;
1047 rj->area = area;
1048
1051
1052 if (area) {
1053 SpaceImage *sima = static_cast<SpaceImage *>(area->spacedata.first);
1054 rj->orig_layer = sima->iuser.layer;
1055 }
1056
1057 if (v3d) {
1058 if (camera_override && camera_override != scene->camera) {
1059 rj->v3d_override = true;
1060 }
1061 }
1062
1063 /* Lock the user interface depending on render settings. */
1064 if (scene->r.use_lock_interface) {
1066
1067 /* Set flag interface need to be unlocked.
1068 *
1069 * This is so because we don't have copy of render settings
1070 * accessible from render job and copy is needed in case
1071 * of non-locked rendering, so we wouldn't try to unlock
1072 * anything if option was initially unset but then was
1073 * enabled during rendering.
1074 */
1075 rj->interface_locked = true;
1076
1077 /* Clean memory used by viewport? */
1078 clean_viewport_memory(rj->main, scene);
1079 }
1080
1081 /* setup job */
1082 if (RE_seq_render_active(scene, &scene->r)) {
1083 name = RPT_("Rendering sequence...");
1084 }
1085 else {
1086 name = RPT_("Render...");
1087 }
1088
1089 wm_job = WM_jobs_get(CTX_wm_manager(C),
1091 scene,
1092 name,
1096 WM_jobs_timer(wm_job, 0.2, NC_SCENE | ND_RENDER_RESULT, 0);
1097 WM_jobs_callbacks(wm_job, render_startjob, nullptr, nullptr, render_endjob);
1098
1099 if (RNA_struct_property_is_set(op->ptr, "layer")) {
1100 WM_jobs_delay_start(wm_job, 0.2);
1101 }
1102
1103 /* get a render result image, and make sure it is empty */
1104 ima = BKE_image_ensure_viewer(bmain, IMA_TYPE_R_RESULT, "Render Result");
1105 BKE_image_signal(rj->main, ima, nullptr, IMA_SIGNAL_FREE);
1106 BKE_image_backup_render(rj->scene, ima, true);
1107 rj->image = ima;
1108
1109 /* setup new render */
1110 re = RE_NewSceneRender(scene);
1118
1119 rj->re = re;
1120 G.is_break = false;
1121
1122 /* store actual owner of job, so modal operator could check for it,
1123 * the reason of this is that active scene could change when rendering
1124 * several layers from compositor #31800. */
1125 op->customdata = scene;
1126
1127 WM_jobs_start(CTX_wm_manager(C), wm_job);
1128
1129 WM_cursor_wait(false);
1131
1132 /* we set G.is_rendering here already instead of only in the job, this ensure
1133 * main loop or other scene updates are disabled in time, since they may
1134 * have started before the job thread */
1135 G.is_rendering = true;
1136
1137 /* add modal handler for ESC */
1139
1141}
1142
1144{
1145 PropertyRNA *prop;
1146
1147 /* identifiers */
1148 ot->name = "Render";
1149 ot->description = "Render active scene";
1150 ot->idname = "RENDER_OT_render";
1151
1152 /* API callbacks. */
1153 ot->invoke = screen_render_invoke;
1154 ot->modal = screen_render_modal;
1155 ot->cancel = screen_render_cancel;
1156 ot->exec = screen_render_exec;
1157
1158 /* This isn't needed, causes failure in background mode. */
1159#if 0
1161#endif
1162
1163 prop = RNA_def_boolean(ot->srna,
1164 "animation",
1165 false,
1166 "Animation",
1167 "Render files from the animation range of this scene");
1170 ot->srna,
1171 "write_still",
1172 false,
1173 "Write Image",
1174 "Save the rendered image to the output path (used only when animation is disabled)");
1175 prop = RNA_def_boolean(ot->srna,
1176 "use_viewport",
1177 false,
1178 "Use 3D Viewport",
1179 "When inside a 3D viewport, use layers and camera of the viewport");
1181 prop = RNA_def_string(ot->srna,
1182 "layer",
1183 nullptr,
1184 RE_MAXNAME,
1185 "Render Layer",
1186 "Single render layer to re-render (used only when animation is disabled)");
1188 prop = RNA_def_string(ot->srna,
1189 "scene",
1190 nullptr,
1191 MAX_ID_NAME - 2,
1192 "Scene",
1193 "Scene to render, current scene if not specified");
1195}
1196
1198{
1202
1203 if (rj) {
1204 return rj->scene;
1205 }
1206
1207 return nullptr;
1208}
1209
1211{
1215 if (rj) {
1216 return rj->current_scene;
1217 }
1218 return nullptr;
1219}
1220
1221/* Motion blur curve preset */
1222
1224{
1225 Scene *scene = CTX_data_scene(C);
1226 CurveMapping *mblur_shutter_curve = &scene->r.mblur_shutter_curve;
1227 CurveMap *cm = mblur_shutter_curve->cm;
1228 int preset = RNA_enum_get(op->ptr, "shape");
1229
1230 mblur_shutter_curve->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
1231 mblur_shutter_curve->preset = preset;
1233 cm, &mblur_shutter_curve->clipr, mblur_shutter_curve->preset, CURVEMAP_SLOPE_POS_NEG);
1234 BKE_curvemapping_changed(mblur_shutter_curve, false);
1235
1236 return OPERATOR_FINISHED;
1237}
1238
1240{
1241 PropertyRNA *prop;
1242 static const EnumPropertyItem prop_shape_items[] = {
1243 {CURVE_PRESET_SHARP, "SHARP", 0, "Sharp", ""},
1244 {CURVE_PRESET_SMOOTH, "SMOOTH", 0, "Smooth", ""},
1245 {CURVE_PRESET_MAX, "MAX", 0, "Max", ""},
1246 {CURVE_PRESET_LINE, "LINE", 0, "Line", ""},
1247 {CURVE_PRESET_ROUND, "ROUND", 0, "Round", ""},
1248 {CURVE_PRESET_ROOT, "ROOT", 0, "Root", ""},
1249 {0, nullptr, 0, nullptr, nullptr},
1250 };
1251
1252 ot->name = "Shutter Curve Preset";
1253 ot->description = "Set shutter curve";
1254 ot->idname = "RENDER_OT_shutter_curve_preset";
1255
1257
1258 prop = RNA_def_enum(ot->srna, "shape", prop_shape_items, CURVE_PRESET_SMOOTH, "Mode", "");
1260 BLT_I18NCONTEXT_ID_CURVE_LEGACY); /* Abusing id_curve :/ */
1261}
int ED_draw_imbuf_method(const ImBuf *ibuf)
Definition glutil.cc:604
void BKE_color_managed_display_settings_copy(ColorManagedDisplaySettings *new_settings, const ColorManagedDisplaySettings *settings)
void BKE_color_managed_view_settings_free(ColorManagedViewSettings *settings)
void BKE_color_managed_view_settings_copy(ColorManagedViewSettings *new_settings, const ColorManagedViewSettings *settings)
void BKE_curvemap_reset(CurveMap *cuma, const rctf *clipr, int preset, int slope)
void BKE_curvemapping_changed(CurveMapping *cumap, bool rem_doubles)
@ CURVEMAP_SLOPE_POS_NEG
bScreen * CTX_wm_screen(const bContext *C)
wmWindow * CTX_wm_window(const bContext *C)
Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
View3D * CTX_wm_view3d(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
@ G_DEBUG
#define G_MAIN
ImBuf * BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **r_lock)
Image * BKE_image_ensure_viewer(Main *bmain, int type, const char *name)
void BKE_image_release_ibuf(Image *ima, ImBuf *ibuf, void *lock)
void BKE_image_update_gputexture_delayed(Image *ima, ImageTile *image_tile, ImBuf *ibuf, int x, int y, int w, int h)
Definition image_gpu.cc:904
void BKE_image_backup_render(Scene *scene, Image *ima, bool free_current_slot)
#define IMA_SIGNAL_FREE
Definition BKE_image.hh:162
void BKE_image_signal(Main *bmain, Image *ima, ImageUser *iuser, int signal)
void BKE_image_partial_update_mark_full_update(Image *image)
Mark the whole image to be updated.
bool BKE_imtype_is_movie(char imtype)
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
ListBase * BKE_view_layer_object_bases_get(ViewLayer *view_layer)
void BKE_main_id_tag_listbase(ListBase *lb, int tag, bool value)
Definition lib_id.cc:1191
void BKE_main_free(Main *bmain)
Definition main.cc:175
void BKE_ntree_update(Main &bmain, std::optional< blender::Span< bNodeTree * > > modified_trees=std::nullopt, const NodeTreeUpdateExtraParams &params={})
void BKE_ntree_update_tag_id_changed(Main *bmain, ID *id)
General operations, lookup, etc. for blender objects.
void BKE_object_free_derived_caches(Object *ob)
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:126
#define SETLOOPER_SET_ONLY(_sce_basis, _sce_iter, _base)
Definition BKE_scene.hh:49
bool BKE_scene_camera_switch_update(Scene *scene)
Definition scene.cc:2267
int BKE_scene_multiview_view_id_get(const RenderData *rd, const char *viewname)
Definition scene.cc:3094
Depsgraph * BKE_scene_get_depsgraph(const Scene *scene, const ViewLayer *view_layer)
Definition scene.cc:3414
void BKE_spacedata_draw_locks(ARegionDrawLockFlags lock_flags)
Definition screen.cc:417
@ REGION_DRAW_LOCK_NONE
@ REGION_DRAW_LOCK_RENDER
#define BLI_assert(a)
Definition BLI_assert.h:46
int BLI_findindex(const ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:586
#define LISTBASE_FOREACH(type, var, list)
void * BLI_findstring(const ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:608
int BLI_findstringindex(const ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:780
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition BLI_rect.h:198
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition BLI_rect.h:194
#define SNPRINTF(dst, format,...)
Definition BLI_string.h:599
size_t BLI_string_join_array(char *result, size_t result_maxncpy, const char *strings[], uint strings_num) ATTR_NONNULL()
void size_t BLI_string_len_array(const char *strings[], uint strings_num) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Platform independent time functions.
double BLI_time_now_seconds(void)
Definition time.cc:65
size_t BLI_timecode_string_from_time_simple(char *str, size_t maxncpy, double time_seconds) ATTR_NONNULL()
Definition timecode.cc:170
#define RPT_(msgid)
#define BLT_I18NCONTEXT_ID_CURVE_LEGACY
void DEG_tag_on_visible_update(Main *bmain, bool do_time)
@ ID_TAG_DOIT
Definition DNA_ID.h:944
@ CUMA_EXTEND_EXTRAPOLATE
@ CURVE_PRESET_ROOT
@ CURVE_PRESET_SMOOTH
@ CURVE_PRESET_ROUND
@ CURVE_PRESET_LINE
@ CURVE_PRESET_SHARP
@ CURVE_PRESET_MAX
@ IMA_TYPE_R_RESULT
@ BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT
Object is a sort of wrapper for general info.
#define RE_PASSNAME_COMBINED
#define V3D_CAMERA_LOCAL(v3d)
@ R_SINGLE_LAYER
@ R_DOSEQ
@ R_NO_FRAME_UPDATE
@ SPACE_IMAGE
@ IMAGE_DRAW_METHOD_GLSL
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
@ OPERATOR_PASS_THROUGH
wmOperatorStatus ED_screen_animation_play(bContext *C, int sync, int mode)
bool ED_operator_screenactive(bContext *C)
bScreen * ED_screen_animation_playing(const wmWindowManager *wm)
void ED_update_for_newframe(Main *bmain, Depsgraph *depsgraph)
bool ED_editors_flush_edits_ex(Main *bmain, bool for_render, bool check_needs_flush)
Definition ed_util.cc:308
void IMB_partial_display_buffer_update(ImBuf *ibuf, const float *linear_buffer, const unsigned char *byte_buffer, int stride, int offset_x, int offset_y, const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings, int xmin, int ymin, int xmax, int ymax)
@ IB_DISPLAY_BUFFER_INVALID
Read Guarded memory(de)allocation.
#define RE_MAXNAME
Definition RE_pipeline.h:34
@ PROP_SKIP_SAVE
Definition RNA_types.hh:330
#define C
Definition RandGen.cpp:29
@ WM_JOB_TYPE_RENDER
Definition WM_api.hh:1728
@ WM_JOB_EXCL_RENDER
Definition WM_api.hh:1715
@ WM_JOB_PROGRESS
Definition WM_api.hh:1716
@ WM_JOB_PRIORITY
Definition WM_api.hh:1710
#define NC_NODE
Definition WM_types.hh:391
#define ND_RENDER_RESULT
Definition WM_types.hh:443
#define NC_SCENE
Definition WM_types.hh:375
#define NA_EDITED
Definition WM_types.hh:581
float progress
Definition WM_types.hh:1019
volatile int lock
BPy_StructRNA * depsgraph
#define offsetof(t, d)
#define printf(...)
#define IMA_MAX_RENDER_TEXT_SIZE
#define MAX_ID_NAME
RenderEngineType * RE_engines_find(const char *idname)
size_t(* MEM_get_peak_memory)(void)
Definition mallocn.cc:73
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:123
size_t(* MEM_get_memory_in_use)(void)
Definition mallocn.cc:70
static size_t mem_in_use
#define G(x, y, z)
static void error(const char *str)
void cache_cleanup(Scene *scene)
bool relations_check_scene_recursion(Scene *scene, ReportList *reports)
void ntreeCompositClearTags(bNodeTree *ntree)
static const EnumPropertyItem prop_shape_items[]
return ret
ScrArea * render_view_open(bContext *C, int mx, int my, ReportList *reports)
static void render_endjob(void *rjv)
static void render_image_restore_layer(RenderJob *rj)
static void current_scene_update(void *rjv, Scene *scene)
static void image_rect_update(void *rjv, RenderResult *rr, rcti *renrect)
static void image_renderinfo_cb(void *rjv, RenderStats *rs)
void RENDER_OT_render(wmOperatorType *ot)
static void image_buffer_rect_update(RenderJob *rj, RenderResult *rr, ImBuf *ibuf, ImageUser *iuser, const rcti *tile_rect, int offset_x, int offset_y, const char *viewname)
static void make_renderinfo_string(const RenderStats *rs, const Scene *scene, const bool v3d_override, const char *error, char ret[IMA_MAX_RENDER_TEXT_SIZE])
Scene * ED_render_job_get_scene(const bContext *C)
static void screen_render_single_layer_set(wmOperator *op, Main *mainp, ViewLayer *active_layer, Scene **scene, ViewLayer **single_layer)
static void render_drawlock(void *rjv, bool lock)
static wmOperatorStatus screen_render_modal(bContext *C, wmOperator *op, const wmEvent *event)
void RENDER_OT_shutter_curve_preset(wmOperatorType *ot)
static bool render_break(void *rjv)
static wmOperatorStatus render_shutter_curve_preset_exec(bContext *C, wmOperator *op)
static void clean_viewport_memory(Main *bmain, Scene *scene)
Scene * ED_render_job_get_current_scene(const bContext *C)
static bool render_breakjob(void *rjv)
static void render_image_update_pass_and_layer(RenderJob *rj, RenderResult *rr, ImageUser *iuser)
static void render_progress_update(void *rjv, float progress)
static void clean_viewport_memory_base(Base *base)
static void screen_render_cancel(bContext *C, wmOperator *op)
static wmOperatorStatus screen_render_exec(bContext *C, wmOperator *op)
static wmOperatorStatus screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static void render_freejob(void *rjv)
static bool image_buffer_calc_tile_rect(const RenderResult *rr, const ImBuf *ibuf, rcti *renrect, rcti *r_ibuf_rect, int *r_offset_x, int *r_offset_y)
static void render_startjob(void *rjv, wmJobWorkerStatus *worker_status)
bool RE_HasCombinedLayer(const RenderResult *result)
RenderView * RE_RenderViewGetById(RenderResult *rr, const int view_id)
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, const int maxlen, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_translation_context(PropertyRNA *prop, const char *context)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
bool RE_HasSingleLayer(Render *re)
void RE_stats_draw_cb(Render *re, void *handle, void(*f)(void *handle, RenderStats *rs))
void RE_progress_cb(Render *re, void *handle, void(*f)(void *handle, float))
void RE_test_break_cb(Render *re, void *handle, bool(*f)(void *handle))
void RE_current_scene_update_cb(Render *re, void *handle, void(*f)(void *handle, Scene *scene))
void RE_InitRenderCB(Render *re)
void RE_RenderFrame(Render *re, Main *bmain, Scene *scene, ViewLayer *single_layer, Object *camera_override, const int frame, const float subframe, const bool write_still)
Render * RE_NewSceneRender(const Scene *scene)
bool RE_seq_render_active(Scene *scene, RenderData *rd)
RenderResult * RE_AcquireResultRead(Render *re)
void RE_ReleaseResult(Render *re)
const char * RE_GetActiveRenderView(Render *re)
void RE_RenderAnim(Render *re, Main *bmain, Scene *scene, ViewLayer *single_layer, Object *camera_override, int sfra, int efra, int tfra)
void RE_system_gpu_context_ensure(Render *re)
bool RE_allow_render_generic_object(Object *ob)
void RE_display_update_cb(Render *re, void *handle, void(*f)(void *handle, RenderResult *rr, rcti *rect))
bool RE_is_rendering_allowed(Scene *scene, ViewLayer *single_layer, Object *camera_override, ReportList *reports)
void RE_draw_lock_cb(Render *re, void *handle, void(*f)(void *handle, bool lock))
void RE_SetReports(Render *re, ReportList *reports)
float * RE_RenderLayerGetPass(RenderLayer *rl, const char *name, const char *viewname)
short flag
struct Object * object
CurveMap cm[4]
Definition DNA_ID.h:404
int tag
Definition DNA_ID.h:424
ImBufFloatBuffer float_buffer
ImBufByteBuffer byte_buffer
struct Scene * scene
short last_render_slot
short render_slot
void * last
void * first
ListBase scenes
Definition BKE_main.hh:245
ListBase wm
Definition BKE_main.hh:276
ListBase objects
Definition BKE_main.hh:247
struct CurveMapping mblur_shutter_curve
char engine[32]
struct ImageFormatData im_format
char use_lock_interface
void(* render)(struct RenderEngine *engine, struct Depsgraph *depsgraph)
Definition RE_engine.h:80
Scene * current_scene
ImageUser iuser
ViewLayer * single_layer
ColorManagedViewSettings view_settings
ReportList * reports
ScrArea * area
bool interface_locked
ViewLayer * view_layer
ColorManagedDisplaySettings display_settings
Object * camera_override
float * progress
char name[RE_MAXNAME]
Definition RE_pipeline.h:81
ListBase layers
RenderLayer * renlay
const char * statstr
double starttime
double lastframetime
const char * infostr
struct ImBuf * ibuf
Definition RE_pipeline.h:44
struct bNodeTree * nodetree
ColorManagedViewSettings view_settings
struct RenderData r
ListBase view_layers
struct Object * camera
ColorManagedDisplaySettings display_settings
ListBase spacedata
struct ImageUser iuser
struct Image * image
ListBase areabase
int ymin
int ymax
int xmin
int xmax
wmEventType type
Definition WM_types.hh:754
int xy[2]
Definition WM_types.hh:758
struct ReportList * reports
struct PointerRNA * ptr
struct wmWindow * next
void * BKE_image_free_buffers
Definition stubs.c:35
void * BKE_image_get_tile
Definition stubs.c:36
i
Definition text_draw.cc:230
void WM_cursor_wait(bool val)
void WM_main_add_notifier(uint type, void *reference)
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
void WM_set_locked_interface_with_flags(wmWindowManager *wm, short lock_flags)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
void WM_set_locked_interface(wmWindowManager *wm, bool lock)
@ EVT_ESCKEY
wmOperatorType * ot
Definition wm_files.cc:4226
void WM_jobs_timer(wmJob *wm_job, double time_step, uint note, uint endnote)
Definition wm_jobs.cc:353
void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job)
Definition wm_jobs.cc:456
void WM_jobs_kill_type(wmWindowManager *wm, const void *owner, int job_type)
Definition wm_jobs.cc:598
void WM_jobs_delay_start(wmJob *wm_job, double delay_time)
Definition wm_jobs.cc:360
wmJob * WM_jobs_get(wmWindowManager *wm, wmWindow *win, const void *owner, const char *name, const eWM_JobFlag flag, const eWM_JobType job_type)
Definition wm_jobs.cc:190
void WM_jobs_callbacks(wmJob *wm_job, wm_jobs_start_callback startjob, void(*initjob)(void *), void(*update)(void *), void(*endjob)(void *))
Definition wm_jobs.cc:365
void WM_jobs_kill_all_except(wmWindowManager *wm, const void *owner)
Definition wm_jobs.cc:589
bool WM_jobs_test(const wmWindowManager *wm, const void *owner, int job_type)
Definition wm_jobs.cc:224
void WM_jobs_customdata_set(wmJob *wm_job, void *customdata, void(*free)(void *customdata))
Definition wm_jobs.cc:337
void * WM_jobs_customdata_from_type(wmWindowManager *wm, const void *owner, int job_type)
Definition wm_jobs.cc:307
ViewLayer * WM_window_get_active_view_layer(const wmWindow *win)
bScreen * WM_window_get_active_screen(const wmWindow *win)