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