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