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