Depsgraph: remove EvaluationContext, pass Depsgraph instead.
[blender.git] / source / blender / windowmanager / intern / wm_draw.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) 2007 Blender Foundation.
19  * All rights reserved.
20  *
21  * 
22  * Contributor(s): Blender Foundation
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file blender/windowmanager/intern/wm_draw.c
28  *  \ingroup wm
29  *
30  * Handle OpenGL buffers for windowing, also paint cursor.
31  */
32
33 #include <stdlib.h>
34 #include <string.h>
35
36 #include "DNA_listBase.h"
37 #include "DNA_object_types.h"
38 #include "DNA_camera_types.h"
39 #include "DNA_screen_types.h"
40 #include "DNA_windowmanager_types.h"
41 #include "DNA_userdef_types.h"
42 #include "DNA_view3d_types.h"
43
44 #include "MEM_guardedalloc.h"
45
46 #include "BLI_blenlib.h"
47 #include "BLI_utildefines.h"
48
49 #include "BIF_gl.h"
50
51 #include "BKE_context.h"
52 #include "BKE_image.h"
53 #include "BKE_scene.h"
54 #include "BKE_workspace.h"
55
56 #include "GHOST_C-api.h"
57
58 #include "ED_node.h"
59 #include "ED_view3d.h"
60 #include "ED_screen.h"
61
62 #include "GPU_draw.h"
63 #include "GPU_extensions.h"
64 #include "GPU_immediate.h"
65 #include "GPU_viewport.h"
66
67 #include "RE_engine.h"
68
69 #include "WM_api.h"
70 #include "WM_types.h"
71 #include "wm.h"
72 #include "wm_draw.h"
73 #include "wm_window.h"
74 #include "wm_event_system.h"
75
76 #ifdef WITH_OPENSUBDIV
77 #  include "BKE_subsurf.h"
78 #endif
79
80 /* swap */
81 #define WIN_NONE_OK     0
82 #define WIN_BACK_OK     1
83 #define WIN_FRONT_OK    2
84 #define WIN_BOTH_OK     3
85
86 /* ******************* drawing, overlays *************** */
87
88
89 static void wm_paintcursor_draw(bContext *C, ARegion *ar)
90 {
91         wmWindowManager *wm = CTX_wm_manager(C);
92         
93         if (wm->paintcursors.first) {
94                 wmWindow *win = CTX_wm_window(C);
95                 bScreen *screen = WM_window_get_active_screen(win);
96                 wmPaintCursor *pc;
97
98                 if (ar->visible && ar == screen->active_region) {
99                         for (pc = wm->paintcursors.first; pc; pc = pc->next) {
100                                 if (pc->poll == NULL || pc->poll(C)) {
101                                         ARegion *ar_other = CTX_wm_region(C);
102                                         if (ELEM(win->grabcursor, GHOST_kGrabWrap, GHOST_kGrabHide)) {
103                                                 int x = 0, y = 0;
104                                                 wm_get_cursor_position(win, &x, &y);
105                                                 pc->draw(C,
106                                                          x - ar_other->winrct.xmin,
107                                                          y - ar_other->winrct.ymin,
108                                                          pc->customdata);
109                                         }
110                                         else {
111                                                 pc->draw(C,
112                                                          win->eventstate->x - ar_other->winrct.xmin,
113                                                          win->eventstate->y - ar_other->winrct.ymin,
114                                                          pc->customdata);
115                                         }
116                                 }
117                         }
118                 }
119         }
120 }
121
122 /* ********************* drawing, swap ****************** */
123
124 static void wm_area_mark_invalid_backbuf(ScrArea *sa)
125 {
126         if (sa->spacetype == SPACE_VIEW3D)
127                 ((View3D *)sa->spacedata.first)->flag |= V3D_INVALID_BACKBUF;
128 }
129
130 static bool wm_area_test_invalid_backbuf(ScrArea *sa)
131 {
132         if (sa->spacetype == SPACE_VIEW3D)
133                 return (((View3D *)sa->spacedata.first)->flag & V3D_INVALID_BACKBUF) != 0;
134         else
135                 return true;
136 }
137
138 static void wm_region_test_render_do_draw(const Scene *scene, struct Depsgraph *depsgraph,
139                                           ScrArea *sa, ARegion *ar)
140 {
141         /* tag region for redraw from render engine preview running inside of it */
142         if (sa->spacetype == SPACE_VIEW3D) {
143                 RegionView3D *rv3d = ar->regiondata;
144                 RenderEngine *engine = (rv3d) ? rv3d->render_engine : NULL;
145                 GPUViewport *viewport = (rv3d) ? rv3d->viewport : NULL;
146
147                 if (engine && (engine->flag & RE_ENGINE_DO_DRAW)) {
148                         View3D *v3d = sa->spacedata.first;
149                         rcti border_rect;
150
151                         /* do partial redraw when possible */
152                         if (ED_view3d_calc_render_border(scene, depsgraph, v3d, ar, &border_rect))
153                                 ED_region_tag_redraw_partial(ar, &border_rect);
154                         else
155                                 ED_region_tag_redraw(ar);
156
157                         engine->flag &= ~RE_ENGINE_DO_DRAW;
158                 }
159                 else if (viewport && GPU_viewport_do_update(viewport)) {
160                         ED_region_tag_redraw(ar);
161                 }
162         }
163 }
164
165 /********************** draw all **************************/
166 /* - reference method, draw all each time                 */
167
168 typedef struct WindowDrawCB {
169         struct WindowDrawCB *next, *prev;
170
171         void(*draw)(const struct wmWindow *, void *);
172         void *customdata;
173
174 } WindowDrawCB;
175
176 void *WM_draw_cb_activate(
177         wmWindow *win,
178         void(*draw)(const struct wmWindow *, void *),
179         void *customdata)
180 {
181         WindowDrawCB *wdc = MEM_callocN(sizeof(*wdc), "WindowDrawCB");
182
183         BLI_addtail(&win->drawcalls, wdc);
184         wdc->draw = draw;
185         wdc->customdata = customdata;
186
187         return wdc;
188 }
189
190 void WM_draw_cb_exit(wmWindow *win, void *handle)
191 {
192         for (WindowDrawCB *wdc = win->drawcalls.first; wdc; wdc = wdc->next) {
193                 if (wdc == (WindowDrawCB *)handle) {
194                         BLI_remlink(&win->drawcalls, wdc);
195                         MEM_freeN(wdc);
196                         return;
197                 }
198         }
199 }
200
201 static void wm_draw_callbacks(wmWindow *win)
202 {
203         for (WindowDrawCB *wdc = win->drawcalls.first; wdc; wdc = wdc->next) {
204                 wdc->draw(win, wdc->customdata);
205         }
206 }
207
208 static void wm_method_draw_full(bContext *C, wmWindow *win)
209 {
210         bScreen *screen = WM_window_get_active_screen(win);
211         ScrArea *sa;
212         ARegion *ar;
213
214         /* draw area regions */
215         for (sa = screen->areabase.first; sa; sa = sa->next) {
216                 CTX_wm_area_set(C, sa);
217
218                 for (ar = sa->regionbase.first; ar; ar = ar->next) {
219                         if (ar->visible) {
220                                 CTX_wm_region_set(C, ar);
221                                 ED_region_do_draw(C, ar);
222                                 ar->do_draw = false;
223                                 wm_paintcursor_draw(C, ar);
224                                 CTX_wm_region_set(C, NULL);
225                         }
226                 }
227                 
228                 wm_area_mark_invalid_backbuf(sa);
229                 CTX_wm_area_set(C, NULL);
230         }
231
232         ED_screen_draw_edges(win);
233         screen->do_draw = false;
234         wm_draw_callbacks(win);
235
236         /* draw overlapping regions */
237         for (ar = screen->regionbase.first; ar; ar = ar->next) {
238                 if (ar->visible) {
239                         CTX_wm_menu_set(C, ar);
240                         ED_region_do_draw(C, ar);
241                         ar->do_draw = false;
242                         CTX_wm_menu_set(C, NULL);
243                 }
244         }
245
246         if (screen->do_draw_gesture)
247                 wm_gesture_draw(win);
248 }
249
250 /****************** draw overlap all **********************/
251 /* - redraw marked areas, and anything that overlaps it   */
252 /* - it also handles swap exchange optionally, assuming   */
253 /*   that on swap no clearing happens and we get back the */
254 /*   same buffer as we swapped to the front               */
255
256 /* mark area-regions to redraw if overlapped with rect */
257 static void wm_flush_regions_down(bScreen *screen, rcti *dirty)
258 {
259         ScrArea *sa;
260         ARegion *ar;
261
262         for (sa = screen->areabase.first; sa; sa = sa->next) {
263                 for (ar = sa->regionbase.first; ar; ar = ar->next) {
264                         if (BLI_rcti_isect(dirty, &ar->winrct, NULL)) {
265                                 ar->do_draw = RGN_DRAW;
266                                 memset(&ar->drawrct, 0, sizeof(ar->drawrct));
267                                 ar->swap = WIN_NONE_OK;
268                         }
269                 }
270         }
271 }
272
273 /* mark menu-regions to redraw if overlapped with rect */
274 static void wm_flush_regions_up(bScreen *screen, rcti *dirty)
275 {
276         ARegion *ar;
277         
278         for (ar = screen->regionbase.first; ar; ar = ar->next) {
279                 if (BLI_rcti_isect(dirty, &ar->winrct, NULL)) {
280                         ar->do_draw = RGN_DRAW;
281                         memset(&ar->drawrct, 0, sizeof(ar->drawrct));
282                         ar->swap = WIN_NONE_OK;
283                 }
284         }
285 }
286
287 static void wm_method_draw_overlap_all(bContext *C, wmWindow *win, int exchange)
288 {
289         wmWindowManager *wm = CTX_wm_manager(C);
290         bScreen *screen = WM_window_get_active_screen(win);
291         ScrArea *sa;
292         ARegion *ar;
293         static rcti rect = {0, 0, 0, 0};
294
295         /* after backbuffer selection draw, we need to redraw */
296         for (sa = screen->areabase.first; sa; sa = sa->next)
297                 for (ar = sa->regionbase.first; ar; ar = ar->next)
298                         if (ar->visible && !wm_area_test_invalid_backbuf(sa))
299                                 ED_region_tag_redraw(ar);
300
301         /* flush overlapping regions */
302         if (screen->regionbase.first) {
303                 /* flush redraws of area regions up to overlapping regions */
304                 for (sa = screen->areabase.first; sa; sa = sa->next)
305                         for (ar = sa->regionbase.first; ar; ar = ar->next)
306                                 if (ar->visible && ar->do_draw)
307                                         wm_flush_regions_up(screen, &ar->winrct);
308                 
309                 /* flush between overlapping regions */
310                 for (ar = screen->regionbase.last; ar; ar = ar->prev)
311                         if (ar->visible && ar->do_draw)
312                                 wm_flush_regions_up(screen, &ar->winrct);
313                 
314                 /* flush redraws of overlapping regions down to area regions */
315                 for (ar = screen->regionbase.last; ar; ar = ar->prev)
316                         if (ar->visible && ar->do_draw)
317                                 wm_flush_regions_down(screen, &ar->winrct);
318         }
319
320         /* flush drag item */
321         if (rect.xmin != rect.xmax) {
322                 wm_flush_regions_down(screen, &rect);
323                 rect.xmin = rect.xmax = 0;
324         }
325         if (wm->drags.first) {
326                 /* doesnt draw, fills rect with boundbox */
327                 wm_drags_draw(C, win, &rect);
328         }
329         
330         /* draw marked area regions */
331         for (sa = screen->areabase.first; sa; sa = sa->next) {
332                 CTX_wm_area_set(C, sa);
333
334                 for (ar = sa->regionbase.first; ar; ar = ar->next) {
335                         if (ar->visible) {
336                                 if (ar->do_draw) {
337                                         CTX_wm_region_set(C, ar);
338                                         ED_region_do_draw(C, ar);
339                                         ar->do_draw = false;
340                                         wm_paintcursor_draw(C, ar);
341                                         CTX_wm_region_set(C, NULL);
342
343                                         if (exchange)
344                                                 ar->swap = WIN_FRONT_OK;
345                                 }
346                                 else if (exchange) {
347                                         if (ar->swap == WIN_FRONT_OK) {
348                                                 CTX_wm_region_set(C, ar);
349                                                 ED_region_do_draw(C, ar);
350                                                 ar->do_draw = false;
351                                                 wm_paintcursor_draw(C, ar);
352                                                 CTX_wm_region_set(C, NULL);
353
354                                                 ar->swap = WIN_BOTH_OK;
355                                         }
356                                         else if (ar->swap == WIN_BACK_OK)
357                                                 ar->swap = WIN_FRONT_OK;
358                                         else if (ar->swap == WIN_BOTH_OK)
359                                                 ar->swap = WIN_BOTH_OK;
360                                 }
361                         }
362                 }
363
364                 wm_area_mark_invalid_backbuf(sa);
365                 CTX_wm_area_set(C, NULL);
366         }
367
368         /* after area regions so we can do area 'overlay' drawing */
369         if (screen->do_draw) {
370                 ED_screen_draw_edges(win);
371                 screen->do_draw = false;
372                 wm_draw_callbacks(win);
373
374                 if (exchange)
375                         screen->swap = WIN_FRONT_OK;
376         }
377         else if (exchange) {
378                 if (screen->swap == WIN_FRONT_OK) {
379                         ED_screen_draw_edges(win);
380                         screen->do_draw = false;
381                         screen->swap = WIN_BOTH_OK;
382                         wm_draw_callbacks(win);
383                 }
384                 else if (screen->swap == WIN_BACK_OK)
385                         screen->swap = WIN_FRONT_OK;
386                 else if (screen->swap == WIN_BOTH_OK)
387                         screen->swap = WIN_BOTH_OK;
388         }
389
390         /* draw marked overlapping regions */
391         for (ar = screen->regionbase.first; ar; ar = ar->next) {
392                 if (ar->visible && ar->do_draw) {
393                         CTX_wm_menu_set(C, ar);
394                         ED_region_do_draw(C, ar);
395                         ar->do_draw = false;
396                         CTX_wm_menu_set(C, NULL);
397                 }
398         }
399
400         if (screen->do_draw_gesture)
401                 wm_gesture_draw(win);
402         
403         /* needs pixel coords in screen */
404         if (wm->drags.first) {
405                 wm_drags_draw(C, win, NULL);
406         }
407 }
408
409 /****************** draw triple buffer ********************/
410 /* - area regions are written into a texture, without any */
411 /*   of the overlapping menus, brushes, gestures. these   */
412 /*   are redrawn each time.                               */
413
414 static void wm_draw_triple_free(wmDrawTriple *triple)
415 {
416         if (triple) {
417                 glDeleteTextures(1, &triple->bind);
418                 MEM_freeN(triple);
419         }
420 }
421
422 static void wm_draw_triple_fail(bContext *C, wmWindow *win)
423 {
424         wm_draw_window_clear(win);
425
426         win->drawfail = true;
427         wm_method_draw_overlap_all(C, win, 0);
428 }
429
430 static bool wm_triple_gen_textures(wmWindow *win, wmDrawTriple *triple)
431 {
432         /* compute texture sizes */
433         const int sizex = WM_window_pixels_x(win);
434         const int sizey = WM_window_pixels_y(win);
435
436         /* generate texture names */
437         glGenTextures(1, &triple->bind);
438
439         /* proxy texture is only guaranteed to test for the cases that
440          * there is only one texture in use, which may not be the case */
441         const GLint maxsize = GPU_max_texture_size();
442
443         if (sizex > maxsize || sizey > maxsize) {
444                 printf("WM: failed to allocate texture for triple buffer drawing "
445                        "(texture too large for graphics card).\n");
446                 return false;
447         }
448
449         /* setup actual texture */
450         glBindTexture(GL_TEXTURE_2D, triple->bind);
451
452         /* no mipmaps */
453         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
454         /* GL_TEXTURE_BASE_LEVEL = 0 by default */
455
456         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
457         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
458
459         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, sizex, sizey, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
460
461         glBindTexture(GL_TEXTURE_2D, 0);
462
463         return true;
464 }
465
466 void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple, float alpha)
467 {
468         const int sizex = WM_window_pixels_x(win);
469         const int sizey = WM_window_pixels_y(win);
470
471         /* wmOrtho for the screen has this same offset */
472         const float ratiox = 1.0f;
473         const float ratioy = 1.0f;
474         const float halfx = GLA_PIXEL_OFS / sizex;
475         const float halfy = GLA_PIXEL_OFS / sizey;
476
477         const int activeTex = 7; /* arbitrary */
478         glActiveTexture(GL_TEXTURE0 + activeTex);
479         glBindTexture(GL_TEXTURE_2D, triple->bind);
480
481         float x1 = halfx;
482         float x2 = ratiox + halfx;
483         float y1 = halfy;
484         float y2 = ratioy + halfy;
485
486         GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_RECT_COLOR);
487         GPU_shader_bind(shader);
488
489         glUniform1i(GPU_shader_get_uniform(shader, "image"), activeTex);
490         glUniform4f(GPU_shader_get_uniform(shader, "rect_icon"), x1, y1, x2, y2);
491         glUniform4f(GPU_shader_get_uniform(shader, "rect_geom"), 0.0f, 0.0f, sizex, sizey);
492         glUniform4f(GPU_shader_get_builtin_uniform(shader, GWN_UNIFORM_COLOR), alpha, alpha, alpha, alpha);
493
494         GWN_draw_primitive(GWN_PRIM_TRI_STRIP, 4);
495
496         glBindTexture(GL_TEXTURE_2D, 0);
497 }
498
499 static void wm_triple_copy_textures(wmWindow *win, wmDrawTriple *triple)
500 {
501         const int sizex = WM_window_pixels_x(win);
502         const int sizey = WM_window_pixels_y(win);
503
504         glBindTexture(GL_TEXTURE_2D, triple->bind);
505         /* what is GL_READ_BUFFER right now? */
506         glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, sizex, sizey);
507         glBindTexture(GL_TEXTURE_2D, 0);
508 }
509
510 static void wm_draw_region_blend(wmWindow *win, ARegion *ar, wmDrawTriple *triple)
511 {
512         float fac = ED_region_blend_factor(ar);
513         
514         /* region blend always is 1, except when blend timer is running */
515         if (fac < 1.0f) {
516                 wmViewport(&ar->winrct);
517
518                 glEnable(GL_BLEND);
519                 wm_triple_draw_textures(win, triple, 1.0f - fac);
520                 glDisable(GL_BLEND);
521         }
522 }
523
524 static void wm_method_draw_triple(bContext *C, wmWindow *win)
525 {
526         wmWindowManager *wm = CTX_wm_manager(C);
527         wmDrawData *dd, *dd_next, *drawdata = win->drawdata.first;
528         bScreen *screen = WM_window_get_active_screen(win);
529         ScrArea *sa;
530         ARegion *ar;
531         bool copytex = false;
532
533         if (drawdata && drawdata->triple) {
534 #if 0 /* why do we need to clear before overwriting? */
535                 glClearColor(1, 1, 0, 0);
536                 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
537 #endif
538
539                 wmWindowViewport(win);
540
541                 wm_triple_draw_textures(win, drawdata->triple, 1.0f);
542         }
543         else {
544                 /* we run it when we start OR when we turn stereo on */
545                 if (drawdata == NULL) {
546                         drawdata = MEM_callocN(sizeof(wmDrawData), "wmDrawData");
547                         BLI_addhead(&win->drawdata, drawdata);
548                 }
549
550                 drawdata->triple = MEM_callocN(sizeof(wmDrawTriple), "wmDrawTriple");
551
552                 if (!wm_triple_gen_textures(win, drawdata->triple)) {
553                         wm_draw_triple_fail(C, win);
554                         return;
555                 }
556         }
557
558         /* it means stereo was just turned off */
559         /* note: we are removing all drawdatas that are not the first */
560         for (dd = drawdata->next; dd; dd = dd_next) {
561                 dd_next = dd->next;
562
563                 BLI_remlink(&win->drawdata, dd);
564                 wm_draw_triple_free(dd->triple);
565                 MEM_freeN(dd);
566         }
567
568         wmDrawTriple *triple = drawdata->triple;
569
570         /* draw marked area regions */
571         for (sa = screen->areabase.first; sa; sa = sa->next) {
572                 CTX_wm_area_set(C, sa);
573
574                 for (ar = sa->regionbase.first; ar; ar = ar->next) {
575                         if (ar->visible && ar->do_draw) {
576                                 if (ar->overlap == false) {
577                                         CTX_wm_region_set(C, ar);
578                                         ED_region_do_draw(C, ar);
579                                         ar->do_draw = false;
580                                         CTX_wm_region_set(C, NULL);
581                                         copytex = true;
582                                 }
583                         }
584                 }
585
586                 wm_area_mark_invalid_backbuf(sa);
587                 CTX_wm_area_set(C, NULL);
588         }
589
590         if (copytex) {
591                 wmWindowViewport(win);
592
593                 wm_triple_copy_textures(win, triple);
594         }
595
596         if (wm->paintcursors.first) {
597                 for (sa = screen->areabase.first; sa; sa = sa->next) {
598                         for (ar = sa->regionbase.first; ar; ar = ar->next) {
599                                 if (ar->visible && ar == screen->active_region) {
600                                         CTX_wm_area_set(C, sa);
601                                         CTX_wm_region_set(C, ar);
602
603                                         /* make region ready for draw, scissor, pixelspace */
604                                         wmViewport(&ar->winrct);
605                                         wm_paintcursor_draw(C, ar);
606
607                                         CTX_wm_region_set(C, NULL);
608                                         CTX_wm_area_set(C, NULL);
609                                 }
610                         }
611                 }
612
613                 wmWindowViewport(win);
614         }
615
616         /* draw overlapping area regions (always like popups) */
617         for (sa = screen->areabase.first; sa; sa = sa->next) {
618                 CTX_wm_area_set(C, sa);
619
620                 for (ar = sa->regionbase.first; ar; ar = ar->next) {
621                         if (ar->visible && ar->overlap) {
622                                 CTX_wm_region_set(C, ar);
623                                 ED_region_do_draw(C, ar);
624                                 ar->do_draw = false;
625                                 CTX_wm_region_set(C, NULL);
626
627                                 wm_draw_region_blend(win, ar, triple);
628                         }
629                 }
630
631                 CTX_wm_area_set(C, NULL);
632         }
633
634         /* after area regions so we can do area 'overlay' drawing */
635         ED_screen_draw_edges(win);
636         WM_window_get_active_screen(win)->do_draw = false;
637         wm_draw_callbacks(win);
638
639         /* draw floating regions (menus) */
640         for (ar = screen->regionbase.first; ar; ar = ar->next) {
641                 if (ar->visible) {
642                         CTX_wm_menu_set(C, ar);
643                         ED_region_do_draw(C, ar);
644                         ar->do_draw = false;
645                         CTX_wm_menu_set(C, NULL);
646                 }
647         }
648
649         /* always draw, not only when screen tagged */
650         if (win->gesture.first)
651                 wm_gesture_draw(win);
652
653         /* needs pixel coords in screen */
654         if (wm->drags.first) {
655                 wm_drags_draw(C, win, NULL);
656         }
657 }
658
659 static void wm_method_draw_triple_multiview(bContext *C, wmWindow *win, eStereoViews sview)
660 {
661         wmWindowManager *wm = CTX_wm_manager(C);
662         wmDrawData *drawdata;
663         wmDrawTriple *triple_data, *triple_all;
664         bScreen *screen = WM_window_get_active_screen(win);
665         ScrArea *sa;
666         ARegion *ar;
667         int copytex = false;
668         int id;
669
670         /* we store the triple_data in sequence to triple_all */
671         for (id = 0; id < 2; id++) {
672                 drawdata = BLI_findlink(&win->drawdata, (sview * 2) + id);
673
674                 if (drawdata && drawdata->triple) {
675                         if (id == 0) {
676 #if 0 /* why do we need to clear before overwriting? */
677                                 glClearColor(0, 0, 0, 0);
678                                 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
679 #endif
680
681                                 wmWindowViewport(win);
682
683                                 wm_triple_draw_textures(win, drawdata->triple, 1.0f);
684                         }
685                 }
686                 else {
687                         /* we run it when we start OR when we turn stereo on */
688                         if (drawdata == NULL) {
689                                 drawdata = MEM_callocN(sizeof(wmDrawData), "wmDrawData");
690                                 BLI_addtail(&win->drawdata, drawdata);
691                         }
692
693                         drawdata->triple = MEM_callocN(sizeof(wmDrawTriple), "wmDrawTriple");
694
695                         if (!wm_triple_gen_textures(win, drawdata->triple)) {
696                                 wm_draw_triple_fail(C, win);
697                                 return;
698                         }
699                 }
700         }
701
702         triple_data = ((wmDrawData *) BLI_findlink(&win->drawdata, sview * 2))->triple;
703         triple_all  = ((wmDrawData *) BLI_findlink(&win->drawdata, (sview * 2) + 1))->triple;
704
705         /* draw marked area regions */
706         for (sa = screen->areabase.first; sa; sa = sa->next) {
707                 CTX_wm_area_set(C, sa);
708
709                 switch (sa->spacetype) {
710                         case SPACE_IMAGE:
711                         {
712                                 SpaceImage *sima = sa->spacedata.first;
713                                 sima->iuser.multiview_eye = sview;
714                                 break;
715                         }
716                         case SPACE_VIEW3D:
717                         {
718                                 View3D *v3d = sa->spacedata.first;
719                                 if (v3d->camera && v3d->camera->type == OB_CAMERA) {
720                                         Camera *cam = v3d->camera->data;
721                                         CameraBGImage *bgpic = cam->bg_images.first;
722                                         v3d->multiview_eye = sview;
723                                         if (bgpic) bgpic->iuser.multiview_eye = sview;
724                                 }
725                                 break;
726                         }
727                         case SPACE_NODE:
728                         {
729                                 SpaceNode *snode = sa->spacedata.first;
730                                 if ((snode->flag & SNODE_BACKDRAW) && ED_node_is_compositor(snode)) {
731                                         Image *ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
732                                         ima->eye = sview;
733                                 }
734                                 break;
735                         }
736                         case SPACE_SEQ:
737                         {
738                                 SpaceSeq *sseq = sa->spacedata.first;
739                                 sseq->multiview_eye = sview;
740                                 break;
741                         }
742                 }
743
744                 /* draw marked area regions */
745                 for (ar = sa->regionbase.first; ar; ar = ar->next) {
746                         if (ar->visible && ar->do_draw) {
747
748                                 if (ar->overlap == false) {
749                                         CTX_wm_region_set(C, ar);
750                                         ED_region_do_draw(C, ar);
751
752                                         if (sview == STEREO_RIGHT_ID)
753                                                 ar->do_draw = false;
754
755                                         CTX_wm_region_set(C, NULL);
756                                         copytex = true;
757                                 }
758                         }
759                 }
760
761                 wm_area_mark_invalid_backbuf(sa);
762                 CTX_wm_area_set(C, NULL);
763         }
764
765         if (copytex) {
766                 wmWindowViewport(win);
767
768                 wm_triple_copy_textures(win, triple_data);
769         }
770
771         if (wm->paintcursors.first) {
772                 for (sa = screen->areabase.first; sa; sa = sa->next) {
773                         for (ar = sa->regionbase.first; ar; ar = ar->next) {
774                                 if (ar->visible && ar == screen->active_region) {
775                                         CTX_wm_area_set(C, sa);
776                                         CTX_wm_region_set(C, ar);
777
778                                         /* make region ready for draw, scissor, pixelspace */
779                                         wmViewport(&ar->winrct);
780                                         wm_paintcursor_draw(C, ar);
781
782                                         CTX_wm_region_set(C, NULL);
783                                         CTX_wm_area_set(C, NULL);
784                                 }
785                         }
786                 }
787
788                 wmWindowViewport(win);
789         }
790
791         /* draw overlapping area regions (always like popups) */
792         for (sa = screen->areabase.first; sa; sa = sa->next) {
793                 CTX_wm_area_set(C, sa);
794
795                 for (ar = sa->regionbase.first; ar; ar = ar->next) {
796                         if (ar->visible && ar->overlap) {
797                                 CTX_wm_region_set(C, ar);
798                                 ED_region_do_draw(C, ar);
799                                 if (sview == STEREO_RIGHT_ID)
800                                         ar->do_draw = false;
801                                 CTX_wm_region_set(C, NULL);
802
803                                 wm_draw_region_blend(win, ar, triple_data);
804                         }
805                 }
806
807                 CTX_wm_area_set(C, NULL);
808         }
809
810         /* after area regions so we can do area 'overlay' drawing */
811         ED_screen_draw_edges(win);
812         if (sview == STEREO_RIGHT_ID)
813                 screen->do_draw = false;
814
815         wm_draw_callbacks(win);
816
817         /* draw floating regions (menus) */
818         for (ar = screen->regionbase.first; ar; ar = ar->next) {
819                 if (ar->visible) {
820                         CTX_wm_menu_set(C, ar);
821                         ED_region_do_draw(C, ar);
822                         if (sview == STEREO_RIGHT_ID)
823                                 ar->do_draw = false;
824                         CTX_wm_menu_set(C, NULL);
825                 }
826         }
827
828         /* always draw, not only when screen tagged */
829         if (win->gesture.first)
830                 wm_gesture_draw(win);
831
832         /* needs pixel coords in screen */
833         if (wm->drags.first) {
834                 wm_drags_draw(C, win, NULL);
835         }
836
837         /* copy the ui + overlays */
838         wmWindowViewport(win);
839         wm_triple_copy_textures(win, triple_all);
840 }
841
842 /****************** main update call **********************/
843
844 /* quick test to prevent changing window drawable */
845 static bool wm_draw_update_test_window(wmWindow *win)
846 {
847         /*const*/ struct WorkSpace *workspace = WM_window_get_active_workspace(win);
848         /*const*/ Scene *scene = WM_window_get_active_scene(win);
849         /*const*/ ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace, scene);
850         struct Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer, true);
851         const bScreen *screen = WM_window_get_active_screen(win);
852         ScrArea *sa;
853         ARegion *ar;
854         bool do_draw = false;
855
856         for (ar = screen->regionbase.first; ar; ar = ar->next) {
857                 if (ar->do_draw_overlay) {
858                         wm_tag_redraw_overlay(win, ar);
859                         ar->do_draw_overlay = false;
860                 }
861                 if (ar->visible && ar->do_draw)
862                         do_draw = true;
863         }
864
865         for (sa = screen->areabase.first; sa; sa = sa->next) {
866                 for (ar = sa->regionbase.first; ar; ar = ar->next) {
867                         wm_region_test_render_do_draw(scene, depsgraph, sa, ar);
868
869                         if (ar->visible && ar->do_draw)
870                                 do_draw = true;
871                 }
872         }
873
874         if (do_draw)
875                 return true;
876         
877         if (screen->do_refresh)
878                 return true;
879         if (screen->do_draw)
880                 return true;
881         if (screen->do_draw_gesture)
882                 return true;
883         if (screen->do_draw_paintcursor)
884                 return true;
885         if (screen->do_draw_drag)
886                 return true;
887         
888         return false;
889 }
890
891 static int wm_automatic_draw_method(wmWindow *win)
892 {
893         /* We assume all supported GPUs now support triple buffer well. */
894         if (win->drawmethod == USER_DRAW_AUTOMATIC) {
895                 return USER_DRAW_TRIPLE;
896         }
897         else {
898                 return win->drawmethod;
899         }
900 }
901
902 bool WM_is_draw_triple(wmWindow *win)
903 {
904         /* function can get called before this variable is set in drawing code below */
905         if (win->drawmethod != U.wmdrawmethod)
906                 win->drawmethod = U.wmdrawmethod;
907         return (USER_DRAW_TRIPLE == wm_automatic_draw_method(win));
908 }
909
910 void wm_tag_redraw_overlay(wmWindow *win, ARegion *ar)
911 {
912         /* for draw triple gestures, paint cursors don't need region redraw */
913         if (ar && win) {
914                 bScreen *screen = WM_window_get_active_screen(win);
915
916                 if (wm_automatic_draw_method(win) != USER_DRAW_TRIPLE)
917                         ED_region_tag_redraw(ar);
918                 screen->do_draw_paintcursor = true;
919         }
920 }
921
922 void WM_paint_cursor_tag_redraw(wmWindow *win, ARegion *ar)
923 {
924         bScreen *screen = WM_window_get_active_screen(win);
925         screen->do_draw_paintcursor = true;
926         wm_tag_redraw_overlay(win, ar);
927 }
928
929 void wm_draw_update(bContext *C)
930 {
931         wmWindowManager *wm = CTX_wm_manager(C);
932         wmWindow *win;
933
934 #ifdef WITH_OPENSUBDIV
935         BKE_subsurf_free_unused_buffers();
936 #endif
937
938         GPU_free_unused_buffers();
939         
940         for (win = wm->windows.first; win; win = win->next) {
941 #ifdef WIN32
942                 GHOST_TWindowState state = GHOST_GetWindowState(win->ghostwin);
943
944                 if (state == GHOST_kWindowStateMinimized) {
945                         /* do not update minimized windows, gives issues on Intel (see T33223)
946                          * and AMD (see T50856). it seems logical to skip update for invisible
947                          * window anyway.
948                          */
949                         continue;
950                 }
951 #endif
952                 if (win->drawmethod != U.wmdrawmethod) {
953                         wm_draw_window_clear(win);
954                         win->drawmethod = U.wmdrawmethod;
955                 }
956
957                 if (wm_draw_update_test_window(win)) {
958                         bScreen *screen = WM_window_get_active_screen(win);
959
960                         CTX_wm_window_set(C, win);
961                         
962                         /* sets context window+screen */
963                         wm_window_make_drawable(wm, win);
964
965                         /* notifiers for screen redraw */
966                         if (screen->do_refresh)
967                                 ED_screen_refresh(wm, win);
968
969                         int drawmethod = wm_automatic_draw_method(win);
970
971                         if (win->drawfail)
972                                 wm_method_draw_overlap_all(C, win, 0);
973                         else if (drawmethod == USER_DRAW_FULL)
974                                 wm_method_draw_full(C, win);
975                         else if (drawmethod == USER_DRAW_OVERLAP)
976                                 wm_method_draw_overlap_all(C, win, 0);
977                         else if (drawmethod == USER_DRAW_OVERLAP_FLIP)
978                                 wm_method_draw_overlap_all(C, win, 1);
979                         else { /* USER_DRAW_TRIPLE */
980                                 if ((WM_stereo3d_enabled(win, false)) == false) {
981                                         wm_method_draw_triple(C, win);
982                                 }
983                                 else {
984                                         wm_method_draw_triple_multiview(C, win, STEREO_LEFT_ID);
985                                         wm_method_draw_triple_multiview(C, win, STEREO_RIGHT_ID);
986                                         wm_method_draw_stereo3d(C, win);
987                                 }
988                         }
989
990                         screen->do_draw_gesture = false;
991                         screen->do_draw_paintcursor = false;
992                         screen->do_draw_drag = false;
993                 
994                         wm_window_swap_buffers(win);
995
996                         CTX_wm_window_set(C, NULL);
997                 }
998         }
999 }
1000
1001 void wm_draw_data_free(wmWindow *win)
1002 {
1003         wmDrawData *dd;
1004
1005         for (dd = win->drawdata.first; dd; dd = dd->next) {
1006                 wm_draw_triple_free(dd->triple);
1007         }
1008         BLI_freelistN(&win->drawdata);
1009 }
1010
1011 void wm_draw_window_clear(wmWindow *win)
1012 {
1013         bScreen *screen = WM_window_get_active_screen(win);
1014         ScrArea *sa;
1015         ARegion *ar;
1016
1017         wm_draw_data_free(win);
1018
1019         /* clear screen swap flags */
1020         if (screen) {
1021                 for (sa = screen->areabase.first; sa; sa = sa->next)
1022                         for (ar = sa->regionbase.first; ar; ar = ar->next)
1023                                 ar->swap = WIN_NONE_OK;
1024                 
1025                 screen->swap = WIN_NONE_OK;
1026         }
1027 }
1028
1029 void wm_draw_region_clear(wmWindow *win, ARegion *ar)
1030 {
1031         bScreen *screen = WM_window_get_active_screen(win);
1032         int drawmethod = wm_automatic_draw_method(win);
1033
1034         if (ELEM(drawmethod, USER_DRAW_OVERLAP, USER_DRAW_OVERLAP_FLIP))
1035                 wm_flush_regions_down(screen, &ar->winrct);
1036
1037         screen->do_draw = true;
1038 }
1039
1040 void WM_redraw_windows(bContext *C)
1041 {
1042         wmWindow *win_prev = CTX_wm_window(C);
1043         ScrArea *area_prev = CTX_wm_area(C);
1044         ARegion *ar_prev = CTX_wm_region(C);
1045
1046         wm_draw_update(C);
1047
1048         CTX_wm_window_set(C, win_prev);
1049         CTX_wm_area_set(C, area_prev);
1050         CTX_wm_region_set(C, ar_prev);
1051 }
1052