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