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