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