1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2006 Blender Foundation.
17  * All rights reserved.
18  */
19 
20 /** \file
21  * \ingroup render
22  */
23 
24 #include <errno.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 
29 #include "MEM_guardedalloc.h"
30 
31 #include "BLI_ghash.h"
32 #include "BLI_hash_md5.h"
33 #include "BLI_listbase.h"
34 #include "BLI_path_util.h"
35 #include "BLI_rect.h"
36 #include "BLI_string.h"
37 #include "BLI_string_utils.h"
38 #include "BLI_threads.h"
39 #include "BLI_utildefines.h"
40 
41 #include "BKE_appdir.h"
42 #include "BKE_camera.h"
43 #include "BKE_global.h"
44 #include "BKE_image.h"
45 #include "BKE_report.h"
46 #include "BKE_scene.h"
47 
48 #include "IMB_colormanagement.h"
49 #include "IMB_imbuf.h"
50 #include "IMB_imbuf_types.h"
51 
52 #include "intern/openexr/openexr_multi.h"
53 
54 #include "RE_engine.h"
55 
56 #include "render_result.h"
57 #include "render_types.h"
58 
59 /********************************** Free *************************************/
60 
render_result_views_free(RenderResult * rr)61 static void render_result_views_free(RenderResult *rr)
62 {
63   while (rr->views.first) {
64     RenderView *rv = rr->views.first;
65     BLI_remlink(&rr->views, rv);
66 
67     if (rv->rect32) {
68       MEM_freeN(rv->rect32);
69     }
70 
71     if (rv->rectz) {
72       MEM_freeN(rv->rectz);
73     }
74 
75     if (rv->rectf) {
76       MEM_freeN(rv->rectf);
77     }
78 
79     MEM_freeN(rv);
80   }
81 
82   rr->have_combined = false;
83 }
84 
render_result_free(RenderResult * rr)85 void render_result_free(RenderResult *rr)
86 {
87   if (rr == NULL) {
88     return;
89   }
90 
91   while (rr->layers.first) {
92     RenderLayer *rl = rr->layers.first;
93 
94     while (rl->passes.first) {
95       RenderPass *rpass = rl->passes.first;
96       if (rpass->rect) {
97         MEM_freeN(rpass->rect);
98       }
99       BLI_remlink(&rl->passes, rpass);
100       MEM_freeN(rpass);
101     }
102     BLI_remlink(&rr->layers, rl);
103     MEM_freeN(rl);
104   }
105 
106   render_result_views_free(rr);
107 
108   if (rr->rect32) {
109     MEM_freeN(rr->rect32);
110   }
111   if (rr->rectz) {
112     MEM_freeN(rr->rectz);
113   }
114   if (rr->rectf) {
115     MEM_freeN(rr->rectf);
116   }
117   if (rr->text) {
118     MEM_freeN(rr->text);
119   }
120   if (rr->error) {
121     MEM_freeN(rr->error);
122   }
123 
124   BKE_stamp_data_free(rr->stamp_data);
125 
126   MEM_freeN(rr);
127 }
128 
129 /* version that's compatible with fullsample buffers */
render_result_free_list(ListBase * lb,RenderResult * rr)130 void render_result_free_list(ListBase *lb, RenderResult *rr)
131 {
132   RenderResult *rrnext;
133 
134   for (; rr; rr = rrnext) {
135     rrnext = rr->next;
136 
137     if (lb && lb->first) {
138       BLI_remlink(lb, rr);
139     }
140 
141     render_result_free(rr);
142   }
143 }
144 
145 /********************************* multiview *************************************/
146 
147 /* create a new views Listbase in rr without duplicating the memory pointers */
render_result_views_shallowcopy(RenderResult * dst,RenderResult * src)148 void render_result_views_shallowcopy(RenderResult *dst, RenderResult *src)
149 {
150   RenderView *rview;
151 
152   if (dst == NULL || src == NULL) {
153     return;
154   }
155 
156   for (rview = src->views.first; rview; rview = rview->next) {
157     RenderView *rv;
158 
159     rv = MEM_mallocN(sizeof(RenderView), "new render view");
160     BLI_addtail(&dst->views, rv);
161 
162     BLI_strncpy(rv->name, rview->name, sizeof(rv->name));
163     rv->rectf = rview->rectf;
164     rv->rectz = rview->rectz;
165     rv->rect32 = rview->rect32;
166   }
167 }
168 
169 /* free the views created temporarily */
render_result_views_shallowdelete(RenderResult * rr)170 void render_result_views_shallowdelete(RenderResult *rr)
171 {
172   if (rr == NULL) {
173     return;
174   }
175 
176   while (rr->views.first) {
177     RenderView *rv = rr->views.first;
178     BLI_remlink(&rr->views, rv);
179     MEM_freeN(rv);
180   }
181 }
182 
set_pass_name(char * outname,const char * name,int channel,const char * chan_id)183 static char *set_pass_name(char *outname, const char *name, int channel, const char *chan_id)
184 {
185   const char *strings[2];
186   int strings_len = 0;
187   strings[strings_len++] = name;
188   char token[2];
189   if (channel >= 0) {
190     ARRAY_SET_ITEMS(token, chan_id[channel], '\0');
191     strings[strings_len++] = token;
192   }
193   BLI_string_join_array_by_sep_char(outname, EXR_PASS_MAXNAME, '.', strings, strings_len);
194   return outname;
195 }
196 
set_pass_full_name(char * fullname,const char * name,int channel,const char * view,const char * chan_id)197 static void set_pass_full_name(
198     char *fullname, const char *name, int channel, const char *view, const char *chan_id)
199 {
200   const char *strings[3];
201   int strings_len = 0;
202   strings[strings_len++] = name;
203   if (view && view[0]) {
204     strings[strings_len++] = view;
205   }
206   char token[2];
207   if (channel >= 0) {
208     ARRAY_SET_ITEMS(token, chan_id[channel], '\0');
209     strings[strings_len++] = token;
210   }
211   BLI_string_join_array_by_sep_char(fullname, EXR_PASS_MAXNAME, '.', strings, strings_len);
212 }
213 
214 /********************************** New **************************************/
215 
render_layer_add_pass(RenderResult * rr,RenderLayer * rl,int channels,const char * name,const char * viewname,const char * chan_id)216 RenderPass *render_layer_add_pass(RenderResult *rr,
217                                   RenderLayer *rl,
218                                   int channels,
219                                   const char *name,
220                                   const char *viewname,
221                                   const char *chan_id)
222 {
223   const int view_id = BLI_findstringindex(&rr->views, viewname, offsetof(RenderView, name));
224   RenderPass *rpass = MEM_callocN(sizeof(RenderPass), name);
225   size_t rectsize = ((size_t)rr->rectx) * rr->recty * channels;
226 
227   rpass->channels = channels;
228   rpass->rectx = rl->rectx;
229   rpass->recty = rl->recty;
230   rpass->view_id = view_id;
231 
232   BLI_strncpy(rpass->name, name, sizeof(rpass->name));
233   BLI_strncpy(rpass->chan_id, chan_id, sizeof(rpass->chan_id));
234   BLI_strncpy(rpass->view, viewname, sizeof(rpass->view));
235   set_pass_full_name(rpass->fullname, rpass->name, -1, rpass->view, rpass->chan_id);
236 
237   if (rl->exrhandle) {
238     int a;
239     for (a = 0; a < channels; a++) {
240       char passname[EXR_PASS_MAXNAME];
241       IMB_exr_add_channel(rl->exrhandle,
242                           rl->name,
243                           set_pass_name(passname, rpass->name, a, rpass->chan_id),
244                           viewname,
245                           0,
246                           0,
247                           NULL,
248                           false);
249     }
250   }
251 
252   /* Always allocate combined for display, in case of save buffers
253    * other passes are not allocated and only saved to the EXR file. */
254   if (rl->exrhandle == NULL || STREQ(rpass->name, RE_PASSNAME_COMBINED)) {
255     float *rect;
256     int x;
257 
258     rpass->rect = MEM_callocN(sizeof(float) * rectsize, name);
259     if (rpass->rect == NULL) {
260       MEM_freeN(rpass);
261       return NULL;
262     }
263 
264     if (STREQ(rpass->name, RE_PASSNAME_VECTOR)) {
265       /* initialize to max speed */
266       rect = rpass->rect;
267       for (x = rectsize - 1; x >= 0; x--) {
268         rect[x] = PASS_VECTOR_MAX;
269       }
270     }
271     else if (STREQ(rpass->name, RE_PASSNAME_Z)) {
272       rect = rpass->rect;
273       for (x = rectsize - 1; x >= 0; x--) {
274         rect[x] = 10e10;
275       }
276     }
277   }
278 
279   BLI_addtail(&rl->passes, rpass);
280 
281   return rpass;
282 }
283 
284 /* called by main render as well for parts */
285 /* will read info from Render *re to define layers */
286 /* called in threads */
287 /* re->winx,winy is coordinate space of entire image, partrct the part within */
render_result_new(Render * re,rcti * partrct,int crop,int savebuffers,const char * layername,const char * viewname)288 RenderResult *render_result_new(Render *re,
289                                 rcti *partrct,
290                                 int crop,
291                                 int savebuffers,
292                                 const char *layername,
293                                 const char *viewname)
294 {
295   RenderResult *rr;
296   RenderLayer *rl;
297   RenderView *rv;
298   int rectx, recty;
299 
300   rectx = BLI_rcti_size_x(partrct);
301   recty = BLI_rcti_size_y(partrct);
302 
303   if (rectx <= 0 || recty <= 0) {
304     return NULL;
305   }
306 
307   rr = MEM_callocN(sizeof(RenderResult), "new render result");
308   rr->rectx = rectx;
309   rr->recty = recty;
310   rr->renrect.xmin = 0;
311   rr->renrect.xmax = rectx - 2 * crop;
312   /* crop is one or two extra pixels rendered for filtering, is used for merging and display too */
313   rr->crop = crop;
314 
315   /* tilerect is relative coordinates within render disprect. do not subtract crop yet */
316   rr->tilerect.xmin = partrct->xmin - re->disprect.xmin;
317   rr->tilerect.xmax = partrct->xmax - re->disprect.xmin;
318   rr->tilerect.ymin = partrct->ymin - re->disprect.ymin;
319   rr->tilerect.ymax = partrct->ymax - re->disprect.ymin;
320 
321   if (savebuffers) {
322     rr->do_exr_tile = true;
323   }
324 
325   render_result_views_new(rr, &re->r);
326 
327   /* check renderdata for amount of layers */
328   FOREACH_VIEW_LAYER_TO_RENDER_BEGIN (re, view_layer) {
329     if (layername && layername[0]) {
330       if (!STREQ(view_layer->name, layername)) {
331         continue;
332       }
333     }
334 
335     rl = MEM_callocN(sizeof(RenderLayer), "new render layer");
336     BLI_addtail(&rr->layers, rl);
337 
338     BLI_strncpy(rl->name, view_layer->name, sizeof(rl->name));
339     rl->layflag = view_layer->layflag;
340 
341     /* for debugging: view_layer->passflag | SCE_PASS_RAYHITS; */
342     rl->passflag = view_layer->passflag;
343 
344     rl->rectx = rectx;
345     rl->recty = recty;
346 
347     if (rr->do_exr_tile) {
348       rl->exrhandle = IMB_exr_get_handle();
349     }
350 
351     for (rv = rr->views.first; rv; rv = rv->next) {
352       const char *view = rv->name;
353 
354       if (viewname && viewname[0]) {
355         if (!STREQ(view, viewname)) {
356           continue;
357         }
358       }
359 
360       if (rr->do_exr_tile) {
361         IMB_exr_add_view(rl->exrhandle, view);
362       }
363 
364 #define RENDER_LAYER_ADD_PASS_SAFE(rr, rl, channels, name, viewname, chan_id) \
365   do { \
366     if (render_layer_add_pass(rr, rl, channels, name, viewname, chan_id) == NULL) { \
367       render_result_free(rr); \
368       return NULL; \
369     } \
370   } while (false)
371 
372       /* a renderlayer should always have a Combined pass*/
373       render_layer_add_pass(rr, rl, 4, "Combined", view, "RGBA");
374 
375       if (view_layer->passflag & SCE_PASS_Z) {
376         RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, RE_PASSNAME_Z, view, "Z");
377       }
378       if (view_layer->passflag & SCE_PASS_VECTOR) {
379         RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 4, RE_PASSNAME_VECTOR, view, "XYZW");
380       }
381       if (view_layer->passflag & SCE_PASS_NORMAL) {
382         RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_NORMAL, view, "XYZ");
383       }
384       if (view_layer->passflag & SCE_PASS_UV) {
385         RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_UV, view, "UVA");
386       }
387       if (view_layer->passflag & SCE_PASS_EMIT) {
388         RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_EMIT, view, "RGB");
389       }
390       if (view_layer->passflag & SCE_PASS_AO) {
391         RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_AO, view, "RGB");
392       }
393       if (view_layer->passflag & SCE_PASS_ENVIRONMENT) {
394         RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_ENVIRONMENT, view, "RGB");
395       }
396       if (view_layer->passflag & SCE_PASS_SHADOW) {
397         RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_SHADOW, view, "RGB");
398       }
399       if (view_layer->passflag & SCE_PASS_INDEXOB) {
400         RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, RE_PASSNAME_INDEXOB, view, "X");
401       }
402       if (view_layer->passflag & SCE_PASS_INDEXMA) {
403         RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, RE_PASSNAME_INDEXMA, view, "X");
404       }
405       if (view_layer->passflag & SCE_PASS_MIST) {
406         RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, RE_PASSNAME_MIST, view, "Z");
407       }
408       if (rl->passflag & SCE_PASS_RAYHITS) {
409         RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 4, RE_PASSNAME_RAYHITS, view, "RGB");
410       }
411       if (view_layer->passflag & SCE_PASS_DIFFUSE_DIRECT) {
412         RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_DIFFUSE_DIRECT, view, "RGB");
413       }
414       if (view_layer->passflag & SCE_PASS_DIFFUSE_INDIRECT) {
415         RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_DIFFUSE_INDIRECT, view, "RGB");
416       }
417       if (view_layer->passflag & SCE_PASS_DIFFUSE_COLOR) {
418         RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_DIFFUSE_COLOR, view, "RGB");
419       }
420       if (view_layer->passflag & SCE_PASS_GLOSSY_DIRECT) {
421         RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_GLOSSY_DIRECT, view, "RGB");
422       }
423       if (view_layer->passflag & SCE_PASS_GLOSSY_INDIRECT) {
424         RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_GLOSSY_INDIRECT, view, "RGB");
425       }
426       if (view_layer->passflag & SCE_PASS_GLOSSY_COLOR) {
427         RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_GLOSSY_COLOR, view, "RGB");
428       }
429       if (view_layer->passflag & SCE_PASS_TRANSM_DIRECT) {
430         RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_TRANSM_DIRECT, view, "RGB");
431       }
432       if (view_layer->passflag & SCE_PASS_TRANSM_INDIRECT) {
433         RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_TRANSM_INDIRECT, view, "RGB");
434       }
435       if (view_layer->passflag & SCE_PASS_TRANSM_COLOR) {
436         RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_TRANSM_COLOR, view, "RGB");
437       }
438       if (view_layer->passflag & SCE_PASS_SUBSURFACE_DIRECT) {
439         RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_SUBSURFACE_DIRECT, view, "RGB");
440       }
441       if (view_layer->passflag & SCE_PASS_SUBSURFACE_INDIRECT) {
442         RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_SUBSURFACE_INDIRECT, view, "RGB");
443       }
444       if (view_layer->passflag & SCE_PASS_SUBSURFACE_COLOR) {
445         RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_SUBSURFACE_COLOR, view, "RGB");
446       }
447 #undef RENDER_LAYER_ADD_PASS_SAFE
448     }
449   }
450   FOREACH_VIEW_LAYER_TO_RENDER_END;
451 
452   /* previewrender doesn't do layers, so we make a default one */
453   if (BLI_listbase_is_empty(&rr->layers) && !(layername && layername[0])) {
454     rl = MEM_callocN(sizeof(RenderLayer), "new render layer");
455     BLI_addtail(&rr->layers, rl);
456 
457     rl->rectx = rectx;
458     rl->recty = recty;
459 
460     /* duplicate code... */
461     if (rr->do_exr_tile) {
462       rl->exrhandle = IMB_exr_get_handle();
463     }
464 
465     for (rv = rr->views.first; rv; rv = rv->next) {
466       const char *view = rv->name;
467 
468       if (viewname && viewname[0]) {
469         if (!STREQ(view, viewname)) {
470           continue;
471         }
472       }
473 
474       if (rr->do_exr_tile) {
475         IMB_exr_add_view(rl->exrhandle, view);
476       }
477 
478       /* a renderlayer should always have a Combined pass */
479       render_layer_add_pass(rr, rl, 4, RE_PASSNAME_COMBINED, view, "RGBA");
480     }
481 
482     /* note, this has to be in sync with scene.c */
483     rl->layflag = 0x7FFF; /* solid ztra halo strand */
484     rl->passflag = SCE_PASS_COMBINED;
485 
486     re->active_view_layer = 0;
487   }
488 
489   /* border render; calculate offset for use in compositor. compo is centralized coords */
490   /* XXX obsolete? I now use it for drawing border render offset (ton) */
491   rr->xof = re->disprect.xmin + BLI_rcti_cent_x(&re->disprect) - (re->winx / 2);
492   rr->yof = re->disprect.ymin + BLI_rcti_cent_y(&re->disprect) - (re->winy / 2);
493 
494   return rr;
495 }
496 
render_result_clone_passes(Render * re,RenderResult * rr,const char * viewname)497 void render_result_clone_passes(Render *re, RenderResult *rr, const char *viewname)
498 {
499   RenderLayer *rl;
500   RenderPass *main_rp;
501 
502   for (rl = rr->layers.first; rl; rl = rl->next) {
503     RenderLayer *main_rl = BLI_findstring(
504         &re->result->layers, rl->name, offsetof(RenderLayer, name));
505     if (!main_rl) {
506       continue;
507     }
508 
509     for (main_rp = main_rl->passes.first; main_rp; main_rp = main_rp->next) {
510       if (viewname && viewname[0] && !STREQ(main_rp->view, viewname)) {
511         continue;
512       }
513 
514       /* Compare fullname to make sure that the view also is equal. */
515       RenderPass *rp = BLI_findstring(
516           &rl->passes, main_rp->fullname, offsetof(RenderPass, fullname));
517       if (!rp) {
518         render_layer_add_pass(
519             rr, rl, main_rp->channels, main_rp->name, main_rp->view, main_rp->chan_id);
520       }
521     }
522   }
523 }
524 
RE_create_render_pass(RenderResult * rr,const char * name,int channels,const char * chan_id,const char * layername,const char * viewname)525 void RE_create_render_pass(RenderResult *rr,
526                            const char *name,
527                            int channels,
528                            const char *chan_id,
529                            const char *layername,
530                            const char *viewname)
531 {
532   RenderLayer *rl;
533   RenderPass *rp;
534   RenderView *rv;
535 
536   for (rl = rr->layers.first; rl; rl = rl->next) {
537     if (layername && layername[0] && !STREQ(rl->name, layername)) {
538       continue;
539     }
540 
541     for (rv = rr->views.first; rv; rv = rv->next) {
542       const char *view = rv->name;
543 
544       if (viewname && viewname[0] && !STREQ(view, viewname)) {
545         continue;
546       }
547 
548       /* Ensure that the pass doesn't exist yet. */
549       for (rp = rl->passes.first; rp; rp = rp->next) {
550         if (!STREQ(rp->name, name)) {
551           continue;
552         }
553         if (!STREQ(rp->view, view)) {
554           continue;
555         }
556         break;
557       }
558 
559       if (!rp) {
560         render_layer_add_pass(rr, rl, channels, name, view, chan_id);
561       }
562     }
563   }
564 }
565 
passtype_from_name(const char * name)566 static int passtype_from_name(const char *name)
567 {
568   const char delim[] = {'.', '\0'};
569   const char *sep, *suf;
570   int len = BLI_str_partition(name, delim, &sep, &suf);
571 
572 #define CHECK_PASS(NAME) \
573   if (STREQLEN(name, RE_PASSNAME_##NAME, len)) { \
574     return SCE_PASS_##NAME; \
575   } \
576   ((void)0)
577 
578   CHECK_PASS(COMBINED);
579   CHECK_PASS(Z);
580   CHECK_PASS(VECTOR);
581   CHECK_PASS(NORMAL);
582   CHECK_PASS(UV);
583   CHECK_PASS(EMIT);
584   CHECK_PASS(SHADOW);
585   CHECK_PASS(AO);
586   CHECK_PASS(ENVIRONMENT);
587   CHECK_PASS(INDEXOB);
588   CHECK_PASS(INDEXMA);
589   CHECK_PASS(MIST);
590   CHECK_PASS(RAYHITS);
591   CHECK_PASS(DIFFUSE_DIRECT);
592   CHECK_PASS(DIFFUSE_INDIRECT);
593   CHECK_PASS(DIFFUSE_COLOR);
594   CHECK_PASS(GLOSSY_DIRECT);
595   CHECK_PASS(GLOSSY_INDIRECT);
596   CHECK_PASS(GLOSSY_COLOR);
597   CHECK_PASS(TRANSM_DIRECT);
598   CHECK_PASS(TRANSM_INDIRECT);
599   CHECK_PASS(TRANSM_COLOR);
600   CHECK_PASS(SUBSURFACE_DIRECT);
601   CHECK_PASS(SUBSURFACE_INDIRECT);
602   CHECK_PASS(SUBSURFACE_COLOR);
603 
604 #undef CHECK_PASS
605   return 0;
606 }
607 
608 /* callbacks for render_result_new_from_exr */
ml_addlayer_cb(void * base,const char * str)609 static void *ml_addlayer_cb(void *base, const char *str)
610 {
611   RenderResult *rr = base;
612   RenderLayer *rl;
613 
614   rl = MEM_callocN(sizeof(RenderLayer), "new render layer");
615   BLI_addtail(&rr->layers, rl);
616 
617   BLI_strncpy(rl->name, str, EXR_LAY_MAXNAME);
618   return rl;
619 }
620 
ml_addpass_cb(void * base,void * lay,const char * name,float * rect,int totchan,const char * chan_id,const char * view)621 static void ml_addpass_cb(void *base,
622                           void *lay,
623                           const char *name,
624                           float *rect,
625                           int totchan,
626                           const char *chan_id,
627                           const char *view)
628 {
629   RenderResult *rr = base;
630   RenderLayer *rl = lay;
631   RenderPass *rpass = MEM_callocN(sizeof(RenderPass), "loaded pass");
632 
633   BLI_addtail(&rl->passes, rpass);
634   rpass->channels = totchan;
635   rl->passflag |= passtype_from_name(name);
636 
637   /* channel id chars */
638   BLI_strncpy(rpass->chan_id, chan_id, sizeof(rpass->chan_id));
639 
640   rpass->rect = rect;
641   BLI_strncpy(rpass->name, name, EXR_PASS_MAXNAME);
642   BLI_strncpy(rpass->view, view, sizeof(rpass->view));
643   set_pass_full_name(rpass->fullname, name, -1, view, rpass->chan_id);
644 
645   if (view[0] != '\0') {
646     rpass->view_id = BLI_findstringindex(&rr->views, view, offsetof(RenderView, name));
647   }
648   else {
649     rpass->view_id = 0;
650   }
651 }
652 
ml_addview_cb(void * base,const char * str)653 static void *ml_addview_cb(void *base, const char *str)
654 {
655   RenderResult *rr = base;
656   RenderView *rv;
657 
658   rv = MEM_callocN(sizeof(RenderView), "new render view");
659   BLI_strncpy(rv->name, str, EXR_VIEW_MAXNAME);
660 
661   /* For stereo drawing we need to ensure:
662    * STEREO_LEFT_NAME  == STEREO_LEFT_ID and
663    * STEREO_RIGHT_NAME == STEREO_RIGHT_ID */
664 
665   if (STREQ(str, STEREO_LEFT_NAME)) {
666     BLI_addhead(&rr->views, rv);
667   }
668   else if (STREQ(str, STEREO_RIGHT_NAME)) {
669     RenderView *left_rv = BLI_findstring(&rr->views, STEREO_LEFT_NAME, offsetof(RenderView, name));
670 
671     if (left_rv == NULL) {
672       BLI_addhead(&rr->views, rv);
673     }
674     else {
675       BLI_insertlinkafter(&rr->views, left_rv, rv);
676     }
677   }
678   else {
679     BLI_addtail(&rr->views, rv);
680   }
681 
682   return rv;
683 }
684 
order_render_passes(const void * a,const void * b)685 static int order_render_passes(const void *a, const void *b)
686 {
687   // 1 if a is after b
688   RenderPass *rpa = (RenderPass *)a;
689   RenderPass *rpb = (RenderPass *)b;
690   unsigned int passtype_a = passtype_from_name(rpa->name);
691   unsigned int passtype_b = passtype_from_name(rpb->name);
692 
693   /* Render passes with default type always go first. */
694   if (passtype_b && !passtype_a) {
695     return 1;
696   }
697   if (passtype_a && !passtype_b) {
698     return 0;
699   }
700 
701   if (passtype_a && passtype_b) {
702     if (passtype_a > passtype_b) {
703       return 1;
704     }
705     if (passtype_a < passtype_b) {
706       return 0;
707     }
708   }
709   else {
710     int cmp = strncmp(rpa->name, rpb->name, EXR_PASS_MAXNAME);
711     if (cmp > 0) {
712       return 1;
713     }
714     if (cmp < 0) {
715       return 0;
716     }
717   }
718 
719   /* they have the same type */
720   /* left first */
721   if (STREQ(rpa->view, STEREO_LEFT_NAME)) {
722     return 0;
723   }
724   if (STREQ(rpb->view, STEREO_LEFT_NAME)) {
725     return 1;
726   }
727 
728   /* right second */
729   if (STREQ(rpa->view, STEREO_RIGHT_NAME)) {
730     return 0;
731   }
732   if (STREQ(rpb->view, STEREO_RIGHT_NAME)) {
733     return 1;
734   }
735 
736   /* remaining in ascending id order */
737   return (rpa->view_id < rpb->view_id);
738 }
739 
740 /* From imbuf, if a handle was returned and
741  * it's not a singlelayer multiview we convert this to render result. */
render_result_new_from_exr(void * exrhandle,const char * colorspace,bool predivide,int rectx,int recty)742 RenderResult *render_result_new_from_exr(
743     void *exrhandle, const char *colorspace, bool predivide, int rectx, int recty)
744 {
745   RenderResult *rr = MEM_callocN(sizeof(RenderResult), __func__);
746   RenderLayer *rl;
747   RenderPass *rpass;
748   const char *to_colorspace = IMB_colormanagement_role_colorspace_name_get(
749       COLOR_ROLE_SCENE_LINEAR);
750 
751   rr->rectx = rectx;
752   rr->recty = recty;
753 
754   IMB_exr_multilayer_convert(exrhandle, rr, ml_addview_cb, ml_addlayer_cb, ml_addpass_cb);
755 
756   for (rl = rr->layers.first; rl; rl = rl->next) {
757     rl->rectx = rectx;
758     rl->recty = recty;
759 
760     BLI_listbase_sort(&rl->passes, order_render_passes);
761 
762     for (rpass = rl->passes.first; rpass; rpass = rpass->next) {
763       rpass->rectx = rectx;
764       rpass->recty = recty;
765 
766       if (rpass->channels >= 3) {
767         IMB_colormanagement_transform(rpass->rect,
768                                       rpass->rectx,
769                                       rpass->recty,
770                                       rpass->channels,
771                                       colorspace,
772                                       to_colorspace,
773                                       predivide);
774       }
775     }
776   }
777 
778   return rr;
779 }
780 
render_result_view_new(RenderResult * rr,const char * viewname)781 void render_result_view_new(RenderResult *rr, const char *viewname)
782 {
783   RenderView *rv = MEM_callocN(sizeof(RenderView), "new render view");
784   BLI_addtail(&rr->views, rv);
785   BLI_strncpy(rv->name, viewname, sizeof(rv->name));
786 }
787 
render_result_views_new(RenderResult * rr,const RenderData * rd)788 void render_result_views_new(RenderResult *rr, const RenderData *rd)
789 {
790   SceneRenderView *srv;
791 
792   /* clear previously existing views - for sequencer */
793   render_result_views_free(rr);
794 
795   /* check renderdata for amount of views */
796   if ((rd->scemode & R_MULTIVIEW)) {
797     for (srv = rd->views.first; srv; srv = srv->next) {
798       if (BKE_scene_multiview_is_render_view_active(rd, srv) == false) {
799         continue;
800       }
801       render_result_view_new(rr, srv->name);
802     }
803   }
804 
805   /* we always need at least one view */
806   if (BLI_listbase_count_at_most(&rr->views, 1) == 0) {
807     render_result_view_new(rr, "");
808   }
809 }
810 
render_result_has_views(RenderResult * rr)811 bool render_result_has_views(RenderResult *rr)
812 {
813   RenderView *rv = rr->views.first;
814   return (rv && (rv->next || rv->name[0]));
815 }
816 
817 /*********************************** Merge ***********************************/
818 
do_merge_tile(RenderResult * rr,RenderResult * rrpart,float * target,float * tile,int pixsize)819 static void do_merge_tile(
820     RenderResult *rr, RenderResult *rrpart, float *target, float *tile, int pixsize)
821 {
822   int y, tilex, tiley;
823   size_t ofs, copylen;
824 
825   copylen = tilex = rrpart->rectx;
826   tiley = rrpart->recty;
827 
828   if (rrpart->crop) { /* filters add pixel extra */
829     tile += pixsize * (rrpart->crop + ((size_t)rrpart->crop) * tilex);
830 
831     copylen = tilex - 2 * rrpart->crop;
832     tiley -= 2 * rrpart->crop;
833 
834     ofs = (((size_t)rrpart->tilerect.ymin) + rrpart->crop) * rr->rectx +
835           (rrpart->tilerect.xmin + rrpart->crop);
836     target += pixsize * ofs;
837   }
838   else {
839     ofs = (((size_t)rrpart->tilerect.ymin) * rr->rectx + rrpart->tilerect.xmin);
840     target += pixsize * ofs;
841   }
842 
843   copylen *= sizeof(float) * pixsize;
844   tilex *= pixsize;
845   ofs = pixsize * rr->rectx;
846 
847   for (y = 0; y < tiley; y++) {
848     memcpy(target, tile, copylen);
849     target += ofs;
850     tile += tilex;
851   }
852 }
853 
854 /* used when rendering to a full buffer, or when reading the exr part-layer-pass file */
855 /* no test happens here if it fits... we also assume layers are in sync */
856 /* is used within threads */
render_result_merge(RenderResult * rr,RenderResult * rrpart)857 void render_result_merge(RenderResult *rr, RenderResult *rrpart)
858 {
859   RenderLayer *rl, *rlp;
860   RenderPass *rpass, *rpassp;
861 
862   for (rl = rr->layers.first; rl; rl = rl->next) {
863     rlp = RE_GetRenderLayer(rrpart, rl->name);
864     if (rlp) {
865       /* Passes are allocated in sync. */
866       for (rpass = rl->passes.first, rpassp = rlp->passes.first; rpass && rpassp;
867            rpass = rpass->next) {
868         /* For save buffers, skip any passes that are only saved to disk. */
869         if (rpass->rect == NULL || rpassp->rect == NULL) {
870           continue;
871         }
872         /* Renderresult have all passes, renderpart only the active view's passes. */
873         if (!STREQ(rpassp->fullname, rpass->fullname)) {
874           continue;
875         }
876 
877         do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, rpass->channels);
878 
879         /* manually get next render pass */
880         rpassp = rpassp->next;
881       }
882     }
883   }
884 }
885 
886 /* Called from the UI and render pipeline, to save multilayer and multiview
887  * images, optionally isolating a specific, view, layer or RGBA/Z pass. */
RE_WriteRenderResult(ReportList * reports,RenderResult * rr,const char * filename,ImageFormatData * imf,const char * view,int layer)888 bool RE_WriteRenderResult(ReportList *reports,
889                           RenderResult *rr,
890                           const char *filename,
891                           ImageFormatData *imf,
892                           const char *view,
893                           int layer)
894 {
895   void *exrhandle = IMB_exr_get_handle();
896   const bool half_float = (imf && imf->depth == R_IMF_CHAN_DEPTH_16);
897   const bool multi_layer = !(imf && imf->imtype == R_IMF_IMTYPE_OPENEXR);
898   const bool write_z = !multi_layer && (imf && (imf->flag & R_IMF_FLAG_ZBUF));
899 
900   /* Write first layer if not multilayer and no layer was specified. */
901   if (!multi_layer && layer == -1) {
902     layer = 0;
903   }
904 
905   /* First add views since IMB_exr_add_channel checks number of views. */
906   if (render_result_has_views(rr)) {
907     LISTBASE_FOREACH (RenderView *, rview, &rr->views) {
908       if (!view || STREQ(view, rview->name)) {
909         IMB_exr_add_view(exrhandle, rview->name);
910       }
911     }
912   }
913 
914   /* Compositing result. */
915   if (rr->have_combined) {
916     LISTBASE_FOREACH (RenderView *, rview, &rr->views) {
917       if (!rview->rectf) {
918         continue;
919       }
920 
921       const char *viewname = rview->name;
922       if (view) {
923         if (!STREQ(view, viewname)) {
924           continue;
925         }
926 
927         viewname = "";
928       }
929 
930       /* Skip compositing if only a single other layer is requested. */
931       if (!multi_layer && layer != 0) {
932         continue;
933       }
934 
935       for (int a = 0; a < 4; a++) {
936         char passname[EXR_PASS_MAXNAME];
937         char layname[EXR_PASS_MAXNAME];
938         const char *chan_id = "RGBA";
939 
940         if (multi_layer) {
941           set_pass_name(passname, "Combined", a, chan_id);
942           BLI_strncpy(layname, "Composite", sizeof(layname));
943         }
944         else {
945           passname[0] = chan_id[a];
946           passname[1] = '\0';
947           layname[0] = '\0';
948         }
949 
950         IMB_exr_add_channel(exrhandle,
951                             layname,
952                             passname,
953                             viewname,
954                             4,
955                             4 * rr->rectx,
956                             rview->rectf + a,
957                             half_float);
958       }
959 
960       if (write_z && rview->rectz) {
961         const char *layname = (multi_layer) ? "Composite" : "";
962         IMB_exr_add_channel(exrhandle, layname, "Z", viewname, 1, rr->rectx, rview->rectz, false);
963       }
964     }
965   }
966 
967   /* Other render layers. */
968   int nr = (rr->have_combined) ? 1 : 0;
969   for (RenderLayer *rl = rr->layers.first; rl; rl = rl->next, nr++) {
970     /* Skip other render layers if requested. */
971     if (!multi_layer && nr != layer) {
972       continue;
973     }
974 
975     LISTBASE_FOREACH (RenderPass *, rp, &rl->passes) {
976       /* Skip non-RGBA and Z passes if not using multi layer. */
977       if (!multi_layer && !(STREQ(rp->name, RE_PASSNAME_COMBINED) || STREQ(rp->name, "") ||
978                             (STREQ(rp->name, RE_PASSNAME_Z) && write_z))) {
979         continue;
980       }
981 
982       /* Skip pass if it does not match the requested view(s). */
983       const char *viewname = rp->view;
984       if (view) {
985         if (!STREQ(view, viewname)) {
986           continue;
987         }
988 
989         viewname = "";
990       }
991 
992       /* We only store RGBA passes as half float, for
993        * others precision loss can be problematic. */
994       bool pass_half_float = half_float &&
995                              (STREQ(rp->chan_id, "RGB") || STREQ(rp->chan_id, "RGBA") ||
996                               STREQ(rp->chan_id, "R") || STREQ(rp->chan_id, "G") ||
997                               STREQ(rp->chan_id, "B") || STREQ(rp->chan_id, "A"));
998 
999       for (int a = 0; a < rp->channels; a++) {
1000         /* Save Combined as RGBA if single layer save. */
1001         char passname[EXR_PASS_MAXNAME];
1002         char layname[EXR_PASS_MAXNAME];
1003 
1004         if (multi_layer) {
1005           set_pass_name(passname, rp->name, a, rp->chan_id);
1006           BLI_strncpy(layname, rl->name, sizeof(layname));
1007         }
1008         else {
1009           passname[0] = rp->chan_id[a];
1010           passname[1] = '\0';
1011           layname[0] = '\0';
1012         }
1013 
1014         IMB_exr_add_channel(exrhandle,
1015                             layname,
1016                             passname,
1017                             viewname,
1018                             rp->channels,
1019                             rp->channels * rr->rectx,
1020                             rp->rect + a,
1021                             pass_half_float);
1022       }
1023     }
1024   }
1025 
1026   errno = 0;
1027 
1028   BLI_make_existing_file(filename);
1029 
1030   int compress = (imf ? imf->exr_codec : 0);
1031   bool success = IMB_exr_begin_write(
1032       exrhandle, filename, rr->rectx, rr->recty, compress, rr->stamp_data);
1033   if (success) {
1034     IMB_exr_write_channels(exrhandle);
1035   }
1036   else {
1037     /* TODO, get the error from openexr's exception */
1038     BKE_reportf(
1039         reports, RPT_ERROR, "Error writing render result, %s (see console)", strerror(errno));
1040   }
1041 
1042   IMB_exr_close(exrhandle);
1043   return success;
1044 }
1045 
1046 /**************************** Single Layer Rendering *************************/
1047 
render_result_single_layer_begin(Render * re)1048 void render_result_single_layer_begin(Render *re)
1049 {
1050   /* all layers except the active one get temporally pushed away */
1051 
1052   /* officially pushed result should be NULL... error can happen with do_seq */
1053   RE_FreeRenderResult(re->pushedresult);
1054 
1055   re->pushedresult = re->result;
1056   re->result = NULL;
1057 }
1058 
1059 /* if scemode is R_SINGLE_LAYER, at end of rendering, merge the both render results */
render_result_single_layer_end(Render * re)1060 void render_result_single_layer_end(Render *re)
1061 {
1062   ViewLayer *view_layer;
1063   RenderLayer *rlpush;
1064   RenderLayer *rl;
1065   int nr;
1066 
1067   if (re->result == NULL) {
1068     printf("pop render result error; no current result!\n");
1069     return;
1070   }
1071 
1072   if (!re->pushedresult) {
1073     return;
1074   }
1075 
1076   if (re->pushedresult->rectx == re->result->rectx &&
1077       re->pushedresult->recty == re->result->recty) {
1078     /* find which layer in re->pushedresult should be replaced */
1079     rl = re->result->layers.first;
1080 
1081     /* render result should be empty after this */
1082     BLI_remlink(&re->result->layers, rl);
1083 
1084     /* reconstruct render result layers */
1085     for (nr = 0, view_layer = re->view_layers.first; view_layer;
1086          view_layer = view_layer->next, nr++) {
1087       if (nr == re->active_view_layer) {
1088         BLI_addtail(&re->result->layers, rl);
1089       }
1090       else {
1091         rlpush = RE_GetRenderLayer(re->pushedresult, view_layer->name);
1092         if (rlpush) {
1093           BLI_remlink(&re->pushedresult->layers, rlpush);
1094           BLI_addtail(&re->result->layers, rlpush);
1095         }
1096       }
1097     }
1098   }
1099 
1100   RE_FreeRenderResult(re->pushedresult);
1101   re->pushedresult = NULL;
1102 }
1103 
1104 /************************* EXR Tile File Rendering ***************************/
1105 
save_render_result_tile(RenderResult * rr,RenderResult * rrpart,const char * viewname)1106 static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart, const char *viewname)
1107 {
1108   RenderLayer *rlp, *rl;
1109   RenderPass *rpassp;
1110   int offs, partx, party;
1111 
1112   BLI_thread_lock(LOCK_IMAGE);
1113 
1114   for (rlp = rrpart->layers.first; rlp; rlp = rlp->next) {
1115     rl = RE_GetRenderLayer(rr, rlp->name);
1116 
1117     /* should never happen but prevents crash if it does */
1118     BLI_assert(rl);
1119     if (UNLIKELY(rl == NULL)) {
1120       continue;
1121     }
1122 
1123     if (rrpart->crop) { /* filters add pixel extra */
1124       offs = (rrpart->crop + rrpart->crop * rrpart->rectx);
1125     }
1126     else {
1127       offs = 0;
1128     }
1129 
1130     /* passes are allocated in sync */
1131     for (rpassp = rlp->passes.first; rpassp; rpassp = rpassp->next) {
1132       const int xstride = rpassp->channels;
1133       int a;
1134       char fullname[EXR_PASS_MAXNAME];
1135 
1136       for (a = 0; a < xstride; a++) {
1137         set_pass_full_name(fullname, rpassp->name, a, viewname, rpassp->chan_id);
1138 
1139         IMB_exr_set_channel(rl->exrhandle,
1140                             rlp->name,
1141                             fullname,
1142                             xstride,
1143                             xstride * rrpart->rectx,
1144                             rpassp->rect + a + xstride * offs);
1145       }
1146     }
1147   }
1148 
1149   party = rrpart->tilerect.ymin + rrpart->crop;
1150   partx = rrpart->tilerect.xmin + rrpart->crop;
1151 
1152   for (rlp = rrpart->layers.first; rlp; rlp = rlp->next) {
1153     rl = RE_GetRenderLayer(rr, rlp->name);
1154 
1155     /* should never happen but prevents crash if it does */
1156     BLI_assert(rl);
1157     if (UNLIKELY(rl == NULL)) {
1158       continue;
1159     }
1160 
1161     IMB_exrtile_write_channels(rl->exrhandle, partx, party, 0, viewname, false);
1162   }
1163 
1164   BLI_thread_unlock(LOCK_IMAGE);
1165 }
1166 
render_result_save_empty_result_tiles(Render * re)1167 void render_result_save_empty_result_tiles(Render *re)
1168 {
1169   RenderResult *rr;
1170   RenderLayer *rl;
1171 
1172   for (rr = re->result; rr; rr = rr->next) {
1173     for (rl = rr->layers.first; rl; rl = rl->next) {
1174       GHashIterator pa_iter;
1175       GHASH_ITER (pa_iter, re->parts) {
1176         RenderPart *pa = BLI_ghashIterator_getValue(&pa_iter);
1177         if (pa->status != PART_STATUS_MERGED) {
1178           int party = pa->disprect.ymin - re->disprect.ymin;
1179           int partx = pa->disprect.xmin - re->disprect.xmin;
1180           IMB_exrtile_write_channels(rl->exrhandle, partx, party, 0, re->viewname, true);
1181         }
1182       }
1183     }
1184   }
1185 }
1186 
1187 /* Compute list of passes needed by render engine. */
templates_register_pass_cb(void * userdata,Scene * UNUSED (scene),ViewLayer * UNUSED (view_layer),const char * name,int channels,const char * chan_id,eNodeSocketDatatype UNUSED (type))1188 static void templates_register_pass_cb(void *userdata,
1189                                        Scene *UNUSED(scene),
1190                                        ViewLayer *UNUSED(view_layer),
1191                                        const char *name,
1192                                        int channels,
1193                                        const char *chan_id,
1194                                        eNodeSocketDatatype UNUSED(type))
1195 {
1196   ListBase *templates = userdata;
1197   RenderPass *pass = MEM_callocN(sizeof(RenderPass), "RenderPassTemplate");
1198 
1199   pass->channels = channels;
1200   BLI_strncpy(pass->name, name, sizeof(pass->name));
1201   BLI_strncpy(pass->chan_id, chan_id, sizeof(pass->chan_id));
1202 
1203   BLI_addtail(templates, pass);
1204 }
1205 
render_result_get_pass_templates(RenderEngine * engine,Render * re,RenderLayer * rl,ListBase * templates)1206 static void render_result_get_pass_templates(RenderEngine *engine,
1207                                              Render *re,
1208                                              RenderLayer *rl,
1209                                              ListBase *templates)
1210 {
1211   BLI_listbase_clear(templates);
1212 
1213   if (engine && engine->type->update_render_passes) {
1214     ViewLayer *view_layer = BLI_findstring(&re->view_layers, rl->name, offsetof(ViewLayer, name));
1215     if (view_layer) {
1216       RE_engine_update_render_passes(
1217           engine, re->scene, view_layer, templates_register_pass_cb, templates);
1218     }
1219   }
1220 }
1221 
1222 /* begin write of exr tile file */
render_result_exr_file_begin(Render * re,RenderEngine * engine)1223 void render_result_exr_file_begin(Render *re, RenderEngine *engine)
1224 {
1225   char str[FILE_MAX];
1226 
1227   for (RenderResult *rr = re->result; rr; rr = rr->next) {
1228     LISTBASE_FOREACH (RenderLayer *, rl, &rr->layers) {
1229       /* Get passes needed by engine. Normally we would wait for the
1230        * engine to create them, but for EXR file we need to know in
1231        * advance. */
1232       ListBase templates;
1233       render_result_get_pass_templates(engine, re, rl, &templates);
1234 
1235       /* Create render passes requested by engine. Only this part is
1236        * mutex locked to avoid deadlock with Python GIL. */
1237       BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
1238       LISTBASE_FOREACH (RenderPass *, pass, &templates) {
1239         RE_create_render_pass(
1240             re->result, pass->name, pass->channels, pass->chan_id, rl->name, NULL);
1241       }
1242       BLI_rw_mutex_unlock(&re->resultmutex);
1243 
1244       BLI_freelistN(&templates);
1245 
1246       /* Open EXR file for writing. */
1247       render_result_exr_file_path(re->scene, rl->name, rr->sample_nr, str);
1248       printf("write exr tmp file, %dx%d, %s\n", rr->rectx, rr->recty, str);
1249       IMB_exrtile_begin_write(rl->exrhandle, str, 0, rr->rectx, rr->recty, re->partx, re->party);
1250     }
1251   }
1252 }
1253 
1254 /* end write of exr tile file, read back first sample */
render_result_exr_file_end(Render * re,RenderEngine * engine)1255 void render_result_exr_file_end(Render *re, RenderEngine *engine)
1256 {
1257   /* Close EXR files. */
1258   for (RenderResult *rr = re->result; rr; rr = rr->next) {
1259     LISTBASE_FOREACH (RenderLayer *, rl, &rr->layers) {
1260       IMB_exr_close(rl->exrhandle);
1261       rl->exrhandle = NULL;
1262     }
1263 
1264     rr->do_exr_tile = false;
1265   }
1266 
1267   /* Create new render result in memory instead of on disk. */
1268   BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
1269   render_result_free_list(&re->fullresult, re->result);
1270   re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS, RR_ALL_VIEWS);
1271   BLI_rw_mutex_unlock(&re->resultmutex);
1272 
1273   LISTBASE_FOREACH (RenderLayer *, rl, &re->result->layers) {
1274     /* Get passes needed by engine. */
1275     ListBase templates;
1276     render_result_get_pass_templates(engine, re, rl, &templates);
1277 
1278     /* Create render passes requested by engine. Only this part is
1279      * mutex locked to avoid deadlock with Python GIL. */
1280     BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
1281     LISTBASE_FOREACH (RenderPass *, pass, &templates) {
1282       RE_create_render_pass(re->result, pass->name, pass->channels, pass->chan_id, rl->name, NULL);
1283     }
1284 
1285     BLI_freelistN(&templates);
1286 
1287     /* Render passes contents from file. */
1288     char str[FILE_MAXFILE + MAX_ID_NAME + MAX_ID_NAME + 100] = "";
1289     render_result_exr_file_path(re->scene, rl->name, 0, str);
1290     printf("read exr tmp file: %s\n", str);
1291 
1292     if (!render_result_exr_file_read_path(re->result, rl, str)) {
1293       printf("cannot read: %s\n", str);
1294     }
1295     BLI_rw_mutex_unlock(&re->resultmutex);
1296   }
1297 }
1298 
1299 /* save part into exr file */
render_result_exr_file_merge(RenderResult * rr,RenderResult * rrpart,const char * viewname)1300 void render_result_exr_file_merge(RenderResult *rr, RenderResult *rrpart, const char *viewname)
1301 {
1302   for (; rr && rrpart; rr = rr->next, rrpart = rrpart->next) {
1303     save_render_result_tile(rr, rrpart, viewname);
1304   }
1305 }
1306 
1307 /* path to temporary exr file */
render_result_exr_file_path(Scene * scene,const char * layname,int sample,char * filepath)1308 void render_result_exr_file_path(Scene *scene, const char *layname, int sample, char *filepath)
1309 {
1310   char name[FILE_MAXFILE + MAX_ID_NAME + MAX_ID_NAME + 100];
1311   const char *fi = BLI_path_basename(BKE_main_blendfile_path_from_global());
1312 
1313   if (sample == 0) {
1314     BLI_snprintf(name, sizeof(name), "%s_%s_%s.exr", fi, scene->id.name + 2, layname);
1315   }
1316   else {
1317     BLI_snprintf(name, sizeof(name), "%s_%s_%s%d.exr", fi, scene->id.name + 2, layname, sample);
1318   }
1319 
1320   /* Make name safe for paths, see T43275. */
1321   BLI_filename_make_safe(name);
1322 
1323   BLI_join_dirfile(filepath, FILE_MAX, BKE_tempdir_session(), name);
1324 }
1325 
1326 /* called for reading temp files, and for external engines */
render_result_exr_file_read_path(RenderResult * rr,RenderLayer * rl_single,const char * filepath)1327 int render_result_exr_file_read_path(RenderResult *rr,
1328                                      RenderLayer *rl_single,
1329                                      const char *filepath)
1330 {
1331   RenderLayer *rl;
1332   RenderPass *rpass;
1333   void *exrhandle = IMB_exr_get_handle();
1334   int rectx, recty;
1335 
1336   if (IMB_exr_begin_read(exrhandle, filepath, &rectx, &recty) == 0) {
1337     printf("failed being read %s\n", filepath);
1338     IMB_exr_close(exrhandle);
1339     return 0;
1340   }
1341 
1342   if (rr == NULL || rectx != rr->rectx || recty != rr->recty) {
1343     if (rr) {
1344       printf("error in reading render result: dimensions don't match\n");
1345     }
1346     else {
1347       printf("error in reading render result: NULL result pointer\n");
1348     }
1349     IMB_exr_close(exrhandle);
1350     return 0;
1351   }
1352 
1353   for (rl = rr->layers.first; rl; rl = rl->next) {
1354     if (rl_single && rl_single != rl) {
1355       continue;
1356     }
1357 
1358     /* passes are allocated in sync */
1359     for (rpass = rl->passes.first; rpass; rpass = rpass->next) {
1360       const int xstride = rpass->channels;
1361       int a;
1362       char fullname[EXR_PASS_MAXNAME];
1363 
1364       for (a = 0; a < xstride; a++) {
1365         set_pass_full_name(fullname, rpass->name, a, rpass->view, rpass->chan_id);
1366         IMB_exr_set_channel(
1367             exrhandle, rl->name, fullname, xstride, xstride * rectx, rpass->rect + a);
1368       }
1369 
1370       set_pass_full_name(rpass->fullname, rpass->name, -1, rpass->view, rpass->chan_id);
1371     }
1372   }
1373 
1374   IMB_exr_read_channels(exrhandle);
1375   IMB_exr_close(exrhandle);
1376 
1377   return 1;
1378 }
1379 
render_result_exr_file_cache_path(Scene * sce,const char * root,char * r_path)1380 static void render_result_exr_file_cache_path(Scene *sce, const char *root, char *r_path)
1381 {
1382   char filename_full[FILE_MAX + MAX_ID_NAME + 100], filename[FILE_MAXFILE], dirname[FILE_MAXDIR];
1383   char path_digest[16] = {0};
1384   char path_hexdigest[33];
1385 
1386   /* If root is relative, use either current .blend file dir, or temp one if not saved. */
1387   const char *blendfile_path = BKE_main_blendfile_path_from_global();
1388   if (blendfile_path[0] != '\0') {
1389     BLI_split_dirfile(blendfile_path, dirname, filename, sizeof(dirname), sizeof(filename));
1390     BLI_path_extension_replace(filename, sizeof(filename), ""); /* strip '.blend' */
1391     BLI_hash_md5_buffer(blendfile_path, strlen(blendfile_path), path_digest);
1392   }
1393   else {
1394     BLI_strncpy(dirname, BKE_tempdir_base(), sizeof(dirname));
1395     BLI_strncpy(filename, "UNSAVED", sizeof(filename));
1396   }
1397   BLI_hash_md5_to_hexdigest(path_digest, path_hexdigest);
1398 
1399   /* Default to *non-volatile* tmp dir. */
1400   if (*root == '\0') {
1401     root = BKE_tempdir_base();
1402   }
1403 
1404   BLI_snprintf(filename_full,
1405                sizeof(filename_full),
1406                "cached_RR_%s_%s_%s.exr",
1407                filename,
1408                sce->id.name + 2,
1409                path_hexdigest);
1410   BLI_make_file_string(dirname, r_path, root, filename_full);
1411 }
1412 
render_result_exr_file_cache_write(Render * re)1413 void render_result_exr_file_cache_write(Render *re)
1414 {
1415   RenderResult *rr = re->result;
1416   char str[FILE_MAXFILE + FILE_MAXFILE + MAX_ID_NAME + 100];
1417   char *root = U.render_cachedir;
1418 
1419   render_result_exr_file_cache_path(re->scene, root, str);
1420   printf("Caching exr file, %dx%d, %s\n", rr->rectx, rr->recty, str);
1421 
1422   RE_WriteRenderResult(NULL, rr, str, NULL, NULL, -1);
1423 }
1424 
1425 /* For cache, makes exact copy of render result */
render_result_exr_file_cache_read(Render * re)1426 bool render_result_exr_file_cache_read(Render *re)
1427 {
1428   char str[FILE_MAXFILE + MAX_ID_NAME + MAX_ID_NAME + 100] = "";
1429   char *root = U.render_cachedir;
1430 
1431   RE_FreeRenderResult(re->result);
1432   re->result = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS, RR_ALL_VIEWS);
1433 
1434   /* First try cache. */
1435   render_result_exr_file_cache_path(re->scene, root, str);
1436 
1437   printf("read exr cache file: %s\n", str);
1438   if (!render_result_exr_file_read_path(re->result, NULL, str)) {
1439     printf("cannot read: %s\n", str);
1440     return false;
1441   }
1442   return true;
1443 }
1444 
1445 /*************************** Combined Pixel Rect *****************************/
1446 
render_result_rect_to_ibuf(RenderResult * rr,const RenderData * rd,const int view_id)1447 ImBuf *render_result_rect_to_ibuf(RenderResult *rr, const RenderData *rd, const int view_id)
1448 {
1449   ImBuf *ibuf = IMB_allocImBuf(rr->rectx, rr->recty, rd->im_format.planes, 0);
1450   RenderView *rv = RE_RenderViewGetById(rr, view_id);
1451 
1452   /* if not exists, BKE_imbuf_write makes one */
1453   ibuf->rect = (unsigned int *)rv->rect32;
1454   ibuf->rect_float = rv->rectf;
1455   ibuf->zbuf_float = rv->rectz;
1456 
1457   /* float factor for random dither, imbuf takes care of it */
1458   ibuf->dither = rd->dither_intensity;
1459 
1460   /* prepare to gamma correct to sRGB color space
1461    * note that sequence editor can generate 8bpc render buffers
1462    */
1463   if (ibuf->rect) {
1464     if (BKE_imtype_valid_depths(rd->im_format.imtype) &
1465         (R_IMF_CHAN_DEPTH_12 | R_IMF_CHAN_DEPTH_16 | R_IMF_CHAN_DEPTH_24 | R_IMF_CHAN_DEPTH_32)) {
1466       if (rd->im_format.depth == R_IMF_CHAN_DEPTH_8) {
1467         /* Higher depth bits are supported but not needed for current file output. */
1468         ibuf->rect_float = NULL;
1469       }
1470       else {
1471         IMB_float_from_rect(ibuf);
1472       }
1473     }
1474     else {
1475       /* ensure no float buffer remained from previous frame */
1476       ibuf->rect_float = NULL;
1477     }
1478   }
1479 
1480   /* color -> grayscale */
1481   /* editing directly would alter the render view */
1482   if (rd->im_format.planes == R_IMF_PLANES_BW) {
1483     ImBuf *ibuf_bw = IMB_dupImBuf(ibuf);
1484     IMB_color_to_bw(ibuf_bw);
1485     IMB_freeImBuf(ibuf);
1486     ibuf = ibuf_bw;
1487   }
1488 
1489   return ibuf;
1490 }
1491 
RE_render_result_rect_from_ibuf(RenderResult * rr,RenderData * UNUSED (rd),ImBuf * ibuf,const int view_id)1492 void RE_render_result_rect_from_ibuf(RenderResult *rr,
1493                                      RenderData *UNUSED(rd),
1494                                      ImBuf *ibuf,
1495                                      const int view_id)
1496 {
1497   RenderView *rv = RE_RenderViewGetById(rr, view_id);
1498 
1499   if (ibuf->rect_float) {
1500     rr->have_combined = true;
1501 
1502     if (!rv->rectf) {
1503       rv->rectf = MEM_mallocN(sizeof(float[4]) * rr->rectx * rr->recty, "render_seq rectf");
1504     }
1505 
1506     memcpy(rv->rectf, ibuf->rect_float, sizeof(float[4]) * rr->rectx * rr->recty);
1507 
1508     /* TSK! Since sequence render doesn't free the *rr render result, the old rect32
1509      * can hang around when sequence render has rendered a 32 bits one before */
1510     MEM_SAFE_FREE(rv->rect32);
1511   }
1512   else if (ibuf->rect) {
1513     rr->have_combined = true;
1514 
1515     if (!rv->rect32) {
1516       rv->rect32 = MEM_mallocN(sizeof(int) * rr->rectx * rr->recty, "render_seq rect");
1517     }
1518 
1519     memcpy(rv->rect32, ibuf->rect, 4 * rr->rectx * rr->recty);
1520 
1521     /* Same things as above, old rectf can hang around from previous render. */
1522     MEM_SAFE_FREE(rv->rectf);
1523   }
1524 }
1525 
render_result_rect_fill_zero(RenderResult * rr,const int view_id)1526 void render_result_rect_fill_zero(RenderResult *rr, const int view_id)
1527 {
1528   RenderView *rv = RE_RenderViewGetById(rr, view_id);
1529 
1530   if (rv->rectf) {
1531     memset(rv->rectf, 0, sizeof(float[4]) * rr->rectx * rr->recty);
1532   }
1533   else if (rv->rect32) {
1534     memset(rv->rect32, 0, 4 * rr->rectx * rr->recty);
1535   }
1536   else {
1537     rv->rect32 = MEM_callocN(sizeof(int) * rr->rectx * rr->recty, "render_seq rect");
1538   }
1539 }
1540 
render_result_rect_get_pixels(RenderResult * rr,unsigned int * rect,int rectx,int recty,const ColorManagedViewSettings * view_settings,const ColorManagedDisplaySettings * display_settings,const int view_id)1541 void render_result_rect_get_pixels(RenderResult *rr,
1542                                    unsigned int *rect,
1543                                    int rectx,
1544                                    int recty,
1545                                    const ColorManagedViewSettings *view_settings,
1546                                    const ColorManagedDisplaySettings *display_settings,
1547                                    const int view_id)
1548 {
1549   RenderView *rv = RE_RenderViewGetById(rr, view_id);
1550 
1551   if (rv && rv->rect32) {
1552     memcpy(rect, rv->rect32, sizeof(int) * rr->rectx * rr->recty);
1553   }
1554   else if (rv && rv->rectf) {
1555     IMB_display_buffer_transform_apply((unsigned char *)rect,
1556                                        rv->rectf,
1557                                        rr->rectx,
1558                                        rr->recty,
1559                                        4,
1560                                        view_settings,
1561                                        display_settings,
1562                                        true);
1563   }
1564   else {
1565     /* else fill with black */
1566     memset(rect, 0, sizeof(int) * rectx * recty);
1567   }
1568 }
1569 
1570 /*************************** multiview functions *****************************/
1571 
RE_HasCombinedLayer(RenderResult * rr)1572 bool RE_HasCombinedLayer(RenderResult *rr)
1573 {
1574   RenderView *rv;
1575 
1576   if (rr == NULL) {
1577     return false;
1578   }
1579 
1580   rv = rr->views.first;
1581   if (rv == NULL) {
1582     return false;
1583   }
1584 
1585   return (rv->rect32 || rv->rectf);
1586 }
1587 
RE_HasFloatPixels(RenderResult * rr)1588 bool RE_HasFloatPixels(RenderResult *rr)
1589 {
1590   RenderView *rview;
1591 
1592   for (rview = rr->views.first; rview; rview = rview->next) {
1593     if (rview->rect32 && !rview->rectf) {
1594       return false;
1595     }
1596   }
1597 
1598   return true;
1599 }
1600 
RE_RenderResult_is_stereo(RenderResult * rr)1601 bool RE_RenderResult_is_stereo(RenderResult *rr)
1602 {
1603   if (!BLI_findstring(&rr->views, STEREO_LEFT_NAME, offsetof(RenderView, name))) {
1604     return false;
1605   }
1606 
1607   if (!BLI_findstring(&rr->views, STEREO_RIGHT_NAME, offsetof(RenderView, name))) {
1608     return false;
1609   }
1610 
1611   return true;
1612 }
1613 
RE_RenderViewGetById(RenderResult * rr,const int view_id)1614 RenderView *RE_RenderViewGetById(RenderResult *rr, const int view_id)
1615 {
1616   RenderView *rv = BLI_findlink(&rr->views, view_id);
1617   BLI_assert(rr->views.first);
1618   return rv ? rv : rr->views.first;
1619 }
1620 
RE_RenderViewGetByName(RenderResult * rr,const char * viewname)1621 RenderView *RE_RenderViewGetByName(RenderResult *rr, const char *viewname)
1622 {
1623   RenderView *rv = BLI_findstring(&rr->views, viewname, offsetof(RenderView, name));
1624   BLI_assert(rr->views.first);
1625   return rv ? rv : rr->views.first;
1626 }
1627 
duplicate_render_pass(RenderPass * rpass)1628 static RenderPass *duplicate_render_pass(RenderPass *rpass)
1629 {
1630   RenderPass *new_rpass = MEM_mallocN(sizeof(RenderPass), "new render pass");
1631   *new_rpass = *rpass;
1632   new_rpass->next = new_rpass->prev = NULL;
1633   if (new_rpass->rect != NULL) {
1634     new_rpass->rect = MEM_dupallocN(new_rpass->rect);
1635   }
1636   return new_rpass;
1637 }
1638 
duplicate_render_layer(RenderLayer * rl)1639 static RenderLayer *duplicate_render_layer(RenderLayer *rl)
1640 {
1641   RenderLayer *new_rl = MEM_mallocN(sizeof(RenderLayer), "new render layer");
1642   *new_rl = *rl;
1643   new_rl->next = new_rl->prev = NULL;
1644   new_rl->passes.first = new_rl->passes.last = NULL;
1645   new_rl->exrhandle = NULL;
1646   for (RenderPass *rpass = rl->passes.first; rpass != NULL; rpass = rpass->next) {
1647     RenderPass *new_rpass = duplicate_render_pass(rpass);
1648     BLI_addtail(&new_rl->passes, new_rpass);
1649   }
1650   return new_rl;
1651 }
1652 
duplicate_render_view(RenderView * rview)1653 static RenderView *duplicate_render_view(RenderView *rview)
1654 {
1655   RenderView *new_rview = MEM_mallocN(sizeof(RenderView), "new render view");
1656   *new_rview = *rview;
1657   if (new_rview->rectf != NULL) {
1658     new_rview->rectf = MEM_dupallocN(new_rview->rectf);
1659   }
1660   if (new_rview->rectz != NULL) {
1661     new_rview->rectz = MEM_dupallocN(new_rview->rectz);
1662   }
1663   if (new_rview->rect32 != NULL) {
1664     new_rview->rect32 = MEM_dupallocN(new_rview->rect32);
1665   }
1666   return new_rview;
1667 }
1668 
RE_DuplicateRenderResult(RenderResult * rr)1669 RenderResult *RE_DuplicateRenderResult(RenderResult *rr)
1670 {
1671   RenderResult *new_rr = MEM_mallocN(sizeof(RenderResult), "new duplicated render result");
1672   *new_rr = *rr;
1673   new_rr->next = new_rr->prev = NULL;
1674   new_rr->layers.first = new_rr->layers.last = NULL;
1675   new_rr->views.first = new_rr->views.last = NULL;
1676   for (RenderLayer *rl = rr->layers.first; rl != NULL; rl = rl->next) {
1677     RenderLayer *new_rl = duplicate_render_layer(rl);
1678     BLI_addtail(&new_rr->layers, new_rl);
1679   }
1680   for (RenderView *rview = rr->views.first; rview != NULL; rview = rview->next) {
1681     RenderView *new_rview = duplicate_render_view(rview);
1682     BLI_addtail(&new_rr->views, new_rview);
1683   }
1684   if (new_rr->rect32 != NULL) {
1685     new_rr->rect32 = MEM_dupallocN(new_rr->rect32);
1686   }
1687   if (new_rr->rectf != NULL) {
1688     new_rr->rectf = MEM_dupallocN(new_rr->rectf);
1689   }
1690   if (new_rr->rectz != NULL) {
1691     new_rr->rectz = MEM_dupallocN(new_rr->rectz);
1692   }
1693   new_rr->stamp_data = BKE_stamp_data_copy(new_rr->stamp_data);
1694   return new_rr;
1695 }
1696