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