b04f1d3e738152c794b81f2d1886f178d843109b
[blender.git] / source / blender / editors / render / render_internal.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2008 Blender Foundation.
19  * All rights reserved.
20  *
21  *
22  * ***** END GPL LICENSE BLOCK *****
23  */
24
25 /** \file blender/editors/render/render_internal.c
26  *  \ingroup edrend
27  */
28
29
30 #include <math.h>
31 #include <string.h>
32 #include <stddef.h>
33
34 #include "MEM_guardedalloc.h"
35
36 #include "BLI_blenlib.h"
37 #include "BLI_math.h"
38 #include "BLI_threads.h"
39 #include "BLI_utildefines.h"
40
41 #include "PIL_time.h"
42
43 #include "BLF_translation.h"
44
45 #include "DNA_object_types.h"
46 #include "DNA_scene_types.h"
47 #include "DNA_view3d_types.h"
48 #include "DNA_userdef_types.h"
49
50 #include "BKE_blender.h"
51 #include "BKE_context.h"
52 #include "BKE_colortools.h"
53 #include "BKE_depsgraph.h"
54 #include "BKE_global.h"
55 #include "BKE_image.h"
56 #include "BKE_library.h"
57 #include "BKE_main.h"
58 #include "BKE_node.h"
59 #include "BKE_object.h"
60 #include "BKE_report.h"
61 #include "BKE_sequencer.h"
62 #include "BKE_screen.h"
63 #include "BKE_scene.h"
64
65 #include "WM_api.h"
66 #include "WM_types.h"
67
68 #include "ED_object.h"
69 #include "ED_render.h"
70 #include "ED_screen.h"
71 #include "ED_util.h"
72 #include "ED_view3d.h"
73
74 #include "RE_pipeline.h"
75 #include "RE_engine.h"
76
77 #include "IMB_colormanagement.h"
78 #include "IMB_imbuf_types.h"
79
80
81 #include "BIF_gl.h"
82 #include "BIF_glutil.h"
83
84 #include "RNA_access.h"
85 #include "RNA_define.h"
86
87
88 #include "render_intern.h"
89
90 /* Render Callbacks */
91 static int render_break(void *rjv);
92
93 typedef struct RenderJob {
94         Main *main;
95         Scene *scene;
96         Scene *current_scene;
97         Render *re;
98         SceneRenderLayer *srl;
99         struct Object *camera_override;
100         int lay_override;
101         bool v3d_override;
102         bool anim, write_still;
103         Image *image;
104         ImageUser iuser;
105         bool image_outdated;
106         short *stop;
107         short *do_update;
108         float *progress;
109         ReportList *reports;
110         int orig_layer;
111         int last_layer;
112         ScrArea *sa;
113         ColorManagedViewSettings view_settings;
114         ColorManagedDisplaySettings display_settings;
115         bool interface_locked;
116 } RenderJob;
117
118 /* called inside thread! */
119 static void image_buffer_rect_update(RenderJob *rj, RenderResult *rr, ImBuf *ibuf, ImageUser *iuser, volatile rcti *renrect)
120 {
121         Scene *scene = rj->scene;
122         const float *rectf = NULL;
123         int ymin, ymax, xmin, xmax;
124         int rymin, rxmin;
125         int linear_stride, linear_offset_x, linear_offset_y;
126         ColorManagedViewSettings *view_settings;
127         ColorManagedDisplaySettings *display_settings;
128
129         /* Exception for exr tiles -- display buffer conversion happens here,
130          * NOT in the color management pipeline.
131          */
132         if (ibuf->userflags & IB_DISPLAY_BUFFER_INVALID &&
133             rr->do_exr_tile == false)
134         {
135                 /* The whole image buffer it so be color managed again anyway. */
136                 return;
137         }
138
139         /* if renrect argument, we only refresh scanlines */
140         if (renrect) {
141                 /* if (ymax == recty), rendering of layer is ready, we should not draw, other things happen... */
142                 if (rr->renlay == NULL || renrect->ymax >= rr->recty)
143                         return;
144
145                 /* xmin here is first subrect x coord, xmax defines subrect width */
146                 xmin = renrect->xmin + rr->crop;
147                 xmax = renrect->xmax - xmin + rr->crop;
148                 if (xmax < 2)
149                         return;
150
151                 ymin = renrect->ymin + rr->crop;
152                 ymax = renrect->ymax - ymin + rr->crop;
153                 if (ymax < 2)
154                         return;
155                 renrect->ymin = renrect->ymax;
156
157         }
158         else {
159                 xmin = ymin = rr->crop;
160                 xmax = rr->rectx - 2 * rr->crop;
161                 ymax = rr->recty - 2 * rr->crop;
162         }
163
164         /* xmin ymin is in tile coords. transform to ibuf */
165         rxmin = rr->tilerect.xmin + xmin;
166         if (rxmin >= ibuf->x) return;
167         rymin = rr->tilerect.ymin + ymin;
168         if (rymin >= ibuf->y) return;
169
170         if (rxmin + xmax > ibuf->x)
171                 xmax = ibuf->x - rxmin;
172         if (rymin + ymax > ibuf->y)
173                 ymax = ibuf->y - rymin;
174
175         if (xmax < 1 || ymax < 1) return;
176
177         /* The thing here is, the logic below (which was default behavior
178          * of how rectf is acquiring since forever) gives float buffer for
179          * composite output only. This buffer can not be used for other
180          * passes obviously.
181          *
182          * We might try finding corresponding for pass buffer in render result
183          * (which is actually missing when rendering with Cycles, who only
184          * writes all the passes when the tile is finished) or use float
185          * buffer from image buffer as reference, which is easier to use and
186          * contains all the data we need anyway.
187          *                                              - sergey -
188          */
189         /* TODO(sergey): Need to check has_combined here? */
190         if (iuser->pass == 0) {
191                 /* find current float rect for display, first case is after composite... still weak */
192                 if (rr->rectf)
193                         rectf = rr->rectf;
194                 else {
195                         if (rr->rect32) {
196                                 /* special case, currently only happens with sequencer rendering,
197                                  * which updates the whole frame, so we can only mark display buffer
198                                  * as invalid here (sergey)
199                                  */
200                                 ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
201                                 return;
202                         }
203                         else {
204                                 if (rr->renlay == NULL || rr->renlay->rectf == NULL) return;
205                                 rectf = rr->renlay->rectf;
206                         }
207                 }
208                 if (rectf == NULL) return;
209
210                 rectf += 4 * (rr->rectx * ymin + xmin);
211                 linear_stride = rr->rectx;
212                 linear_offset_x = rxmin;
213                 linear_offset_y = rymin;
214         }
215         else {
216                 rectf = ibuf->rect_float;
217                 linear_stride = ibuf->x;
218                 linear_offset_x = 0;
219                 linear_offset_y = 0;
220         }
221
222         if (rr->do_exr_tile) {
223                 /* We don't support changing color management settings during rendering
224                  * when using Save Buffers option.
225                  */
226                 view_settings = &rj->view_settings;
227                 display_settings = &rj->display_settings;
228         }
229         else {
230                 view_settings = &scene->view_settings;
231                 display_settings = &scene->display_settings;
232         }
233
234         IMB_partial_display_buffer_update(ibuf, rectf, NULL,
235                                           linear_stride, linear_offset_x, linear_offset_y,
236                                           view_settings, display_settings,
237                                           rxmin, rymin, rxmin + xmax, rymin + ymax,
238                                           rr->do_exr_tile);
239 }
240
241 /* ****************************** render invoking ***************** */
242
243 /* set callbacks, exported to sequence render too.
244  * Only call in foreground (UI) renders. */
245
246 static void screen_render_scene_layer_set(wmOperator *op, Main *mainp, Scene **scene, SceneRenderLayer **srl)
247 {
248         /* single layer re-render */
249         if (RNA_struct_property_is_set(op->ptr, "scene")) {
250                 Scene *scn;
251                 char scene_name[MAX_ID_NAME - 2];
252
253                 RNA_string_get(op->ptr, "scene", scene_name);
254                 scn = (Scene *)BLI_findstring(&mainp->scene, scene_name, offsetof(ID, name) + 2);
255                 
256                 if (scn) {
257                         /* camera switch wont have updated */
258                         scn->r.cfra = (*scene)->r.cfra;
259                         BKE_scene_camera_switch_update(scn);
260
261                         *scene = scn;
262                 }
263         }
264
265         if (RNA_struct_property_is_set(op->ptr, "layer")) {
266                 SceneRenderLayer *rl;
267                 char rl_name[RE_MAXNAME];
268
269                 RNA_string_get(op->ptr, "layer", rl_name);
270                 rl = (SceneRenderLayer *)BLI_findstring(&(*scene)->r.layers, rl_name, offsetof(SceneRenderLayer, name));
271                 
272                 if (rl)
273                         *srl = rl;
274         }
275 }
276
277 /* executes blocking render */
278 static int screen_render_exec(bContext *C, wmOperator *op)
279 {
280         Scene *scene = CTX_data_scene(C);
281         SceneRenderLayer *srl = NULL;
282         Render *re;
283         Image *ima;
284         View3D *v3d = CTX_wm_view3d(C);
285         Main *mainp = CTX_data_main(C);
286         unsigned int lay_override;
287         const bool is_animation = RNA_boolean_get(op->ptr, "animation");
288         const bool is_write_still = RNA_boolean_get(op->ptr, "write_still");
289         struct Object *camera_override = v3d ? V3D_CAMERA_LOCAL(v3d) : NULL;
290
291         /* custom scene and single layer re-render */
292         screen_render_scene_layer_set(op, mainp, &scene, &srl);
293
294         if (!is_animation && is_write_still && BKE_imtype_is_movie(scene->r.im_format.imtype)) {
295                 BKE_report(op->reports, RPT_ERROR, "Cannot write a single file with an animation format selected");
296                 return OPERATOR_CANCELLED;
297         }
298
299         re = RE_NewRender(scene->id.name);
300         lay_override = (v3d && v3d->lay != scene->lay) ? v3d->lay : 0;
301
302         G.is_break = false;
303         RE_test_break_cb(re, NULL, render_break);
304
305         ima = BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result");
306         BKE_image_signal(ima, NULL, IMA_SIGNAL_FREE);
307         BKE_image_backup_render(scene, ima);
308
309         /* cleanup sequencer caches before starting user triggered render.
310          * otherwise, invalidated cache entries can make their way into
311          * the output rendering. We can't put that into RE_BlenderFrame,
312          * since sequence rendering can call that recursively... (peter) */
313         BKE_sequencer_cache_cleanup();
314
315         RE_SetReports(re, op->reports);
316
317         BLI_begin_threaded_malloc();
318         if (is_animation)
319                 RE_BlenderAnim(re, mainp, scene, camera_override, lay_override, scene->r.sfra, scene->r.efra, scene->r.frame_step);
320         else
321                 RE_BlenderFrame(re, mainp, scene, srl, camera_override, lay_override, scene->r.cfra, is_write_still);
322         BLI_end_threaded_malloc();
323
324         RE_SetReports(re, NULL);
325
326         // no redraw needed, we leave state as we entered it
327         ED_update_for_newframe(mainp, scene, 1);
328
329         WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene);
330
331         return OPERATOR_FINISHED;
332 }
333
334 static void render_freejob(void *rjv)
335 {
336         RenderJob *rj = rjv;
337
338         BKE_color_managed_view_settings_free(&rj->view_settings);
339         MEM_freeN(rj);
340 }
341
342 /* str is IMA_MAX_RENDER_TEXT in size */
343 static void make_renderinfo_string(const RenderStats *rs,
344                                    const Scene *scene,
345                                    const bool v3d_override,
346                                    const char *error,
347                                    char *str)
348 {
349         char info_time_str[32]; // used to be extern to header_info.c
350         uintptr_t mem_in_use, mmap_in_use, peak_memory;
351         float megs_used_memory, mmap_used_memory, megs_peak_memory;
352         char *spos = str;
353
354         mem_in_use = MEM_get_memory_in_use();
355         mmap_in_use = MEM_get_mapped_memory_in_use();
356         peak_memory = MEM_get_peak_memory();
357
358         megs_used_memory = (mem_in_use - mmap_in_use) / (1024.0 * 1024.0);
359         mmap_used_memory = (mmap_in_use) / (1024.0 * 1024.0);
360         megs_peak_memory = (peak_memory) / (1024.0 * 1024.0);
361
362         /* local view */
363         if (rs->localview)
364                 spos += sprintf(spos, "%s | ", IFACE_("3D Local View"));
365         else if (v3d_override)
366                 spos += sprintf(spos, "%s | ", IFACE_("3D View"));
367
368         /* frame number */
369         spos += sprintf(spos, IFACE_("Frame:%d "), (scene->r.cfra));
370
371         /* previous and elapsed time */
372         BLI_timestr(rs->lastframetime, info_time_str, sizeof(info_time_str));
373
374         if (rs->infostr && rs->infostr[0]) {
375                 if (rs->lastframetime != 0.0)
376                         spos += sprintf(spos, IFACE_("| Last:%s "), info_time_str);
377                 else
378                         spos += sprintf(spos, "| ");
379
380                 BLI_timestr(PIL_check_seconds_timer() - rs->starttime, info_time_str, sizeof(info_time_str));
381         }
382         else
383                 spos += sprintf(spos, "| ");
384
385         spos += sprintf(spos, IFACE_("Time:%s "), info_time_str);
386
387         /* statistics */
388         if (rs->statstr) {
389                 if (rs->statstr[0]) {
390                         spos += sprintf(spos, "| %s ", rs->statstr);
391                 }
392         }
393         else {
394                 if (rs->totvert || rs->totface || rs->tothalo || rs->totstrand || rs->totlamp)
395                         spos += sprintf(spos, "| ");
396
397                 if (rs->totvert) spos += sprintf(spos, IFACE_("Ve:%d "), rs->totvert);
398                 if (rs->totface) spos += sprintf(spos, IFACE_("Fa:%d "), rs->totface);
399                 if (rs->tothalo) spos += sprintf(spos, IFACE_("Ha:%d "), rs->tothalo);
400                 if (rs->totstrand) spos += sprintf(spos, IFACE_("St:%d "), rs->totstrand);
401                 if (rs->totlamp) spos += sprintf(spos, IFACE_("La:%d "), rs->totlamp);
402
403                 if (rs->mem_peak == 0.0f)
404                         spos += sprintf(spos, IFACE_("| Mem:%.2fM (%.2fM, Peak %.2fM) "),
405                                         megs_used_memory, mmap_used_memory, megs_peak_memory);
406                 else
407                         spos += sprintf(spos, IFACE_("| Mem:%.2fM, Peak: %.2fM "), rs->mem_used, rs->mem_peak);
408
409                 if (rs->curfield)
410                         spos += sprintf(spos, IFACE_("Field %d "), rs->curfield);
411                 if (rs->curblur)
412                         spos += sprintf(spos, IFACE_("Blur %d "), rs->curblur);
413         }
414
415         /* full sample */
416         if (rs->curfsa)
417                 spos += sprintf(spos, IFACE_("| Full Sample %d "), rs->curfsa);
418         
419         /* extra info */
420         if (rs->infostr && rs->infostr[0]) {
421                 spos += sprintf(spos, "| %s ", rs->infostr);
422         }
423         else if (error && error[0]) {
424                 spos += sprintf(spos, "| %s ", error);
425         }
426
427         /* very weak... but 512 characters is quite safe */
428         if (spos >= str + IMA_MAX_RENDER_TEXT)
429                 if (G.debug & G_DEBUG)
430                         printf("WARNING! renderwin text beyond limit\n");
431
432 }
433
434 static void image_renderinfo_cb(void *rjv, RenderStats *rs)
435 {
436         RenderJob *rj = rjv;
437         RenderResult *rr;
438
439         rr = RE_AcquireResultRead(rj->re);
440
441         if (rr) {
442                 /* malloc OK here, stats_draw is not in tile threads */
443                 if (rr->text == NULL)
444                         rr->text = MEM_callocN(IMA_MAX_RENDER_TEXT, "rendertext");
445
446                 make_renderinfo_string(rs, rj->scene, rj->v3d_override,
447                                        rr->error, rr->text);
448         }
449
450         RE_ReleaseResult(rj->re);
451
452         /* make jobs timer to send notifier */
453         *(rj->do_update) = true;
454
455 }
456
457 static void render_progress_update(void *rjv, float progress)
458 {
459         RenderJob *rj = rjv;
460         
461         if (rj->progress && *rj->progress != progress) {
462                 *rj->progress = progress;
463
464                 /* make jobs timer to send notifier */
465                 *(rj->do_update) = true;
466         }
467 }
468
469 /* Not totally reliable, but works fine in most of cases and
470  * in worst case would just make it so extra color management
471  * for the whole render result is applied (which was already
472  * happening already).
473  */
474 static void render_image_update_pass_and_layer(RenderJob *rj, RenderResult *rr, ImageUser *iuser)
475 {
476         wmWindowManager *wm;
477         ScrArea *first_sa = NULL, *matched_sa = NULL;
478
479         /* image window, compo node users */
480         for (wm = rj->main->wm.first; wm && matched_sa == NULL; wm = wm->id.next) { /* only 1 wm */
481                 wmWindow *win;
482                 for (win = wm->windows.first; win && matched_sa == NULL; win = win->next) {
483                         ScrArea *sa;
484                         for (sa = win->screen->areabase.first; sa; sa = sa->next) {
485                                 if (sa->spacetype == SPACE_IMAGE) {
486                                         SpaceImage *sima = sa->spacedata.first;
487                                         // sa->spacedata might be empty when toggling fullscreen mode.
488                                         if (sima != NULL && sima->image == rj->image) {
489                                                 if (first_sa == NULL) {
490                                                         first_sa = sa;
491                                                 }
492                                                 if (sa == rj->sa) {
493                                                         matched_sa = sa;
494                                                         break;
495                                                 }
496                                         }
497                                 }
498                         }
499                 }
500         }
501
502         if (matched_sa == NULL) {
503                 matched_sa = first_sa;
504         }
505
506         if (matched_sa) {
507                 SpaceImage *sima = matched_sa->spacedata.first;
508                 RenderResult *main_rr = RE_AcquireResultRead(rj->re);
509
510                 /* TODO(sergey): is there faster way to get the layer index? */
511                 if (rr->renlay) {
512                         int layer = BLI_findstringindex(&main_rr->layers,
513                                                         (char *)rr->renlay->name,
514                                                         offsetof(RenderLayer, name));
515                         if (layer != rj->last_layer) {
516                                 sima->iuser.layer = layer;
517                                 rj->last_layer = layer;
518                         }
519                 }
520
521                 iuser->pass = sima->iuser.pass;
522                 iuser->layer = sima->iuser.layer;
523
524                 RE_ReleaseResult(rj->re);
525         }
526 }
527
528 static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrect)
529 {
530         RenderJob *rj = rjv;
531         Image *ima = rj->image;
532         ImBuf *ibuf;
533         void *lock;
534
535         /* only update if we are displaying the slot being rendered */
536         if (ima->render_slot != ima->last_render_slot) {
537                 rj->image_outdated = true;
538                 return;
539         }
540         else if (rj->image_outdated) {
541                 /* update entire render */
542                 rj->image_outdated = false;
543                 BKE_image_signal(ima, NULL, IMA_SIGNAL_COLORMANAGE);
544                 *(rj->do_update) = true;
545                 return;
546         }
547         
548         if (rr == NULL)
549                 return;
550         
551         /* update part of render */
552         render_image_update_pass_and_layer(rj, rr, &rj->iuser);
553         ibuf = BKE_image_acquire_ibuf(ima, &rj->iuser, &lock);
554         if (ibuf) {
555                 /* Don't waste time on CPU side color management if
556                  * image will be displayed using GLSL.
557                  *
558                  * Need to update rect if Save Buffers enabled because in
559                  * this case GLSL doesn't have original float buffer to
560                  * operate with.
561                  */
562                 if (rr->do_exr_tile ||
563                     ibuf->channels == 1 ||
564                     U.image_draw_method != IMAGE_DRAW_METHOD_GLSL)
565                 {
566                         image_buffer_rect_update(rj, rr, ibuf, &rj->iuser, renrect);
567                 }
568                 
569                 /* make jobs timer to send notifier */
570                 *(rj->do_update) = true;
571         }
572         BKE_image_release_ibuf(ima, ibuf, lock);
573 }
574
575 static void current_scene_update(void *rjv, Scene *scene)
576 {
577         RenderJob *rj = rjv;
578         rj->current_scene = scene;
579         rj->iuser.scene = scene;
580 }
581
582 static void render_startjob(void *rjv, short *stop, short *do_update, float *progress)
583 {
584         RenderJob *rj = rjv;
585
586         rj->stop = stop;
587         rj->do_update = do_update;
588         rj->progress = progress;
589
590         RE_SetReports(rj->re, rj->reports);
591
592         if (rj->anim)
593                 RE_BlenderAnim(rj->re, rj->main, rj->scene, rj->camera_override, rj->lay_override, rj->scene->r.sfra, rj->scene->r.efra, rj->scene->r.frame_step);
594         else
595                 RE_BlenderFrame(rj->re, rj->main, rj->scene, rj->srl, rj->camera_override, rj->lay_override, rj->scene->r.cfra, rj->write_still);
596
597         RE_SetReports(rj->re, NULL);
598 }
599
600 static void render_image_restore_layer(RenderJob *rj)
601 {
602         wmWindowManager *wm;
603
604         /* image window, compo node users */
605         for (wm = rj->main->wm.first; wm; wm = wm->id.next) { /* only 1 wm */
606                 wmWindow *win;
607                 for (win = wm->windows.first; win; win = win->next) {
608                         ScrArea *sa;
609                         for (sa = win->screen->areabase.first; sa; sa = sa->next) {
610                                 if (sa == rj->sa) {
611                                         if (sa->spacetype == SPACE_IMAGE) {
612                                                 SpaceImage *sima = sa->spacedata.first;
613                                                 sima->iuser.layer = rj->orig_layer;
614                                         }
615                                         return;
616                                 }
617                         }
618                 }
619         }
620 }
621
622 static void render_endjob(void *rjv)
623 {
624         RenderJob *rj = rjv;
625
626         /* this render may be used again by the sequencer without the active 'Render' where the callbacks
627          * would be re-assigned. assign dummy callbacks to avoid referencing freed renderjobs bug [#24508] */
628         RE_InitRenderCB(rj->re);
629
630         if (rj->main != G.main)
631                 BKE_main_free(rj->main);
632
633         /* else the frame will not update for the original value */
634         if (rj->anim && !(rj->scene->r.scemode & R_NO_FRAME_UPDATE)) {
635                 /* possible this fails of loading new file while rendering */
636                 if (G.main->wm.first) {
637                         ED_update_for_newframe(G.main, rj->scene, 1);
638                 }
639         }
640         
641         /* XXX above function sets all tags in nodes */
642         ntreeCompositClearTags(rj->scene->nodetree);
643         
644         /* potentially set by caller */
645         rj->scene->r.scemode &= ~R_NO_FRAME_UPDATE;
646         
647         if (rj->srl) {
648                 nodeUpdateID(rj->scene->nodetree, &rj->scene->id);
649                 WM_main_add_notifier(NC_NODE | NA_EDITED, rj->scene);
650         }
651
652         if (rj->sa) {
653                 render_image_restore_layer(rj);
654         }
655
656         /* XXX render stability hack */
657         G.is_rendering = false;
658         WM_main_add_notifier(NC_SCENE | ND_RENDER_RESULT, NULL);
659
660         /* Partial render result will always update display buffer
661          * for first render layer only. This is nice because you'll
662          * see render progress during rendering, but it ends up in
663          * wrong display buffer shown after rendering.
664          *
665          * The code below will mark display buffer as invalid after
666          * rendering in case multiple layers were rendered, which
667          * ensures display buffer matches render layer after
668          * rendering.
669          *
670          * Perhaps proper way would be to toggle active render
671          * layer in image editor and job, so we always display
672          * layer being currently rendered. But this is not so much
673          * trivial at this moment, especially because of external
674          * engine API, so lets use simple and robust way for now
675          *                                          - sergey -
676          */
677         if (rj->scene->r.layers.first != rj->scene->r.layers.last ||
678             rj->image_outdated)
679         {
680                 void *lock;
681                 Image *ima = rj->image;
682                 ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &rj->iuser, &lock);
683
684                 if (ibuf)
685                         ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
686
687                 BKE_image_release_ibuf(ima, ibuf, lock);
688         }
689
690         /* Finally unlock the user interface (if it was locked). */
691         if (rj->interface_locked) {
692                 Scene *scene;
693
694                 /* Interface was locked, so window manager couldn't have been changed
695                  * and using one from Global will unlock exactly the same manager as
696                  * was locked before running the job.
697                  */
698                 WM_set_locked_interface(G.main->wm.first, false);
699
700                 /* We've freed all the derived caches before rendering, which is
701                  * effectively the same as if we re-loaded the file.
702                  *
703                  * So let's not try being smart here and just reset all updated
704                  * scene layers and use generic DAG_on_visible_update.
705                  */
706                 for (scene = G.main->scene.first; scene; scene = scene->id.next) {
707                         scene->lay_updated = 0;
708                 }
709
710                 DAG_on_visible_update(G.main, false);
711         }
712 }
713
714 /* called by render, check job 'stop' value or the global */
715 static int render_breakjob(void *rjv)
716 {
717         RenderJob *rj = rjv;
718
719         if (G.is_break)
720                 return 1;
721         if (rj->stop && *(rj->stop))
722                 return 1;
723         return 0;
724 }
725
726 /* for exec() when there is no render job
727  * note: this wont check for the escape key being pressed, but doing so isnt threadsafe */
728 static int render_break(void *UNUSED(rjv))
729 {
730         if (G.is_break)
731                 return 1;
732         return 0;
733 }
734
735 /* runs in thread, no cursor setting here works. careful with notifiers too (malloc conflicts) */
736 /* maybe need a way to get job send notifer? */
737 static void render_drawlock(void *rjv, int lock)
738 {
739         RenderJob *rj = rjv;
740
741         /* If interface is locked, renderer callback shall do nothing. */
742         if (!rj->interface_locked) {
743                 BKE_spacedata_draw_locks(lock);
744         }
745 }
746
747 /* catch esc */
748 static int screen_render_modal(bContext *C, wmOperator *op, const wmEvent *event)
749 {
750         Scene *scene = (Scene *) op->customdata;
751
752         /* no running blender, remove handler and pass through */
753         if (0 == WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_RENDER)) {
754                 return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
755         }
756
757         /* running render */
758         switch (event->type) {
759                 case ESCKEY:
760                         return OPERATOR_RUNNING_MODAL;
761         }
762         return OPERATOR_PASS_THROUGH;
763 }
764
765 static void screen_render_cancel(bContext *C, wmOperator *op)
766 {
767         wmWindowManager *wm = CTX_wm_manager(C);
768         Scene *scene = (Scene *) op->customdata;
769
770         /* kill on cancel, because job is using op->reports */
771         WM_jobs_kill_type(wm, scene, WM_JOB_TYPE_RENDER);
772 }
773
774 static void clean_viewport_memory(Main *bmain, Scene *scene, int renderlay)
775 {
776         Object *object;
777         Scene *sce_iter;
778         Base *base;
779
780         for (object = bmain->object.first; object; object = object->id.next) {
781                 object->id.flag |= LIB_DOIT;
782         }
783
784         for (SETLOOPER(scene, sce_iter, base)) {
785                 if ((base->lay & renderlay) == 0) {
786                         continue;
787                 }
788
789                 if (RE_allow_render_generic_object(base->object)) {
790                         base->object->id.flag &= ~LIB_DOIT;
791                 }
792         }
793
794         for (object = bmain->object.first; object; object = object->id.next) {
795                 if ((object->id.flag & LIB_DOIT) == 0) {
796                         continue;
797                 }
798                 object->id.flag &= ~LIB_DOIT;
799
800                 BKE_object_free_derived_caches(object);
801         }
802 }
803
804 /* using context, starts job */
805 static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *event)
806 {
807         /* new render clears all callbacks */
808         Main *mainp;
809         Scene *scene = CTX_data_scene(C);
810         SceneRenderLayer *srl = NULL;
811         Render *re;
812         wmJob *wm_job;
813         RenderJob *rj;
814         Image *ima;
815         int jobflag;
816         const bool is_animation = RNA_boolean_get(op->ptr, "animation");
817         const bool is_write_still = RNA_boolean_get(op->ptr, "write_still");
818         const bool use_viewport = RNA_boolean_get(op->ptr, "use_viewport");
819         View3D *v3d = use_viewport ? CTX_wm_view3d(C) : NULL;
820         struct Object *camera_override = v3d ? V3D_CAMERA_LOCAL(v3d) : NULL;
821         const char *name;
822         ScrArea *sa;
823         
824         /* only one render job at a time */
825         if (WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_RENDER))
826                 return OPERATOR_CANCELLED;
827
828         if (RE_force_single_renderlayer(scene))
829                 WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, NULL);
830
831         if (!RE_is_rendering_allowed(scene, camera_override, op->reports)) {
832                 return OPERATOR_CANCELLED;
833         }
834
835         if (!is_animation && is_write_still && BKE_imtype_is_movie(scene->r.im_format.imtype)) {
836                 BKE_report(op->reports, RPT_ERROR, "Cannot write a single file with an animation format selected");
837                 return OPERATOR_CANCELLED;
838         }
839         
840         /* stop all running jobs, except screen one. currently previews frustrate Render */
841         WM_jobs_kill_all_except(CTX_wm_manager(C), CTX_wm_screen(C));
842
843         /* get main */
844         if (G.debug_value == 101) {
845                 /* thread-safety experiment, copy main from the undo buffer */
846                 mainp = BKE_undo_get_main(&scene);
847         }
848         else
849                 mainp = CTX_data_main(C);
850
851         /* cancel animation playback */
852         if (ED_screen_animation_playing(CTX_wm_manager(C)))
853                 ED_screen_animation_play(C, 0, 0);
854         
855         /* handle UI stuff */
856         WM_cursor_wait(1);
857
858         /* flush sculpt and editmode changes */
859         ED_editors_flush_edits(C, true);
860
861         /* cleanup sequencer caches before starting user triggered render.
862          * otherwise, invalidated cache entries can make their way into
863          * the output rendering. We can't put that into RE_BlenderFrame,
864          * since sequence rendering can call that recursively... (peter) */
865         BKE_sequencer_cache_cleanup();
866
867         // store spare
868         // get view3d layer, local layer, make this nice api call to render
869         // store spare
870
871         /* ensure at least 1 area shows result */
872         sa = render_view_open(C, event->x, event->y);
873
874         jobflag = WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS;
875         
876         /* custom scene and single layer re-render */
877         screen_render_scene_layer_set(op, mainp, &scene, &srl);
878
879         if (RNA_struct_property_is_set(op->ptr, "layer"))
880                 jobflag |= WM_JOB_SUSPEND;
881
882         /* job custom data */
883         rj = MEM_callocN(sizeof(RenderJob), "render job");
884         rj->main = mainp;
885         rj->scene = scene;
886         rj->current_scene = rj->scene;
887         rj->srl = srl;
888         rj->camera_override = camera_override;
889         rj->lay_override = 0;
890         rj->anim = is_animation;
891         rj->write_still = is_write_still && !is_animation;
892         rj->iuser.scene = scene;
893         rj->iuser.ok = 1;
894         rj->reports = op->reports;
895         rj->orig_layer = 0;
896         rj->last_layer = 0;
897         rj->sa = sa;
898
899         BKE_color_managed_display_settings_copy(&rj->display_settings, &scene->display_settings);
900         BKE_color_managed_view_settings_copy(&rj->view_settings, &scene->view_settings);
901
902         if (sa) {
903                 SpaceImage *sima = sa->spacedata.first;
904                 rj->orig_layer = sima->iuser.layer;
905         }
906
907         if (v3d) {
908                 if (scene->lay != v3d->lay) {
909                         rj->lay_override = v3d->lay;
910                         rj->v3d_override = true;
911                 }
912                 else if (camera_override && camera_override != scene->camera)
913                         rj->v3d_override = true;
914
915                 if (v3d->localvd)
916                         rj->lay_override |= v3d->localvd->lay;
917         }
918
919         /* Lock the user interface depending on render settings. */
920         if (scene->r.use_lock_interface) {
921                 int renderlay = rj->lay_override ? rj->lay_override : scene->lay;
922
923                 WM_set_locked_interface(CTX_wm_manager(C), true);
924
925                 /* Set flag interface need to be unlocked.
926                  *
927                  * This is so because we don't have copy of render settings
928                  * accessible from render job and copy is needed in case
929                  * of non-locked rendering, so we wouldn't try to unlock
930                  * anything if option was initially unset but then was
931                  * enabled during rendering.
932                  */
933                 rj->interface_locked = true;
934
935                 /* Clean memory used by viewport? */
936                 clean_viewport_memory(rj->main, scene, renderlay);
937         }
938
939         /* setup job */
940         if (RE_seq_render_active(scene, &scene->r)) name = "Sequence Render";
941         else name = "Render";
942
943         wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, name, jobflag, WM_JOB_TYPE_RENDER);
944         WM_jobs_customdata_set(wm_job, rj, render_freejob);
945         WM_jobs_timer(wm_job, 0.2, NC_SCENE | ND_RENDER_RESULT, 0);
946         WM_jobs_callbacks(wm_job, render_startjob, NULL, NULL, render_endjob);
947
948         /* get a render result image, and make sure it is empty */
949         ima = BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result");
950         BKE_image_signal(ima, NULL, IMA_SIGNAL_FREE);
951         BKE_image_backup_render(rj->scene, ima);
952         rj->image = ima;
953
954         /* setup new render */
955         re = RE_NewRender(scene->id.name);
956         RE_test_break_cb(re, rj, render_breakjob);
957         RE_draw_lock_cb(re, rj, render_drawlock);
958         RE_display_update_cb(re, rj, image_rect_update);
959         RE_current_scene_update_cb(re, rj, current_scene_update);
960         RE_stats_draw_cb(re, rj, image_renderinfo_cb);
961         RE_progress_cb(re, rj, render_progress_update);
962
963         rj->re = re;
964         G.is_break = false;
965
966         /* store actual owner of job, so modal operator could check for it,
967          * the reason of this is that active scene could change when rendering
968          * several layers from compositor [#31800]
969          */
970         op->customdata = scene;
971
972         WM_jobs_start(CTX_wm_manager(C), wm_job);
973
974         WM_cursor_wait(0);
975         WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene);
976
977         /* we set G.is_rendering here already instead of only in the job, this ensure
978          * main loop or other scene updates are disabled in time, since they may
979          * have started before the job thread */
980         G.is_rendering = true;
981
982         /* add modal handler for ESC */
983         WM_event_add_modal_handler(C, op);
984
985         return OPERATOR_RUNNING_MODAL;
986 }
987
988 /* contextual render, using current scene, view3d? */
989 void RENDER_OT_render(wmOperatorType *ot)
990 {
991         PropertyRNA *prop;
992
993         /* identifiers */
994         ot->name = "Render";
995         ot->description = "Render active scene";
996         ot->idname = "RENDER_OT_render";
997
998         /* api callbacks */
999         ot->invoke = screen_render_invoke;
1000         ot->modal = screen_render_modal;
1001         ot->cancel = screen_render_cancel;
1002         ot->exec = screen_render_exec;
1003
1004         /*ot->poll = ED_operator_screenactive;*/ /* this isn't needed, causes failer in background mode */
1005
1006         RNA_def_boolean(ot->srna, "animation", 0, "Animation", "Render files from the animation range of this scene");
1007         RNA_def_boolean(ot->srna, "write_still", 0, "Write Image", "Save rendered the image to the output path (used only when animation is disabled)");
1008         RNA_def_boolean(ot->srna, "use_viewport", 0, "Use 3D Viewport", "When inside a 3D viewport, use layers and camera of the viewport");
1009         prop = RNA_def_string(ot->srna, "layer", NULL, RE_MAXNAME, "Render Layer", "Single render layer to re-render (used only when animation is disabled)");
1010         RNA_def_property_flag(prop, PROP_SKIP_SAVE);
1011         prop = RNA_def_string(ot->srna, "scene", NULL, MAX_ID_NAME - 2, "Scene", "Scene to render, current scene if not specified");
1012         RNA_def_property_flag(prop, PROP_SKIP_SAVE);
1013 }
1014
1015
1016 /* ************** preview for 3d viewport ***************** */
1017
1018 #define PR_UPDATE_VIEW                          1
1019 #define PR_UPDATE_RENDERSIZE            2
1020 #define PR_UPDATE_MATERIAL                      4
1021 #define PR_UPDATE_DATABASE                      8
1022
1023 typedef struct RenderPreview {
1024         /* from wmJob */
1025         void *owner;
1026         short *stop, *do_update;
1027         wmJob *job;
1028         
1029         Scene *scene;
1030         ScrArea *sa;
1031         ARegion *ar;
1032         View3D *v3d;
1033         RegionView3D *rv3d;
1034         Main *bmain;
1035         RenderEngine *engine;
1036         
1037         float viewmat[4][4];
1038
1039         int start_resolution_divider;
1040         int resolution_divider;
1041         bool has_freestyle;
1042 } RenderPreview;
1043
1044 static int render_view3d_disprect(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, rcti *disprect)
1045 {
1046         /* copied code from view3d_draw.c */
1047         rctf viewborder;
1048         int draw_border;
1049         
1050         if (rv3d->persp == RV3D_CAMOB)
1051                 draw_border = (scene->r.mode & R_BORDER) != 0;
1052         else
1053                 draw_border = (v3d->flag2 & V3D_RENDER_BORDER) != 0;
1054
1055         if (draw_border) {
1056                 if (rv3d->persp == RV3D_CAMOB) {
1057                         ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, false);
1058                         
1059                         disprect->xmin = viewborder.xmin + scene->r.border.xmin * BLI_rctf_size_x(&viewborder);
1060                         disprect->ymin = viewborder.ymin + scene->r.border.ymin * BLI_rctf_size_y(&viewborder);
1061                         disprect->xmax = viewborder.xmin + scene->r.border.xmax * BLI_rctf_size_x(&viewborder);
1062                         disprect->ymax = viewborder.ymin + scene->r.border.ymax * BLI_rctf_size_y(&viewborder);
1063                 }
1064                 else {
1065                         disprect->xmin = v3d->render_border.xmin * ar->winx;
1066                         disprect->xmax = v3d->render_border.xmax * ar->winx;
1067                         disprect->ymin = v3d->render_border.ymin * ar->winy;
1068                         disprect->ymax = v3d->render_border.ymax * ar->winy;
1069                 }
1070                 
1071                 return 1;
1072         }
1073         
1074         BLI_rcti_init(disprect, 0, 0, 0, 0);
1075         return 0;
1076 }
1077
1078 /* returns true if OK  */
1079 static bool render_view3d_get_rects(ARegion *ar, View3D *v3d, RegionView3D *rv3d, rctf *viewplane, RenderEngine *engine,
1080                                     float *r_clipsta, float *r_clipend, float *r_pixsize, bool *r_ortho)
1081 {
1082         
1083         if (ar->winx < 4 || ar->winy < 4) return false;
1084         
1085         *r_ortho = ED_view3d_viewplane_get(v3d, rv3d, ar->winx, ar->winy, viewplane, r_clipsta, r_clipend, r_pixsize);
1086         
1087         engine->resolution_x = ar->winx;
1088         engine->resolution_y = ar->winy;
1089
1090         return true;
1091 }
1092
1093 static bool render_view3d_is_valid(RenderPreview *rp)
1094 {
1095         return (rp->rv3d->render_engine != NULL);
1096 }
1097
1098 /* called by renderer, checks job value */
1099 static int render_view3d_break(void *rpv)
1100 {
1101         RenderPreview *rp = rpv;
1102         
1103         if (G.is_break)
1104                 return 1;
1105         
1106         /* during render, rv3d->engine can get freed */
1107         if (render_view3d_is_valid(rp) == false) {
1108                 *rp->stop = 1;
1109         }
1110         
1111         return *(rp->stop);
1112 }
1113
1114 static void render_view3d_display_update(void *rpv, RenderResult *UNUSED(rr), volatile struct rcti *UNUSED(rect))
1115 {
1116         RenderPreview *rp = rpv;
1117         
1118         *(rp->do_update) = true;
1119 }
1120
1121 static void render_view3d_renderinfo_cb(void *rjp, RenderStats *rs)
1122 {
1123         RenderPreview *rp = rjp;
1124
1125         /* during render, rv3d->engine can get freed */
1126         if (rp->rv3d->render_engine == NULL) {
1127                 *rp->stop = 1;
1128         }
1129         else {
1130                 make_renderinfo_string(rs, rp->scene, false, NULL, rp->engine->text);
1131         
1132                 /* make jobs timer to send notifier */
1133                 *(rp->do_update) = true;
1134         }
1135 }
1136
1137 BLI_INLINE void rcti_scale_coords(rcti *scaled_rect, const rcti *rect,
1138                                   const float scale)
1139 {
1140         scaled_rect->xmin = rect->xmin * scale;
1141         scaled_rect->ymin = rect->ymin * scale;
1142         scaled_rect->xmax = rect->xmax * scale;
1143         scaled_rect->ymax = rect->ymax * scale;
1144 }
1145
1146 static void render_update_resolution(Render *re, const RenderPreview *rp,
1147                                      bool use_border, const rcti *clip_rect)
1148 {
1149         int winx = rp->ar->winx / rp->resolution_divider,
1150             winy = rp->ar->winy / rp->resolution_divider;
1151         if (use_border) {
1152                 rcti scaled_cliprct;
1153                 rcti_scale_coords(&scaled_cliprct, clip_rect,
1154                                   1.0f / rp->resolution_divider);
1155                 RE_ChangeResolution(re, winx, winy, &scaled_cliprct);
1156         }
1157         else {
1158                 RE_ChangeResolution(re, winx, winy, NULL);
1159         }
1160
1161         if (rp->has_freestyle) {
1162                 if (rp->resolution_divider == 1) {
1163                         RE_ChangeModeFlag(re, R_EDGE_FRS, false);
1164                 }
1165                 else {
1166                         RE_ChangeModeFlag(re, R_EDGE_FRS, true);
1167                 }
1168         }
1169 }
1170
1171 static void render_view3d_startjob(void *customdata, short *stop, short *do_update, float *UNUSED(progress))
1172 {
1173         RenderPreview *rp = customdata;
1174         Render *re;
1175         RenderStats *rstats;
1176         rctf viewplane;
1177         rcti cliprct;
1178         float clipsta, clipend, pixsize;
1179         bool orth, restore = 0;
1180         char name[32];
1181         int update_flag;
1182         bool use_border;
1183
1184         update_flag = rp->engine->job_update_flag;
1185         rp->engine->job_update_flag = 0;
1186
1187         //printf("ma %d res %d view %d db %d\n", update_flag & PR_UPDATE_MATERIAL, update_flag & PR_UPDATE_RENDERSIZE, update_flag & PR_UPDATE_VIEW, update_flag & PR_UPDATE_DATABASE);
1188
1189         G.is_break = false;
1190         
1191         if (false == render_view3d_get_rects(rp->ar, rp->v3d, rp->rv3d, &viewplane, rp->engine, &clipsta, &clipend, &pixsize, &orth))
1192                 return;
1193         
1194         rp->stop = stop;
1195         rp->do_update = do_update;
1196
1197         // printf("Enter previewrender\n");
1198         
1199         /* ok, are we rendering all over? */
1200         sprintf(name, "View3dPreview %p", (void *)rp->ar);
1201         re = rp->engine->re = RE_GetRender(name);
1202         
1203         /* set this always, rp is different for each job */
1204         RE_test_break_cb(re, rp, render_view3d_break);
1205         RE_display_update_cb(re, rp, render_view3d_display_update);
1206         RE_stats_draw_cb(re, rp, render_view3d_renderinfo_cb);
1207         
1208         rstats = RE_GetStats(re);
1209
1210         if (update_flag & PR_UPDATE_VIEW) {
1211                 Object *object;
1212                 rp->resolution_divider = rp->start_resolution_divider;
1213
1214                 /* Same as database_init_objects(), loop over all objects.
1215                  * We might consider de-duplicating the code between this two cases.
1216                  */
1217                 for (object = rp->bmain->object.first; object; object = object->id.next) {
1218                         float mat[4][4];
1219                         mul_m4_m4m4(mat, rp->viewmat, object->obmat);
1220                         invert_m4_m4(object->imat_ren, mat);
1221                 }
1222         }
1223
1224         use_border = render_view3d_disprect(rp->scene, rp->ar, rp->v3d,
1225                                             rp->rv3d, &cliprct);
1226
1227         if ((update_flag & (PR_UPDATE_RENDERSIZE | PR_UPDATE_DATABASE)) || rstats->convertdone == 0) {
1228                 RenderData rdata;
1229
1230                 /* no osa, blur, seq, layers, etc for preview render */
1231                 rdata = rp->scene->r;
1232                 rdata.mode &= ~(R_OSA | R_MBLUR | R_BORDER | R_PANORAMA);
1233                 rdata.scemode &= ~(R_DOSEQ | R_DOCOMP | R_FREE_IMAGE);
1234                 rdata.scemode |= R_VIEWPORT_PREVIEW;
1235
1236                 /* we do use layers, but only active */
1237                 rdata.scemode |= R_SINGLE_LAYER;
1238
1239                 /* initalize always */
1240                 if (use_border) {
1241                         rdata.mode |= R_BORDER;
1242                         RE_InitState(re, NULL, &rdata, NULL, rp->ar->winx, rp->ar->winy, &cliprct);
1243                 }
1244                 else
1245                         RE_InitState(re, NULL, &rdata, NULL, rp->ar->winx, rp->ar->winy, NULL);
1246         }
1247
1248         if (orth)
1249                 RE_SetOrtho(re, &viewplane, clipsta, clipend);
1250         else
1251                 RE_SetWindow(re, &viewplane, clipsta, clipend);
1252
1253         RE_SetPixelSize(re, pixsize);
1254         
1255         if ((update_flag & PR_UPDATE_DATABASE) || rstats->convertdone == 0) {
1256                 unsigned int lay = rp->scene->lay;
1257
1258                 /* allow localview render for objects with lights in normal layers */
1259                 if (rp->v3d->lay & 0xFF000000)
1260                         lay |= rp->v3d->lay;
1261                 else lay = rp->v3d->lay;
1262                 
1263                 RE_SetView(re, rp->viewmat);
1264
1265                 /* copying blender data while main thread is locked, to avoid crashes */
1266                 WM_job_main_thread_lock_acquire(rp->job);
1267                 RE_Database_Free(re);
1268                 RE_Database_FromScene(re, rp->bmain, rp->scene, lay, 0);                // 0= dont use camera view
1269                 WM_job_main_thread_lock_release(rp->job);
1270
1271                 /* do preprocessing like building raytree, shadows, volumes, SSS */
1272                 RE_Database_Preprocess(re);
1273
1274                 /* conversion not completed, need to do it again */
1275                 if (!rstats->convertdone) {
1276                         if (render_view3d_is_valid(rp)) {
1277                                 rp->engine->job_update_flag |= PR_UPDATE_DATABASE;
1278                         }
1279                 }
1280
1281                 // printf("dbase update\n");
1282         }
1283         else {
1284                 // printf("dbase rotate\n");
1285                 RE_DataBase_IncrementalView(re, rp->viewmat, 0);
1286                 restore = 1;
1287         }
1288
1289         RE_DataBase_ApplyWindow(re);
1290
1291         /* OK, can we enter render code? */
1292         if (rstats->convertdone) {
1293                 bool first_time = true;
1294                 for (;;) {
1295                         if (first_time == false) {
1296                                 if (restore)
1297                                         RE_DataBase_IncrementalView(re, rp->viewmat, 1);
1298
1299                                 rp->resolution_divider /= 2;
1300                                 *do_update = 1;
1301
1302                                 render_update_resolution(re, rp, use_border, &cliprct);
1303
1304                                 RE_DataBase_IncrementalView(re, rp->viewmat, 0);
1305                                 RE_DataBase_ApplyWindow(re);
1306                                 restore = 1;
1307                         }
1308                         else {
1309                                 render_update_resolution(re, rp, use_border, &cliprct);
1310                         }
1311
1312                         RE_TileProcessor(re);
1313
1314                         first_time = false;
1315
1316                         if (*stop || rp->resolution_divider == 1) {
1317                                 break;
1318                         }
1319                 }
1320
1321                 /* always rotate back */
1322                 if (restore)
1323                         RE_DataBase_IncrementalView(re, rp->viewmat, 1);
1324         }
1325 }
1326
1327 static void render_view3d_free(void *customdata)
1328 {
1329         RenderPreview *rp = customdata;
1330         
1331         MEM_freeN(rp);
1332 }
1333
1334 static bool render_view3d_flag_changed(RenderEngine *engine, const bContext *C)
1335 {
1336         RegionView3D *rv3d = CTX_wm_region_view3d(C);
1337         View3D *v3d = CTX_wm_view3d(C);
1338         ARegion *ar = CTX_wm_region(C);
1339         Scene *scene = CTX_data_scene(C);
1340         Render *re;
1341         rctf viewplane;
1342         rcti disprect;
1343         float clipsta, clipend;
1344         bool orth;
1345         int job_update_flag = 0;
1346         char name[32];
1347         
1348         /* ensure render engine exists */
1349         re = engine->re;
1350
1351         if (!re) {
1352                 sprintf(name, "View3dPreview %p", (void *)ar);
1353                 re = engine->re = RE_GetRender(name);
1354                 if (!re)
1355                         re = engine->re = RE_NewRender(name);
1356
1357                 engine->update_flag |= RE_ENGINE_UPDATE_DATABASE;
1358         }
1359
1360         /* check update_flag */
1361         if (engine->update_flag & RE_ENGINE_UPDATE_MA)
1362                 job_update_flag |= PR_UPDATE_MATERIAL;
1363         
1364         if (engine->update_flag & RE_ENGINE_UPDATE_OTHER)
1365                 job_update_flag |= PR_UPDATE_MATERIAL;
1366         
1367         if (engine->update_flag & RE_ENGINE_UPDATE_DATABASE) {
1368                 job_update_flag |= PR_UPDATE_DATABASE;
1369
1370                 /* load editmesh */
1371                 if (scene->obedit)
1372                         ED_object_editmode_load(scene->obedit);
1373         }
1374         
1375         engine->update_flag = 0;
1376         
1377         /* check if viewport changed */
1378         if (engine->last_winx != ar->winx || engine->last_winy != ar->winy) {
1379                 engine->last_winx = ar->winx;
1380                 engine->last_winy = ar->winy;
1381                 job_update_flag |= PR_UPDATE_RENDERSIZE;
1382         }
1383
1384         if (compare_m4m4(engine->last_viewmat, rv3d->viewmat, 0.00001f) == 0) {
1385                 copy_m4_m4(engine->last_viewmat, rv3d->viewmat);
1386                 job_update_flag |= PR_UPDATE_VIEW;
1387         }
1388         
1389         render_view3d_get_rects(ar, v3d, rv3d, &viewplane, engine, &clipsta, &clipend, NULL, &orth);
1390         
1391         if (BLI_rctf_compare(&viewplane, &engine->last_viewplane, 0.00001f) == 0) {
1392                 engine->last_viewplane = viewplane;
1393                 job_update_flag |= PR_UPDATE_VIEW;
1394         }
1395         
1396         render_view3d_disprect(scene, ar, v3d, rv3d, &disprect);
1397         if (BLI_rcti_compare(&disprect, &engine->last_disprect) == 0) {
1398                 engine->last_disprect = disprect;
1399                 job_update_flag |= PR_UPDATE_RENDERSIZE;
1400         }
1401
1402         /* any changes? go ahead and rerender */
1403         if (job_update_flag) {
1404                 engine->job_update_flag |= job_update_flag;
1405                 return true;
1406         }
1407
1408         return false;
1409 }
1410
1411 static void render_view3d_do(RenderEngine *engine, const bContext *C)
1412 {
1413         wmJob *wm_job;
1414         RenderPreview *rp;
1415         Scene *scene = CTX_data_scene(C);
1416         ARegion *ar = CTX_wm_region(C);
1417         int width = ar->winx, height = ar->winy;
1418         int divider = 1;
1419         int resolution_threshold = scene->r.preview_start_resolution *
1420                                    scene->r.preview_start_resolution;
1421
1422         if (CTX_wm_window(C) == NULL)
1423                 return;
1424         if (!render_view3d_flag_changed(engine, C))
1425                 return;
1426
1427         wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), CTX_wm_region(C), "Render Preview",
1428                              WM_JOB_EXCL_RENDER, WM_JOB_TYPE_RENDER_PREVIEW);
1429         rp = MEM_callocN(sizeof(RenderPreview), "render preview");
1430         rp->job = wm_job;
1431
1432         while (width * height > resolution_threshold) {
1433                 width = max_ii(1, width / 2);
1434                 height = max_ii(1, height / 2);
1435                 divider *= 2;
1436         }
1437
1438         /* customdata for preview thread */
1439         rp->scene = scene;
1440         rp->engine = engine;
1441         rp->sa = CTX_wm_area(C);
1442         rp->ar = CTX_wm_region(C);
1443         rp->v3d = rp->sa->spacedata.first;
1444         rp->rv3d = CTX_wm_region_view3d(C);
1445         rp->bmain = CTX_data_main(C);
1446         rp->resolution_divider = divider;
1447         rp->start_resolution_divider = divider;
1448         rp->has_freestyle = (scene->r.mode & R_EDGE_FRS) != 0;
1449         copy_m4_m4(rp->viewmat, rp->rv3d->viewmat);
1450         
1451         /* clear info text */
1452         engine->text[0] = '\0';
1453         
1454         /* setup job */
1455         WM_jobs_customdata_set(wm_job, rp, render_view3d_free);
1456         WM_jobs_timer(wm_job, 0.1, NC_SPACE | ND_SPACE_VIEW3D, NC_SPACE | ND_SPACE_VIEW3D);
1457         WM_jobs_callbacks(wm_job, render_view3d_startjob, NULL, NULL, NULL);
1458         
1459         WM_jobs_start(CTX_wm_manager(C), wm_job);
1460         
1461         engine->flag &= ~RE_ENGINE_DO_UPDATE;
1462 }
1463
1464 /* callback for render engine , on changes */
1465 void render_view3d_update(RenderEngine *engine, const bContext *C)
1466 {       
1467         /* this shouldn't be needed and causes too many database rebuilds, but we
1468          * aren't actually tracking updates for all relevent datablocks so this is
1469          * a catch-all for updates */
1470         engine->update_flag |= RE_ENGINE_UPDATE_DATABASE;
1471
1472         render_view3d_do(engine, C);
1473 }
1474
1475 void render_view3d_draw(RenderEngine *engine, const bContext *C)
1476 {
1477         Render *re = engine->re;
1478         RenderResult rres;
1479         char name[32];
1480         
1481         render_view3d_do(engine, C);
1482         
1483         if (re == NULL) {
1484                 sprintf(name, "View3dPreview %p", (void *)CTX_wm_region(C));
1485                 re = RE_GetRender(name);
1486         
1487                 if (re == NULL) return;
1488         }
1489         
1490         RE_AcquireResultImage(re, &rres);
1491         
1492         if (rres.rectf) {
1493                 RegionView3D *rv3d = CTX_wm_region_view3d(C);
1494                 View3D *v3d = CTX_wm_view3d(C);
1495                 Scene *scene = CTX_data_scene(C);
1496                 ARegion *ar = CTX_wm_region(C);
1497                 bool force_fallback = false;
1498                 bool need_fallback = true;
1499                 float dither = scene->r.dither_intensity;
1500                 float scale_x, scale_y;
1501                 rcti clip_rect;
1502                 int xof, yof;
1503
1504                 if (render_view3d_disprect(scene, ar, v3d, rv3d, &clip_rect)) {
1505                         scale_x = (float) BLI_rcti_size_x(&clip_rect) / rres.rectx;
1506                         scale_y = (float) BLI_rcti_size_y(&clip_rect) / rres.recty;
1507                         xof = clip_rect.xmin;
1508                         yof = clip_rect.ymin;
1509                 }
1510                 else {
1511                         scale_x = (float) ar->winx / rres.rectx;
1512                         scale_y = (float) ar->winy / rres.recty;
1513                         xof = rres.xof;
1514                         yof = rres.yof;
1515                 }
1516
1517                 /* If user decided not to use GLSL, fallback to glaDrawPixelsAuto */
1518                 force_fallback |= (U.image_draw_method != IMAGE_DRAW_METHOD_GLSL);
1519
1520                 /* Try using GLSL display transform. */
1521                 if (force_fallback == false) {
1522                         if (IMB_colormanagement_setup_glsl_draw(&scene->view_settings, &scene->display_settings, dither, true)) {
1523                                 glEnable(GL_BLEND);
1524                                 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
1525                                 glPixelZoom(scale_x, scale_y);
1526                                 glaDrawPixelsTex(xof, yof, rres.rectx, rres.recty,
1527                                                  GL_RGBA, GL_FLOAT, GL_NEAREST, rres.rectf);
1528                                 glPixelZoom(1.0f, 1.0f);
1529                                 glDisable(GL_BLEND);
1530
1531                                 IMB_colormanagement_finish_glsl_draw();
1532                                 need_fallback = false;
1533                         }
1534                 }
1535
1536                 /* If GLSL failed, use old-school CPU-based transform. */
1537                 if (need_fallback) {
1538                         unsigned char *display_buffer = MEM_mallocN(4 * rres.rectx * rres.recty * sizeof(char),
1539                                                                     "render_view3d_draw");
1540
1541                         IMB_colormanagement_buffer_make_display_space(rres.rectf, display_buffer, rres.rectx, rres.recty,
1542                                                                       4, dither, &scene->view_settings, &scene->display_settings);
1543
1544                         glEnable(GL_BLEND);
1545                         glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
1546                         glPixelZoom(scale_x, scale_y);
1547                         glaDrawPixelsAuto(xof, yof, rres.rectx, rres.recty,
1548                                           GL_RGBA, GL_UNSIGNED_BYTE,
1549                                           GL_NEAREST, display_buffer);
1550                         glPixelZoom(1.0f, 1.0f);
1551                         glDisable(GL_BLEND);
1552
1553                         MEM_freeN(display_buffer);
1554                 }
1555         }
1556
1557         RE_ReleaseResultImage(re);
1558 }
1559
1560 void ED_viewport_render_kill_jobs(wmWindowManager *wm,
1561                                   Main *bmain,
1562                                   bool free_database)
1563 {
1564         bScreen *sc;
1565         ScrArea *sa;
1566         ARegion *ar;
1567
1568         if (!wm)
1569                 return;
1570
1571         /* kill all actively running jobs */
1572         WM_jobs_kill(wm, NULL, render_view3d_startjob);
1573
1574         /* loop over 3D view render engines */
1575         for (sc = bmain->screen.first; sc; sc = sc->id.next) {
1576                 for (sa = sc->areabase.first; sa; sa = sa->next) {
1577                         if (sa->spacetype != SPACE_VIEW3D)
1578                                 continue;
1579                         
1580                         for (ar = sa->regionbase.first; ar; ar = ar->next) {
1581                                 RegionView3D *rv3d;
1582                                 
1583                                 if (ar->regiontype != RGN_TYPE_WINDOW)
1584                                         continue;
1585                                 
1586                                 rv3d = ar->regiondata;
1587
1588                                 if (rv3d->render_engine) {
1589                                         /* free render database now before we change data, because
1590                                          * RE_Database_Free will also loop over blender data */
1591                                         if (free_database) {
1592                                                 char name[32];
1593                                                 Render *re;
1594
1595                                                 sprintf(name, "View3dPreview %p", (void *)ar);
1596                                                 re = RE_GetRender(name);
1597
1598                                                 if (re)
1599                                                         RE_Database_Free(re);
1600
1601                                                 /* tag render engine to update entire database */
1602                                                 rv3d->render_engine->update_flag |= RE_ENGINE_UPDATE_DATABASE;
1603                                         }
1604                                         else {
1605                                                 /* quick shader update */
1606                                                 rv3d->render_engine->update_flag |= RE_ENGINE_UPDATE_MA;
1607                                         }
1608                                 }
1609                         }
1610                 }
1611         }
1612 }
1613
1614 Scene *ED_render_job_get_scene(const bContext *C)
1615 {
1616         wmWindowManager *wm = CTX_wm_manager(C);
1617         RenderJob *rj = (RenderJob *)WM_jobs_customdata_from_type(wm, WM_JOB_TYPE_RENDER);
1618         
1619         if (rj)
1620                 return rj->current_scene;
1621         
1622         return NULL;
1623 }