Blender  V3.3
engine.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2006 Blender Foundation. All rights reserved. */
3 
8 #include <stddef.h>
9 #include <stdlib.h>
10 #include <string.h>
11 
12 #include "MEM_guardedalloc.h"
13 
14 #include "BLT_translation.h"
15 
16 #include "BLI_ghash.h"
17 #include "BLI_listbase.h"
18 #include "BLI_math_bits.h"
19 #include "BLI_rect.h"
20 #include "BLI_string.h"
21 #include "BLI_utildefines.h"
22 
23 #include "DNA_object_types.h"
24 
25 #include "BKE_camera.h"
26 #include "BKE_colortools.h"
27 #include "BKE_global.h"
28 #include "BKE_layer.h"
29 #include "BKE_node.h"
30 #include "BKE_report.h"
31 #include "BKE_scene.h"
32 
33 #include "DEG_depsgraph.h"
34 #include "DEG_depsgraph_debug.h"
35 #include "DEG_depsgraph_query.h"
36 
37 #include "RNA_access.h"
38 
39 #ifdef WITH_PYTHON
40 # include "BPY_extern.h"
41 #endif
42 
43 #include "RE_bake.h"
44 #include "RE_engine.h"
45 #include "RE_pipeline.h"
46 
47 #include "DRW_engine.h"
48 
49 #include "GPU_context.h"
50 
51 #include "pipeline.h"
52 #include "render_result.h"
53 #include "render_types.h"
54 
55 /* Render Engine Types */
56 
58 
59 void RE_engines_init(void)
60 {
62 }
63 
65 {
67 }
68 
69 void RE_engines_exit(void)
70 {
72 
74 
75  for (type = R_engines.first; type; type = next) {
76  next = type->next;
77 
79 
80  if (!(type->flag & RE_INTERNAL)) {
81  if (type->rna_ext.free) {
82  type->rna_ext.free(type->rna_ext.data);
83  }
84 
85  MEM_freeN(type);
86  }
87  }
88 }
89 
91 {
92  if (render_type->draw_engine) {
93  DRW_engine_register(render_type->draw_engine);
94  }
95  BLI_addtail(&R_engines, render_type);
96 }
97 
98 RenderEngineType *RE_engines_find(const char *idname)
99 {
101 
102  type = BLI_findstring(&R_engines, idname, offsetof(RenderEngineType, idname));
103  if (!type) {
104  type = BLI_findstring(&R_engines, "BLENDER_EEVEE", offsetof(RenderEngineType, idname));
105  }
106 
107  return type;
108 }
109 
111 {
112  return (re->engine && re->engine->type && re->engine->type->render);
113 }
114 
116 {
117  /* TODO: refine? Can we have ogl render engine without ogl render pipeline? */
118  return (render_type->draw_engine != NULL) && DRW_engine_render_support(render_type->draw_engine);
119 }
120 
122 {
123  if ((render_type->flag & RE_USE_ALEMBIC_PROCEDURAL) == 0) {
124  return false;
125  }
126 
128  return false;
129  }
130 
131  return true;
132 }
133 
134 /* Create, Free */
135 
137 {
138  RenderEngine *engine = MEM_callocN(sizeof(RenderEngine), "RenderEngine");
139  engine->type = type;
140 
142 
143  return engine;
144 }
145 
147 {
148  if (engine->depsgraph) {
149  /* Need GPU context since this might free GPU buffers. */
150  const bool use_gpu_context = (engine->type->flag & RE_USE_GPU_CONTEXT);
151  if (use_gpu_context) {
152  DRW_render_context_enable(engine->re);
153  }
154 
155  DEG_graph_free(engine->depsgraph);
156  engine->depsgraph = NULL;
157 
158  if (use_gpu_context) {
160  }
161  }
162 }
163 
165 {
166 #ifdef WITH_PYTHON
167  if (engine->py_instance) {
169  }
170 #endif
171 
172  engine_depsgraph_free(engine);
173 
175 
176  MEM_freeN(engine);
177 }
178 
179 /* Bake Render Results */
180 
182  RenderEngine *engine, int x, int y, int w, int h, const char *layername)
183 {
184  BakeImage *image = &engine->bake.targets->images[engine->bake.image_id];
185  const BakePixel *pixels = engine->bake.pixels + image->offset;
186  const size_t channels_num = engine->bake.targets->channels_num;
187 
188  /* Remember layer name for to match images in render_frame_finish. */
189  if (image->render_layer_name[0] == '\0') {
190  STRNCPY(image->render_layer_name, layername);
191  }
192 
193  /* Create render result with specified size. */
194  RenderResult *rr = MEM_callocN(sizeof(RenderResult), __func__);
195 
196  rr->rectx = w;
197  rr->recty = h;
198  rr->tilerect.xmin = x;
199  rr->tilerect.ymin = y;
200  rr->tilerect.xmax = x + w;
201  rr->tilerect.ymax = y + h;
202 
203  /* Add single baking render layer. */
204  RenderLayer *rl = MEM_callocN(sizeof(RenderLayer), "bake render layer");
205  STRNCPY(rl->name, layername);
206  rl->rectx = w;
207  rl->recty = h;
208  BLI_addtail(&rr->layers, rl);
209 
210  /* Add render passes. */
211  render_layer_add_pass(rr, rl, channels_num, RE_PASSNAME_COMBINED, "", "RGBA", true);
212 
213  RenderPass *primitive_pass = render_layer_add_pass(rr, rl, 4, "BakePrimitive", "", "RGBA", true);
214  RenderPass *differential_pass = render_layer_add_pass(
215  rr, rl, 4, "BakeDifferential", "", "RGBA", true);
216 
217  /* Fill render passes from bake pixel array, to be read by the render engine. */
218  for (int ty = 0; ty < h; ty++) {
219  size_t offset = ty * w * 4;
220  float *primitive = primitive_pass->rect + offset;
221  float *differential = differential_pass->rect + offset;
222 
223  size_t bake_offset = (y + ty) * image->width + x;
224  const BakePixel *bake_pixel = pixels + bake_offset;
225 
226  for (int tx = 0; tx < w; tx++) {
227  if (bake_pixel->object_id != engine->bake.object_id) {
228  primitive[0] = int_as_float(-1);
229  primitive[1] = int_as_float(-1);
230  }
231  else {
232  primitive[0] = int_as_float(bake_pixel->seed);
233  primitive[1] = int_as_float(bake_pixel->primitive_id);
234  primitive[2] = bake_pixel->uv[0];
235  primitive[3] = bake_pixel->uv[1];
236 
237  differential[0] = bake_pixel->du_dx;
238  differential[1] = bake_pixel->du_dy;
239  differential[2] = bake_pixel->dv_dx;
240  differential[3] = bake_pixel->dv_dy;
241  }
242 
243  primitive += 4;
244  differential += 4;
245  bake_pixel++;
246  }
247  }
248 
249  return rr;
250 }
251 
253 {
254  RenderLayer *rl = rr->layers.first;
256  if (!rpass) {
257  return;
258  }
259 
260  /* Find bake image corresponding to layer. */
261  int image_id = 0;
262  for (; image_id < engine->bake.targets->images_num; image_id++) {
263  if (STREQ(engine->bake.targets->images[image_id].render_layer_name, rl->name)) {
264  break;
265  }
266  }
267  if (image_id == engine->bake.targets->images_num) {
268  return;
269  }
270 
271  const BakeImage *image = &engine->bake.targets->images[image_id];
272  const BakePixel *pixels = engine->bake.pixels + image->offset;
273  const size_t channels_num = engine->bake.targets->channels_num;
274  const size_t channels_size = channels_num * sizeof(float);
275  float *result = engine->bake.result + image->offset * channels_num;
276 
277  /* Copy from tile render result to full image bake result. Just the pixels for the
278  * object currently being baked, to preserve other objects when baking multiple. */
279  const int x = rr->tilerect.xmin;
280  const int y = rr->tilerect.ymin;
281  const int w = rr->tilerect.xmax - rr->tilerect.xmin;
282  const int h = rr->tilerect.ymax - rr->tilerect.ymin;
283 
284  for (int ty = 0; ty < h; ty++) {
285  const size_t offset = ty * w;
286  const size_t bake_offset = (y + ty) * image->width + x;
287 
288  const float *pass_rect = rpass->rect + offset * channels_num;
289  const BakePixel *bake_pixel = pixels + bake_offset;
290  float *bake_result = result + bake_offset * channels_num;
291 
292  for (int tx = 0; tx < w; tx++) {
293  if (bake_pixel->object_id == engine->bake.object_id) {
294  memcpy(bake_result, pass_rect, channels_size);
295  }
296  pass_rect += channels_num;
297  bake_result += channels_num;
298  bake_pixel++;
299  }
300  }
301 }
302 
303 /* Render Results */
304 
306 {
308  tile.rect = result->tilerect;
309 
310  return tile;
311 }
312 
314  const HighlightedTile *tile,
315  bool highlight)
316 {
317  if ((engine->flag & RE_ENGINE_HIGHLIGHT_TILES) == 0) {
318  return;
319  }
320 
321  Render *re = engine->re;
322 
324 
325  if (re->highlighted_tiles == NULL) {
328  }
329 
330  if (highlight) {
331  HighlightedTile **tile_in_set;
332  if (!BLI_gset_ensure_p_ex(re->highlighted_tiles, tile, (void ***)&tile_in_set)) {
333  *tile_in_set = MEM_mallocN(sizeof(HighlightedTile), __func__);
334  **tile_in_set = *tile;
335  }
336  }
337  else {
339  }
340 
342 }
343 
345  RenderEngine *engine, int x, int y, int w, int h, const char *layername, const char *viewname)
346 {
347  if (engine->bake.targets) {
348  RenderResult *result = render_result_from_bake(engine, x, y, w, h, layername);
349  BLI_addtail(&engine->fullresult, result);
350  return result;
351  }
352 
353  Render *re = engine->re;
355  rcti disprect;
356 
357  /* ensure the coordinates are within the right limits */
358  CLAMP(x, 0, re->result->rectx);
359  CLAMP(y, 0, re->result->recty);
360  CLAMP(w, 0, re->result->rectx);
361  CLAMP(h, 0, re->result->recty);
362 
363  if (x + w > re->result->rectx) {
364  w = re->result->rectx - x;
365  }
366  if (y + h > re->result->recty) {
367  h = re->result->recty - y;
368  }
369 
370  /* allocate a render result */
371  disprect.xmin = x;
372  disprect.xmax = x + w;
373  disprect.ymin = y;
374  disprect.ymax = y + h;
375 
376  result = render_result_new(re, &disprect, layername, viewname);
377 
378  /* TODO: make this thread safe. */
379 
380  /* can be NULL if we CLAMP the width or height to 0 */
381  if (result) {
382  render_result_clone_passes(re, result, viewname);
384 
385  BLI_addtail(&engine->fullresult, result);
386 
387  result->tilerect.xmin += re->disprect.xmin;
388  result->tilerect.xmax += re->disprect.xmin;
389  result->tilerect.ymin += re->disprect.ymin;
390  result->tilerect.ymax += re->disprect.ymin;
391  }
392 
393  return result;
394 }
395 
397 {
398  if (!re->result->passes_allocated) {
400  if (!re->result->passes_allocated) {
402  }
404  }
405 }
406 
408 {
409  if (engine->bake.targets) {
410  /* No interactive baking updates for now. */
411  return;
412  }
413 
414  Render *re = engine->re;
415 
416  if (result) {
419  result->renlay = result->layers.first; /* weak, draws first layer always */
420  re->display_update(re->duh, result, NULL);
421  }
422 }
423 
425  const char *name,
426  int channels,
427  const char *chan_id,
428  const char *layername)
429 {
430  Render *re = engine->re;
431 
432  if (!re || !re->result) {
433  return;
434  }
435 
436  RE_create_render_pass(re->result, name, channels, chan_id, layername, NULL, false);
437 }
438 
440  RenderEngine *engine, RenderResult *result, bool cancel, bool highlight, bool merge_results)
441 {
442  Render *re = engine->re;
443 
444  if (!result) {
445  return;
446  }
447 
448  if (engine->bake.targets) {
449  if (!cancel || merge_results) {
450  render_result_to_bake(engine, result);
451  }
452  BLI_remlink(&engine->fullresult, result);
454  return;
455  }
456 
457  if (re->engine && (re->engine->flag & RE_ENGINE_HIGHLIGHT_TILES)) {
459 
460  engine_tile_highlight_set(engine, &tile, highlight);
461  }
462 
463  if (!cancel || merge_results) {
464  if (!(re->test_break(re->tbh) && (re->r.scemode & R_BUTS_PREVIEW))) {
467  }
468 
469  /* draw */
470  if (!re->test_break(re->tbh)) {
471  result->renlay = result->layers.first; /* weak, draws first layer always */
472  re->display_update(re->duh, result, NULL);
473  }
474  }
475 
476  /* free */
477  BLI_remlink(&engine->fullresult, result);
479 }
480 
482 {
483  return engine->re->result;
484 }
485 
486 /* Cancel */
487 
489 {
490  Render *re = engine->re;
491 
492  if (re) {
493  return re->test_break(re->tbh);
494  }
495 
496  return 0;
497 }
498 
499 /* Statistics */
500 
501 void RE_engine_update_stats(RenderEngine *engine, const char *stats, const char *info)
502 {
503  Render *re = engine->re;
504 
505  /* stats draw callback */
506  if (re) {
507  re->i.statstr = stats;
508  re->i.infostr = info;
509  re->stats_draw(re->sdh, &re->i);
510  re->i.infostr = NULL;
511  re->i.statstr = NULL;
512  }
513 
514  /* set engine text */
515  engine->text[0] = '\0';
516 
517  if (stats && stats[0] && info && info[0]) {
518  BLI_snprintf(engine->text, sizeof(engine->text), "%s | %s", stats, info);
519  }
520  else if (info && info[0]) {
521  BLI_strncpy(engine->text, info, sizeof(engine->text));
522  }
523  else if (stats && stats[0]) {
524  BLI_strncpy(engine->text, stats, sizeof(engine->text));
525  }
526 }
527 
528 void RE_engine_update_progress(RenderEngine *engine, float progress)
529 {
530  Render *re = engine->re;
531 
532  if (re) {
533  CLAMP(progress, 0.0f, 1.0f);
534  re->progress(re->prh, progress);
535  }
536 }
537 
538 void RE_engine_update_memory_stats(RenderEngine *engine, float mem_used, float mem_peak)
539 {
540  Render *re = engine->re;
541 
542  if (re) {
543  re->i.mem_used = mem_used;
544  re->i.mem_peak = mem_peak;
545  }
546 }
547 
548 void RE_engine_report(RenderEngine *engine, int type, const char *msg)
549 {
550  Render *re = engine->re;
551 
552  if (re) {
553  BKE_report(engine->re->reports, type, msg);
554  }
555  else if (engine->reports) {
556  BKE_report(engine->reports, type, msg);
557  }
558 }
559 
560 void RE_engine_set_error_message(RenderEngine *engine, const char *msg)
561 {
562  Render *re = engine->re;
563  if (re != NULL) {
565  if (rr) {
566  if (rr->error != NULL) {
567  MEM_freeN(rr->error);
568  }
569  rr->error = BLI_strdup(msg);
570  }
571  RE_ReleaseResult(re);
572  }
573 }
574 
575 RenderPass *RE_engine_pass_by_index_get(RenderEngine *engine, const char *layer_name, int index)
576 {
577  Render *re = engine->re;
578  if (re == NULL) {
579  return NULL;
580  }
581 
582  RenderPass *pass = NULL;
583 
585  if (rr != NULL) {
586  const RenderLayer *layer = RE_GetRenderLayer(rr, layer_name);
587  if (layer != NULL) {
588  pass = BLI_findlink(&layer->passes, index);
589  }
590  }
591  RE_ReleaseResult(re);
592 
593  return pass;
594 }
595 
597 {
598  Render *re = engine->re;
599  return RE_GetActiveRenderView(re);
600 }
601 
602 void RE_engine_active_view_set(RenderEngine *engine, const char *viewname)
603 {
604  Render *re = engine->re;
605  RE_SetActiveRenderView(re, viewname);
606 }
607 
608 float RE_engine_get_camera_shift_x(RenderEngine *engine, Object *camera, bool use_spherical_stereo)
609 {
610  /* When using spherical stereo, get camera shift without multiview,
611  * leaving stereo to be handled by the engine. */
612  Render *re = engine->re;
613  if (use_spherical_stereo || re == NULL) {
615  }
616 
617  return BKE_camera_multiview_shift_x(&re->r, camera, re->viewname);
618 }
619 
621  Object *camera,
622  bool use_spherical_stereo,
623  float r_modelmat[16])
624 {
625  /* When using spherical stereo, get model matrix without multiview,
626  * leaving stereo to be handled by the engine. */
627  Render *re = engine->re;
628  if (use_spherical_stereo || re == NULL) {
629  BKE_camera_multiview_model_matrix(NULL, camera, NULL, (float(*)[4])r_modelmat);
630  }
631  else {
632  BKE_camera_multiview_model_matrix(&re->r, camera, re->viewname, (float(*)[4])r_modelmat);
633  }
634 }
635 
637 {
638  Render *re = engine->re;
639  return BKE_camera_multiview_spherical_stereo(re ? &re->r : NULL, camera) ? 1 : 0;
640 }
641 
642 rcti *RE_engine_get_current_tiles(Render *re, int *r_total_tiles, bool *r_needs_free)
643 {
644  static rcti tiles_static[BLENDER_MAX_THREADS];
645  const int allocation_step = BLENDER_MAX_THREADS;
646  int total_tiles = 0;
647  rcti *tiles = tiles_static;
648  int allocation_size = BLENDER_MAX_THREADS;
649 
651 
652  *r_needs_free = false;
653 
654  if (re->highlighted_tiles == NULL) {
655  *r_total_tiles = 0;
657  return NULL;
658  }
659 
661  if (total_tiles >= allocation_size) {
662  /* Just in case we're using crazy network rendering with more
663  * workers than BLENDER_MAX_THREADS.
664  */
665  allocation_size += allocation_step;
666  if (tiles == tiles_static) {
667  /* Can not realloc yet, tiles are pointing to a
668  * stack memory.
669  */
670  tiles = MEM_mallocN(allocation_size * sizeof(rcti), "current engine tiles");
671  }
672  else {
673  tiles = MEM_reallocN(tiles, allocation_size * sizeof(rcti));
674  }
675  *r_needs_free = true;
676  }
677  tiles[total_tiles] = tile->rect;
678 
679  total_tiles++;
680  }
682 
684 
685  *r_total_tiles = total_tiles;
686 
687  return tiles;
688 }
689 
691 {
692  return &re->r;
693 }
694 
696 {
697  /* Re-rendering is not supported with GPU contexts, since the GPU context
698  * is destroyed when the render thread exists. */
699  return (engine->re->r.mode & R_PERSISTENT_DATA) && !(engine->type->flag & RE_USE_GPU_CONTEXT);
700 }
701 
703 {
704  /* For persistent data or GPU engines like Eevee, reuse the depsgraph between
705  * view layers and animation frames. For renderers like Cycles that create
706  * their own copy of the scene, persistent data must be explicitly enabled to
707  * keep memory usage low by default. */
708  return (engine->re->r.mode & R_PERSISTENT_DATA) || (engine->type->flag & RE_USE_GPU_CONTEXT);
709 }
710 
711 /* Depsgraph */
712 static void engine_depsgraph_init(RenderEngine *engine, ViewLayer *view_layer)
713 {
714  Main *bmain = engine->re->main;
715  Scene *scene = engine->re->scene;
716  bool reuse_depsgraph = false;
717 
718  /* Reuse depsgraph from persistent data if possible. */
719  if (engine->depsgraph) {
720  if (DEG_get_bmain(engine->depsgraph) != bmain ||
721  DEG_get_input_scene(engine->depsgraph) != scene) {
722  /* If bmain or scene changes, we need a completely new graph. */
723  engine_depsgraph_free(engine);
724  }
725  else if (DEG_get_input_view_layer(engine->depsgraph) != view_layer) {
726  /* If only view layer changed, reuse depsgraph in the hope of reusing
727  * objects shared between view layers. */
728  DEG_graph_replace_owners(engine->depsgraph, bmain, scene, view_layer);
730  }
731 
732  reuse_depsgraph = true;
733  }
734 
735  if (!engine->depsgraph) {
736  /* Ensure we only use persistent data for one scene / view layer at a time,
737  * to avoid excessive memory usage. */
739 
740  /* Create new depsgraph if not cached with persistent data. */
741  engine->depsgraph = DEG_graph_new(bmain, scene, view_layer, DAG_EVAL_RENDER);
742  DEG_debug_name_set(engine->depsgraph, "RENDER");
743  }
744 
745  if (engine->re->r.scemode & R_BUTS_PREVIEW) {
746  /* Update for preview render. */
747  Depsgraph *depsgraph = engine->depsgraph;
749 
750  /* Need GPU context since this might free GPU buffers. */
751  const bool use_gpu_context = (engine->type->flag & RE_USE_GPU_CONTEXT) && reuse_depsgraph;
752  if (use_gpu_context) {
753  DRW_render_context_enable(engine->re);
754  }
755 
757 
758  if (use_gpu_context) {
760  }
761  }
762  else {
763  /* Go through update with full Python callbacks for regular render. */
765  }
766 
768 }
769 
771 {
772  if (engine->depsgraph) {
773  if (engine_keep_depsgraph(engine)) {
774  /* Clear recalc flags since the engine should have handled the updates for the currently
775  * rendered framed by now. */
776  DEG_ids_clear_recalc(engine->depsgraph, false);
777  }
778  else {
779  /* Free immediately to save memory. */
780  engine_depsgraph_free(engine);
781  }
782  }
783 }
784 
785 void RE_engine_frame_set(RenderEngine *engine, int frame, float subframe)
786 {
787  if (!engine->depsgraph) {
788  return;
789  }
790 
791  /* Clear recalc flags before update so engine can detect what changed. */
792  DEG_ids_clear_recalc(engine->depsgraph, false);
793 
794  Render *re = engine->re;
795  double cfra = (double)frame + (double)subframe;
796 
797  CLAMP(cfra, MINAFRAME, MAXFRAME);
798  BKE_scene_frame_set(re->scene, cfra);
800 
802 }
803 
804 /* Bake */
805 
807 {
808  re->scene = scene;
809  re->main = bmain;
810  render_copy_renderdata(&re->r, &scene->r);
811 }
812 
813 bool RE_bake_has_engine(const Render *re)
814 {
816  return (type->bake != NULL);
817 }
818 
821  Object *object,
822  const int object_id,
823  const BakePixel pixel_array[],
824  const BakeTargets *targets,
825  const eScenePassType pass_type,
826  const int pass_filter,
827  float result[])
828 {
830  RenderEngine *engine;
831 
832  /* set render info */
833  re->i.cfra = re->scene->r.cfra;
834  BLI_strncpy(re->i.scene_name, re->scene->id.name + 2, sizeof(re->i.scene_name) - 2);
835 
836  /* render */
837  engine = re->engine;
838 
839  if (!engine) {
840  engine = RE_engine_create(type);
841  re->engine = engine;
842  }
843 
844  engine->flag |= RE_ENGINE_RENDERING;
845 
846  /* TODO: actually link to a parent which shouldn't happen */
847  engine->re = re;
848 
849  engine->resolution_x = re->winx;
850  engine->resolution_y = re->winy;
851 
852  if (type->bake) {
853  engine->depsgraph = depsgraph;
854 
855  /* update is only called so we create the engine.session */
856  if (type->update) {
857  type->update(engine, re->main, engine->depsgraph);
858  }
859 
860  /* Bake all images. */
861  engine->bake.targets = targets;
862  engine->bake.pixels = pixel_array;
863  engine->bake.result = result;
864  engine->bake.object_id = object_id;
865 
866  for (int i = 0; i < targets->images_num; i++) {
867  const BakeImage *image = &targets->images[i];
868  engine->bake.image_id = i;
869 
870  type->bake(
871  engine, engine->depsgraph, object, pass_type, pass_filter, image->width, image->height);
872  }
873 
874  /* Optionally let render images read bake images from disk delayed. */
875  if (type->render_frame_finish) {
876  engine->bake.image_id = 0;
877  type->render_frame_finish(engine);
878  }
879 
880  memset(&engine->bake, 0, sizeof(engine->bake));
881 
882  engine->depsgraph = NULL;
883  }
884 
885  engine->flag &= ~RE_ENGINE_RENDERING;
886 
887  engine_depsgraph_free(engine);
888 
889  RE_engine_free(engine);
890  re->engine = NULL;
891 
893  G.is_break = true;
894  }
895 
896  return true;
897 }
898 
899 /* Render */
900 
902  RenderEngine *engine,
903  ViewLayer *view_layer_iter,
904  const bool use_engine,
905  const bool use_grease_pencil)
906 {
907  /* Lock UI so scene can't be edited while we read from it in this render thread. */
908  if (re->draw_lock) {
909  re->draw_lock(re->dlh, true);
910  }
911 
912  /* Create depsgraph with scene evaluated at render resolution. */
913  ViewLayer *view_layer = BLI_findstring(
914  &re->scene->view_layers, view_layer_iter->name, offsetof(ViewLayer, name));
915  engine_depsgraph_init(engine, view_layer);
916 
917  /* Sync data to engine, within draw lock so scene data can be accessed safely. */
918  if (use_engine) {
919  if (engine->has_grease_pencil && use_grease_pencil && G.background) {
920  /* Workaround for specific NVidia drivers which crash on Linux when OptiX context is
921  * initialized prior to OpenGL context. This affects driver versions 545.29.06, 550.54.14,
922  * and 550.67 running on kernel 6.8.
923  *
924  * The idea here is to initialize GPU context before giving control to the render engine in
925  * cases when we know that the GPU context will definitely be needed later on.
926  *
927  * Only do it for background renders to avoid possible extra global locking during the
928  * context initialization. For the non-background renders the GPU context is already
929  * initialized for the Blender interface and no workaround is needed.
930  *
931  * Technically it is enough to only call WM_init_gpu() here, but it expects to only be called
932  * once, and from here it is not possible to know whether GPU sub-system is initialized or
933  * not. So instead temporarily enable the render context, which will take care of the GPU
934  * context initialization.
935  *
936  * For demo file and tracking progress of possible fixes on driver side refer to #120007. */
937  DRW_render_context_enable(engine->re);
939  }
940 
941  if (engine->type->update) {
942  engine->type->update(engine, re->main, engine->depsgraph);
943  }
944  }
945 
946  if (re->draw_lock) {
947  re->draw_lock(re->dlh, false);
948  }
949 
950  /* Perform render with engine. */
951  if (use_engine) {
952  const bool use_gpu_context = (engine->type->flag & RE_USE_GPU_CONTEXT);
953  if (use_gpu_context) {
954  DRW_render_context_enable(engine->re);
955  }
956 
960 
961  engine->type->render(engine, engine->depsgraph);
962 
964  re->engine->flag &= ~RE_ENGINE_CAN_DRAW;
966 
967  if (use_gpu_context) {
969  }
970  }
971 
972  /* Optionally composite grease pencil over render result.
973  * Only do it if the passes are allocated (and the engine will not override the grease pencil
974  * when reading its result from EXR file and writing to the Blender side. */
975  if (engine->has_grease_pencil && use_grease_pencil && re->result->passes_allocated) {
976  /* NOTE: External engine might have been requested to free its
977  * dependency graph, which is only allowed if there is no grease
978  * pencil (pipeline is taking care of that). */
979  if (!RE_engine_test_break(engine) && engine->depsgraph != NULL) {
980  DRW_render_gpencil(engine, engine->depsgraph);
981  }
982  }
983 
984  /* Free dependency graph, if engine has not done it already. */
985  engine_depsgraph_exit(engine);
986 }
987 
988 bool RE_engine_render(Render *re, bool do_all)
989 {
991 
992  /* verify if we can render */
993  if (!type->render) {
994  return false;
995  }
996  if ((re->r.scemode & R_BUTS_PREVIEW) && !(type->flag & RE_USE_PREVIEW)) {
997  return false;
998  }
999  if (do_all && !(type->flag & RE_USE_POSTPROCESS)) {
1000  return false;
1001  }
1002  if (!do_all && (type->flag & RE_USE_POSTPROCESS)) {
1003  return false;
1004  }
1005 
1006  /* Lock drawing in UI during data phase. */
1007  if (re->draw_lock) {
1008  re->draw_lock(re->dlh, true);
1009  }
1010 
1011  if ((type->flag & RE_USE_GPU_CONTEXT) && !GPU_backend_supported()) {
1012  /* Clear UI drawing locks. */
1013  if (re->draw_lock) {
1014  re->draw_lock(re->dlh, false);
1015  }
1016  BKE_report(re->reports, RPT_ERROR, "Can not initialize the GPU");
1017  G.is_break = true;
1018  return true;
1019  }
1020 
1021  /* update animation here so any render layer animation is applied before
1022  * creating the render result */
1023  if ((re->r.scemode & (R_NO_FRAME_UPDATE | R_BUTS_PREVIEW)) == 0) {
1025  }
1026 
1027  /* create render result */
1029  if (re->result == NULL || !(re->r.scemode & R_BUTS_PREVIEW)) {
1030  if (re->result) {
1032  }
1033 
1035  }
1037 
1038  if (re->result == NULL) {
1039  /* Clear UI drawing locks. */
1040  if (re->draw_lock) {
1041  re->draw_lock(re->dlh, false);
1042  }
1043  /* Too small image is handled earlier, here it could only happen if
1044  * there was no sufficient memory to allocate all passes.
1045  */
1046  BKE_report(re->reports, RPT_ERROR, "Failed allocate render result, out of memory");
1047  G.is_break = true;
1048  return true;
1049  }
1050 
1051  /* set render info */
1052  re->i.cfra = re->scene->r.cfra;
1053  BLI_strncpy(re->i.scene_name, re->scene->id.name + 2, sizeof(re->i.scene_name));
1054 
1055  /* render */
1056  RenderEngine *engine = re->engine;
1057 
1058  if (!engine) {
1059  engine = RE_engine_create(type);
1060  re->engine = engine;
1061  }
1062 
1063  engine->flag |= RE_ENGINE_RENDERING;
1064 
1065  /* TODO: actually link to a parent which shouldn't happen */
1066  engine->re = re;
1067 
1068  if (re->flag & R_ANIMATION) {
1069  engine->flag |= RE_ENGINE_ANIMATION;
1070  }
1071  if (re->r.scemode & R_BUTS_PREVIEW) {
1072  engine->flag |= RE_ENGINE_PREVIEW;
1073  }
1074  engine->camera_override = re->camera_override;
1075 
1076  engine->resolution_x = re->winx;
1077  engine->resolution_y = re->winy;
1078 
1079  /* Clear UI drawing locks. */
1080  if (re->draw_lock) {
1081  re->draw_lock(re->dlh, false);
1082  }
1083 
1084  /* Render view layers. */
1085  bool delay_grease_pencil = false;
1086 
1087  if (type->render) {
1088  FOREACH_VIEW_LAYER_TO_RENDER_BEGIN (re, view_layer_iter) {
1089  engine_render_view_layer(re, engine, view_layer_iter, true, true);
1090 
1091  /* If render passes are not allocated the render engine deferred final pixels write for
1092  * later. Need to defer the grease pencil for until after the engine has written the
1093  * render result to Blender. */
1094  delay_grease_pencil = engine->has_grease_pencil && !re->result->passes_allocated;
1095 
1096  if (RE_engine_test_break(engine)) {
1097  break;
1098  }
1099  }
1101  }
1102 
1103  if (type->render_frame_finish) {
1104  type->render_frame_finish(engine);
1105  }
1106 
1107  /* Perform delayed grease pencil rendering. */
1108  if (delay_grease_pencil) {
1109  FOREACH_VIEW_LAYER_TO_RENDER_BEGIN (re, view_layer_iter) {
1110  engine_render_view_layer(re, engine, view_layer_iter, false, true);
1111  if (RE_engine_test_break(engine)) {
1112  break;
1113  }
1114  }
1116  }
1117 
1118  /* Clear tile data */
1119  engine->flag &= ~RE_ENGINE_RENDERING;
1120 
1122 
1123  /* re->engine becomes zero if user changed active render engine during render */
1124  if (!engine_keep_depsgraph(engine) || !re->engine) {
1125  engine_depsgraph_free(engine);
1126 
1127  RE_engine_free(engine);
1128  re->engine = NULL;
1129  }
1130 
1131  if (re->r.scemode & R_EXR_CACHE_FILE) {
1135  }
1136 
1138  G.is_break = true;
1139  }
1140 
1141 #ifdef WITH_FREESTYLE
1142  if (re->r.mode & R_EDGE_FRS) {
1143  RE_RenderFreestyleExternal(re);
1144  }
1145 #endif
1146 
1147  return true;
1148 }
1149 
1151  struct Scene *scene,
1152  struct ViewLayer *view_layer,
1154  void *callback_data)
1155 {
1156  if (!(scene && view_layer && engine && callback && engine->type->update_render_passes)) {
1157  return;
1158  }
1159 
1161 
1163  engine->update_render_passes_data = callback_data;
1164  engine->type->update_render_passes(engine, scene, view_layer);
1165  engine->update_render_passes_cb = NULL;
1166  engine->update_render_passes_data = NULL;
1167 
1169 }
1170 
1172  struct Scene *scene,
1173  struct ViewLayer *view_layer,
1174  const char *name,
1175  int channels,
1176  const char *chanid,
1178 {
1179  if (!(scene && view_layer && engine && engine->update_render_passes_cb)) {
1180  return;
1181  }
1182 
1183  engine->update_render_passes_cb(
1184  engine->update_render_passes_data, scene, view_layer, name, channels, chanid, type);
1185 }
1186 
1188 {
1189  /* Weak way to save memory, but not crash grease pencil.
1190  *
1191  * TODO(sergey): Find better solution for this.
1192  */
1193  if (engine->has_grease_pencil || engine_keep_depsgraph(engine)) {
1194  return;
1195  }
1196  engine_depsgraph_free(engine);
1197 }
1198 
1200 {
1201  return re->engine;
1202 }
1203 
1205 {
1207 
1208  RenderEngine *engine = re->engine;
1209 
1210  if (engine == NULL || engine->type->draw == NULL || (engine->flag & RE_ENGINE_CAN_DRAW) == 0) {
1212  return false;
1213  }
1214 
1215  return true;
1216 }
1217 
1219 {
1221 }
1222 
1224  RenderEngine *engine, int x, int y, int width, int height, bool highlight)
1225 {
1227  BLI_rcti_init(&tile.rect, x, x + width, y, y + height);
1228 
1229  engine_tile_highlight_set(engine, &tile, highlight);
1230 }
1231 
1233 {
1234  if ((engine->flag & RE_ENGINE_HIGHLIGHT_TILES) == 0) {
1235  return;
1236  }
1237 
1238  Render *re = engine->re;
1239 
1241 
1242  if (re->highlighted_tiles != NULL) {
1244  }
1245 
1247 }
1248 
1249 /* -------------------------------------------------------------------- */
1257 {
1258  if (engine->re == NULL) {
1259  return false;
1260  }
1261 
1262  return RE_gl_context_get(engine->re) != NULL;
1263 }
1264 
1266 {
1267  DRW_render_context_enable(engine->re);
1268 }
1269 
1271 {
1272  DRW_render_context_disable(engine->re);
1273 }
1274 
typedef float(TangentPoint)[2]
Camera data-block and utility functions.
float BKE_camera_multiview_shift_x(const struct RenderData *rd, const struct Object *camera, const char *viewname)
void BKE_camera_multiview_model_matrix(const struct RenderData *rd, const struct Object *camera, const char *viewname, float r_modelmat[4][4])
bool BKE_camera_multiview_spherical_stereo(const struct RenderData *rd, const struct Object *camera)
bool BKE_reports_contain(ReportList *reports, eReportType level)
Definition: report.c:293
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition: report.c:83
void BKE_scene_graph_update_for_newframe_ex(struct Depsgraph *depsgraph, bool clear_recalc)
Definition: scene.cc:2658
float BKE_scene_frame_get(const struct Scene *scene)
bool BKE_scene_camera_switch_update(struct Scene *scene)
Definition: scene.cc:2295
void BKE_scene_frame_set(struct Scene *scene, float frame)
Definition: scene.cc:2420
bool BKE_scene_uses_cycles(const struct Scene *scene)
bool BKE_scene_uses_cycles_experimental_features(struct Scene *scene)
Definition: scene.cc:2871
#define GSET_FOREACH_END()
Definition: BLI_ghash.h:540
bool BLI_gset_ensure_p_ex(GSet *gs, const void *key, void ***r_key)
Definition: BLI_ghash.c:974
#define BLI_ghashutil_inthash_v4_cmp
Definition: BLI_ghash.h:601
GSet * BLI_gset_new(GSetHashFP hashfp, GSetCmpFP cmpfp, const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:947
void BLI_gset_clear(GSet *gs, GSetKeyFreeFP keyfreefp)
Definition: BLI_ghash.c:1032
#define GSET_FOREACH_BEGIN(type, var, what)
Definition: BLI_ghash.h:534
#define BLI_ghashutil_inthash_v4_p
Definition: BLI_ghash.h:592
bool BLI_gset_remove(GSet *gs, const void *key, GSetKeyFreeFP keyfreefp)
Definition: BLI_ghash.c:1002
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:100
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void * BLI_findstring(const struct ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE float int_as_float(int i)
void BLI_rcti_init(struct rcti *rect, int xmin, int xmax, int ymin, int ymax)
Definition: rct.c:417
#define STRNCPY(dst, src)
Definition: BLI_string.h:483
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC
Definition: string.c:42
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
void BLI_mutex_end(ThreadMutex *mutex)
Definition: threads.cc:388
void BLI_mutex_init(ThreadMutex *mutex)
Definition: threads.cc:368
#define THREAD_LOCK_WRITE
Definition: BLI_threads.h:121
void BLI_rw_mutex_lock(ThreadRWMutex *mutex, int mode)
Definition: threads.cc:488
void BLI_mutex_lock(ThreadMutex *mutex)
Definition: threads.cc:373
void BLI_mutex_unlock(ThreadMutex *mutex)
Definition: threads.cc:378
#define BLENDER_MAX_THREADS
Definition: BLI_threads.h:19
void BLI_rw_mutex_unlock(ThreadRWMutex *mutex)
Definition: threads.cc:498
#define UNUSED(x)
#define STREQ(a, b)
void BPY_DECREF_RNA_INVALIDATE(void *pyob_ptr)
typedef double(DMatrix)[4][4]
Depsgraph * DEG_graph_new(struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer, eEvaluationMode mode)
Definition: depsgraph.cc:267
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
void DEG_ids_clear_recalc(Depsgraph *depsgraph, bool backup)
@ DAG_EVAL_RENDER
Definition: DEG_depsgraph.h:46
void DEG_graph_replace_owners(struct Depsgraph *depsgraph, struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer)
Definition: depsgraph.cc:274
void DEG_graph_free(Depsgraph *graph)
Definition: depsgraph.cc:295
void DEG_evaluate_on_framechange(Depsgraph *graph, float frame)
void DEG_graph_tag_relations_update(struct Depsgraph *graph)
void DEG_graph_relations_update(struct Depsgraph *graph)
void DEG_debug_name_set(struct Depsgraph *depsgraph, const char *name)
struct Scene * DEG_get_input_scene(const Depsgraph *graph)
struct Main * DEG_get_bmain(const Depsgraph *graph)
struct ViewLayer * DEG_get_input_view_layer(const Depsgraph *graph)
eNodeSocketDatatype
Object is a sort of wrapper for general info.
#define RE_PASSNAME_COMBINED
#define R_PERSISTENT_DATA
#define MINAFRAME
#define R_BUTS_PREVIEW
#define R_EXR_CACHE_FILE
#define R_EDGE_FRS
#define R_NO_FRAME_UPDATE
eScenePassType
#define MAXFRAME
bool DRW_render_check_grease_pencil(struct Depsgraph *depsgraph)
void DRW_engines_free(void)
void DRW_engines_register(void)
void DRW_render_gpencil(struct RenderEngine *engine, struct Depsgraph *depsgraph)
void DRW_engine_register(struct DrawEngineType *draw_engine_type)
bool DRW_engine_render_support(struct DrawEngineType *draw_engine_type)
void DRW_render_context_disable(struct Render *render)
void DRW_render_context_enable(struct Render *render)
void DRW_engines_register_experimental(void)
bool GPU_backend_supported(void)
Definition: gpu_context.cc:218
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
Read Guarded memory(de)allocation.
#define MEM_reallocN(vmemh, len)
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position CLAMP
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between camera
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a producing a negative Combine Generate a color from its and blue channels(Deprecated)") DefNode(ShaderNode
#define RE_ENGINE_CAN_DRAW
Definition: RE_engine.h:64
#define RE_USE_ALEMBIC_PROCEDURAL
Definition: RE_engine.h:55
#define RE_INTERNAL
Definition: RE_engine.h:43
#define RE_ENGINE_ANIMATION
Definition: RE_engine.h:58
#define RE_USE_GPU_CONTEXT
Definition: RE_engine.h:52
#define RE_ENGINE_PREVIEW
Definition: RE_engine.h:59
#define RE_ENGINE_RENDERING
Definition: RE_engine.h:62
#define RE_ENGINE_HIGHLIGHT_TILES
Definition: RE_engine.h:63
#define RE_USE_PREVIEW
Definition: RE_engine.h:45
void(* update_render_passes_cb_t)(void *userdata, struct Scene *scene, struct ViewLayer *view_layer, const char *name, int channels, const char *chanid, eNodeSocketDatatype type)
Definition: RE_engine.h:119
#define RE_USE_POSTPROCESS
Definition: RE_engine.h:46
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
Scene scene
const Depsgraph * depsgraph
DEGForeachIDComponentCallback callback
depth_tx normal_tx diffuse_light_tx specular_light_tx volume_light_tx environment_tx ambient_occlusion_tx aov_value_tx in_weight_img image(1, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D_ARRAY, "out_weight_img") .image(3
static void re_ensure_passes_allocated_thread_safe(Render *re)
Definition: engine.c:396
RenderEngine * RE_engine_create(RenderEngineType *type)
Definition: engine.c:136
RenderEngineType * RE_engines_find(const char *idname)
Definition: engine.c:98
void RE_engine_draw_release(Render *re)
Definition: engine.c:1218
bool RE_engine_is_external(const Render *re)
Definition: engine.c:110
bool RE_engine_is_opengl(RenderEngineType *render_type)
Definition: engine.c:115
bool RE_bake_engine(Render *re, Depsgraph *depsgraph, Object *object, const int object_id, const BakePixel pixel_array[], const BakeTargets *targets, const eScenePassType pass_type, const int pass_filter, float result[])
Definition: engine.c:819
void RE_engine_frame_set(RenderEngine *engine, int frame, float subframe)
Definition: engine.c:785
void RE_engine_update_render_passes(struct RenderEngine *engine, struct Scene *scene, struct ViewLayer *view_layer, update_render_passes_cb_t callback, void *callback_data)
Definition: engine.c:1150
bool RE_engine_supports_alembic_procedural(const RenderEngineType *render_type, Scene *scene)
Definition: engine.c:121
static void engine_depsgraph_exit(RenderEngine *engine)
Definition: engine.c:770
void RE_engine_add_pass(RenderEngine *engine, const char *name, int channels, const char *chan_id, const char *layername)
Definition: engine.c:424
static void engine_depsgraph_init(RenderEngine *engine, ViewLayer *view_layer)
Definition: engine.c:712
void RE_engine_report(RenderEngine *engine, int type, const char *msg)
Definition: engine.c:548
bool RE_bake_has_engine(const Render *re)
Definition: engine.c:813
void RE_engine_active_view_set(RenderEngine *engine, const char *viewname)
Definition: engine.c:602
bool RE_engine_use_persistent_data(RenderEngine *engine)
Definition: engine.c:695
float RE_engine_get_camera_shift_x(RenderEngine *engine, Object *camera, bool use_spherical_stereo)
Definition: engine.c:608
void RE_engine_update_result(RenderEngine *engine, RenderResult *result)
Definition: engine.c:407
static void engine_render_view_layer(Render *re, RenderEngine *engine, ViewLayer *view_layer_iter, const bool use_engine, const bool use_grease_pencil)
Definition: engine.c:901
void RE_engine_update_memory_stats(RenderEngine *engine, float mem_used, float mem_peak)
Definition: engine.c:538
bool RE_engine_has_render_context(RenderEngine *engine)
Definition: engine.c:1256
void RE_engines_init(void)
Definition: engine.c:59
void RE_engine_tile_highlight_set(RenderEngine *engine, int x, int y, int width, int height, bool highlight)
Definition: engine.c:1223
bool RE_engine_draw_acquire(Render *re)
Definition: engine.c:1204
RenderPass * RE_engine_pass_by_index_get(RenderEngine *engine, const char *layer_name, int index)
Definition: engine.c:575
bool RE_engine_get_spherical_stereo(RenderEngine *engine, Object *camera)
Definition: engine.c:636
bool RE_engine_render(Render *re, bool do_all)
Definition: engine.c:988
bool RE_engine_test_break(RenderEngine *engine)
Definition: engine.c:488
void RE_engine_register_pass(struct RenderEngine *engine, struct Scene *scene, struct ViewLayer *view_layer, const char *name, int channels, const char *chanid, eNodeSocketDatatype type)
Definition: engine.c:1171
void RE_engine_update_stats(RenderEngine *engine, const char *stats, const char *info)
Definition: engine.c:501
void RE_engines_init_experimental()
Definition: engine.c:64
void RE_bake_engine_set_engine_parameters(Render *re, Main *bmain, Scene *scene)
Definition: engine.c:806
static RenderResult * render_result_from_bake(RenderEngine *engine, int x, int y, int w, int h, const char *layername)
Definition: engine.c:181
static void engine_depsgraph_free(RenderEngine *engine)
Definition: engine.c:146
void RE_engines_exit(void)
Definition: engine.c:69
void RE_engines_register(RenderEngineType *render_type)
Definition: engine.c:90
void RE_engine_free(RenderEngine *engine)
Definition: engine.c:164
void RE_engine_free_blender_memory(RenderEngine *engine)
Definition: engine.c:1187
RenderResult * RE_engine_get_result(RenderEngine *engine)
Definition: engine.c:481
struct RenderEngine * RE_engine_get(const Render *re)
Definition: engine.c:1199
void RE_engine_set_error_message(RenderEngine *engine, const char *msg)
Definition: engine.c:560
const char * RE_engine_active_view_get(RenderEngine *engine)
Definition: engine.c:596
RenderData * RE_engine_get_render_data(Render *re)
Definition: engine.c:690
void RE_engine_render_context_disable(RenderEngine *engine)
Definition: engine.c:1270
void RE_engine_end_result(RenderEngine *engine, RenderResult *result, bool cancel, bool highlight, bool merge_results)
Definition: engine.c:439
ListBase R_engines
Definition: engine.c:57
static void engine_tile_highlight_set(RenderEngine *engine, const HighlightedTile *tile, bool highlight)
Definition: engine.c:313
void RE_engine_render_context_enable(RenderEngine *engine)
Definition: engine.c:1265
void RE_engine_tile_highlight_clear_all(RenderEngine *engine)
Definition: engine.c:1232
static HighlightedTile highlighted_tile_from_result_get(Render *UNUSED(re), RenderResult *result)
Definition: engine.c:305
RenderResult * RE_engine_begin_result(RenderEngine *engine, int x, int y, int w, int h, const char *layername, const char *viewname)
Definition: engine.c:344
static bool engine_keep_depsgraph(RenderEngine *engine)
Definition: engine.c:702
static void render_result_to_bake(RenderEngine *engine, RenderResult *rr)
Definition: engine.c:252
void RE_engine_get_camera_model_matrix(RenderEngine *engine, Object *camera, bool use_spherical_stereo, float r_modelmat[16])
Definition: engine.c:620
void RE_engine_update_progress(RenderEngine *engine, float progress)
Definition: engine.c:528
rcti * RE_engine_get_current_tiles(Render *re, int *r_total_tiles, bool *r_needs_free)
Definition: engine.c:642
ccl_gpu_kernel_postfix ccl_global KernelWorkTile * tiles
ccl_global const KernelWorkTile * tile
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
static ulong * next
#define G(x, y, z)
RenderPass * RE_pass_find_by_name(RenderLayer *rl, const char *name, const char *viewname)
Definition: pipeline.c:2591
RenderResult * RE_AcquireResultRead(Render *re)
Definition: pipeline.c:314
void * RE_gl_context_get(Render *re)
Definition: pipeline.c:927
void render_copy_renderdata(RenderData *to, RenderData *from)
Definition: pipeline.c:717
void RE_FreePersistentData(const Scene *scene)
Definition: pipeline.c:660
void render_update_anim_renderdata(Render *re, RenderData *rd, ListBase *render_layers)
Definition: pipeline.c:831
RenderLayer * RE_GetRenderLayer(RenderResult *rr, const char *name)
Definition: pipeline.c:244
void RE_ReleaseResult(Render *re)
Definition: pipeline.c:351
const char * RE_GetActiveRenderView(Render *re)
Definition: pipeline.c:1671
void RE_SetActiveRenderView(Render *re, const char *viewname)
Definition: pipeline.c:1666
void render_result_exr_file_cache_write(Render *re)
RenderPass * render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channels, const char *name, const char *viewname, const char *chan_id, const bool allocate)
void render_result_merge(RenderResult *rr, RenderResult *rrpart)
void render_result_passes_allocated_ensure(RenderResult *rr)
void render_result_free(RenderResult *rr)
Definition: render_result.c:70
RenderResult * render_result_new(Render *re, rcti *partrct, const char *layername, const char *viewname)
void render_result_clone_passes(Render *re, RenderResult *rr, const char *viewname)
void render_result_free_list(ListBase *lb, RenderResult *rr)
void RE_create_render_pass(RenderResult *rr, const char *name, int channels, const char *chan_id, const char *layername, const char *viewname, const bool allocate)
#define FOREACH_VIEW_LAYER_TO_RENDER_END
#define RR_ALL_VIEWS
Definition: render_result.h:13
#define RR_ALL_LAYERS
Definition: render_result.h:12
#define FOREACH_VIEW_LAYER_TO_RENDER_BEGIN(re_, iter_)
#define R_ANIMATION
Definition: render_types.h:133
char render_layer_name[RE_MAXNAME]
Definition: RE_bake.h:31
int channels_num
Definition: RE_bake.h:46
int images_num
Definition: RE_bake.h:37
BakeImage * images
Definition: RE_bake.h:36
char name[66]
Definition: DNA_ID.h:378
void * first
Definition: DNA_listBase.h:31
Definition: BKE_main.h:121
char engine[32]
void(* render)(struct RenderEngine *engine, struct Depsgraph *depsgraph)
Definition: RE_engine.h:78
void(* update)(struct RenderEngine *engine, struct Main *bmain, struct Depsgraph *depsgraph)
Definition: RE_engine.h:76
struct DrawEngineType * draw_engine
Definition: RE_engine.h:113
void(* draw)(struct RenderEngine *engine, const struct bContext *context, struct Depsgraph *depsgraph)
Definition: RE_engine.h:87
void(* update_render_passes)(struct RenderEngine *engine, struct Scene *scene, struct ViewLayer *view_layer)
Definition: RE_engine.h:109
struct ReportList * reports
Definition: RE_engine.h:141
struct Depsgraph * depsgraph
Definition: RE_engine.h:152
RenderEngineType * type
Definition: RE_engine.h:128
const struct BakePixel * pixels
Definition: RE_engine.h:145
float * result
Definition: RE_engine.h:146
char text[512]
Definition: RE_engine.h:137
bool has_grease_pencil
Definition: RE_engine.h:153
struct Render * re
Definition: RE_engine.h:135
void * update_render_passes_data
Definition: RE_engine.h:158
ListBase fullresult
Definition: RE_engine.h:136
void * py_instance
Definition: RE_engine.h:129
int resolution_x
Definition: RE_engine.h:139
struct RenderEngine::@1172 bake
update_render_passes_cb_t update_render_passes_cb
Definition: RE_engine.h:157
int resolution_y
Definition: RE_engine.h:139
ThreadMutex update_render_passes_mutex
Definition: RE_engine.h:156
const struct BakeTargets * targets
Definition: RE_engine.h:144
struct Object * camera_override
Definition: RE_engine.h:132
ListBase passes
Definition: RE_pipeline.h:95
char name[RE_MAXNAME]
Definition: RE_pipeline.h:87
float * rect
Definition: RE_pipeline.h:67
ListBase layers
Definition: RE_pipeline.h:122
char * error
Definition: RE_pipeline.h:139
bool passes_allocated
Definition: RE_pipeline.h:143
const char * statstr
Definition: RE_pipeline.h:150
char scene_name[MAX_ID_NAME - 2]
Definition: RE_pipeline.h:151
float mem_peak
Definition: RE_pipeline.h:152
float mem_used
Definition: RE_pipeline.h:152
const char * infostr
Definition: RE_pipeline.h:150
ThreadMutex engine_draw_mutex
Definition: render_types.h:60
void * sdh
Definition: render_types.h:109
void(* progress)(void *handle, float i)
Definition: render_types.h:110
void * duh
Definition: render_types.h:104
void * prh
Definition: render_types.h:111
RenderResult * result
Definition: render_types.h:49
RenderData r
Definition: render_types.h:82
int winy
Definition: render_types.h:65
struct RenderEngine * engine
Definition: render_types.h:91
struct Main * main
Definition: render_types.h:80
struct GSet * highlighted_tiles
Definition: render_types.h:88
void * dlh
Definition: render_types.h:114
Scene * scene
Definition: render_types.h:81
void(* display_update)(void *handle, RenderResult *rr, rcti *rect)
Definition: render_types.h:103
short flag
Definition: render_types.h:46
ThreadRWMutex resultmutex
Definition: render_types.h:57
char viewname[MAX_NAME]
Definition: render_types.h:123
RenderStats i
Definition: render_types.h:118
void * tbh
Definition: render_types.h:116
int winx
Definition: render_types.h:65
void(* draw_lock)(void *handle, bool lock)
Definition: render_types.h:113
void(* stats_draw)(void *handle, RenderStats *ri)
Definition: render_types.h:108
int(* test_break)(void *handle)
Definition: render_types.h:115
ThreadMutex highlighted_tiles_mutex
Definition: render_types.h:87
struct ReportList * reports
Definition: render_types.h:120
rcti disprect
Definition: render_types.h:66
struct Object * camera_override
Definition: render_types.h:85
struct RenderData r
ListBase view_layers
char name[64]
int ymin
Definition: DNA_vec_types.h:64
int ymax
Definition: DNA_vec_types.h:64
int xmin
Definition: DNA_vec_types.h:63
int xmax
Definition: DNA_vec_types.h:63