Blender  V3.3
wm_draw.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2007 Blender Foundation. All rights reserved. */
3 
10 #include <stdlib.h>
11 #include <string.h>
12 
13 #include "DNA_camera_types.h"
14 #include "DNA_listBase.h"
15 #include "DNA_object_types.h"
16 #include "DNA_screen_types.h"
17 #include "DNA_userdef_types.h"
18 #include "DNA_view3d_types.h"
20 
21 #include "MEM_guardedalloc.h"
22 
23 #include "BLI_blenlib.h"
24 #include "BLI_utildefines.h"
25 
26 #include "BKE_context.h"
27 #include "BKE_global.h"
28 #include "BKE_image.h"
29 #include "BKE_main.h"
30 #include "BKE_scene.h"
31 #include "BKE_screen.h"
32 
33 #include "GHOST_C-api.h"
34 
35 #include "ED_node.h"
36 #include "ED_screen.h"
37 #include "ED_view3d.h"
38 
39 #include "GPU_batch_presets.h"
40 #include "GPU_context.h"
41 #include "GPU_debug.h"
42 #include "GPU_framebuffer.h"
43 #include "GPU_immediate.h"
44 #include "GPU_matrix.h"
45 #include "GPU_state.h"
46 #include "GPU_texture.h"
47 #include "GPU_viewport.h"
48 
49 #include "RE_engine.h"
50 
51 #include "WM_api.h"
52 #include "WM_toolsystem.h"
53 #include "WM_types.h"
54 #include "wm.h"
55 #include "wm_draw.h"
56 #include "wm_event_system.h"
57 #include "wm_surface.h"
58 #include "wm_window.h"
59 
60 #include "UI_resources.h"
61 
62 #ifdef WITH_OPENSUBDIV
63 # include "BKE_subsurf.h"
64 #endif
65 
66 /* -------------------------------------------------------------------- */
71 {
73  wmWindow *win = CTX_wm_window(C);
74  bScreen *screen = WM_window_get_active_screen(win);
75 
76  /* Don't draw paint cursors with locked interface. Painting is not possible
77  * then, and cursor drawing can use scene data that another thread may be
78  * modifying. */
79  if (wm->is_interface_locked) {
80  return;
81  }
82 
83  if (!region->visible || region != screen->active_region) {
84  return;
85  }
86 
88  if ((pc->space_type != SPACE_TYPE_ANY) && (area->spacetype != pc->space_type)) {
89  continue;
90  }
91 
92  if (!ELEM(pc->region_type, RGN_TYPE_ANY, region->regiontype)) {
93  continue;
94  }
95 
96  if (pc->poll == NULL || pc->poll(C)) {
97  UI_SetTheme(area->spacetype, region->regiontype);
98 
99  /* Prevent drawing outside region. */
100  GPU_scissor_test(true);
101  GPU_scissor(region->winrct.xmin,
102  region->winrct.ymin,
103  BLI_rcti_size_x(&region->winrct) + 1,
104  BLI_rcti_size_y(&region->winrct) + 1);
105 
107  int x = 0, y = 0;
108  wm_cursor_position_get(win, &x, &y);
109  pc->draw(C, x, y, pc->customdata);
110  }
111  else {
112  pc->draw(C, win->eventstate->xy[0], win->eventstate->xy[1], pc->customdata);
113  }
114 
115  GPU_scissor_test(false);
116  }
117  }
118 }
119 
122 /* -------------------------------------------------------------------- */
132 static struct {
134  int winid;
135  int xy[2];
136 } g_software_cursor = {
137  .enabled = -1,
138  .winid = -1,
139 };
140 
142 struct GrabState {
145  int bounds[4];
146 };
147 
148 static bool wm_software_cursor_needed(void)
149 {
150  if (UNLIKELY(g_software_cursor.enabled == -1)) {
152  }
153  return g_software_cursor.enabled;
154 }
155 
156 static bool wm_software_cursor_needed_for_window(const wmWindow *win, struct GrabState *grab_state)
157 {
160  /* NOTE: The value in `win->grabcursor` can't be used as it
161  * doesn't always match GHOST's value in the case of tablet events. */
162  bool use_software_cursor;
164  &grab_state->mode,
165  &grab_state->wrap_axis,
166  grab_state->bounds,
167  &use_software_cursor);
168  if (use_software_cursor) {
169  return true;
170  }
171  }
172  return false;
173 }
174 
176 {
177  return (g_software_cursor.winid != win->winid) ||
178  (g_software_cursor.xy[0] != win->eventstate->xy[0]) ||
179  (g_software_cursor.xy[1] != win->eventstate->xy[1]);
180 }
181 
183 {
184 
185  g_software_cursor.winid = win->winid;
186  g_software_cursor.xy[0] = win->eventstate->xy[0];
187  g_software_cursor.xy[1] = win->eventstate->xy[1];
188 }
189 
191 {
192  g_software_cursor.winid = -1;
193  g_software_cursor.xy[0] = -1;
194  g_software_cursor.xy[1] = -1;
195 }
196 
197 static void wm_software_cursor_draw_bitmap(const int event_xy[2],
198  const GHOST_CursorBitmapRef *bitmap)
199 {
201 
202  float gl_matrix[4][4];
204  "softeare_cursor", bitmap->data_size[0], bitmap->data_size[1], 1, GPU_RGBA8, NULL);
205  GPU_texture_update(texture, GPU_DATA_UBYTE, bitmap->data);
206  GPU_texture_filter_mode(texture, false);
207 
208  GPU_matrix_push();
209 
210  const int scale = (int)U.pixelsize;
211 
212  unit_m4(gl_matrix);
213 
214  gl_matrix[3][0] = event_xy[0] - (bitmap->hot_spot[0] * scale);
215  gl_matrix[3][1] = event_xy[1] - ((bitmap->data_size[1] - bitmap->hot_spot[1]) * scale);
216 
217  gl_matrix[0][0] = bitmap->data_size[0] * scale;
218  gl_matrix[1][1] = bitmap->data_size[1] * scale;
219 
220  GPU_matrix_mul(gl_matrix);
221 
222  GPUVertFormat *imm_format = immVertexFormat();
223  uint pos = GPU_vertformat_attr_add(imm_format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
224  uint texCoord = GPU_vertformat_attr_add(
225  imm_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
226 
227  /* Use 3D image for correct display of planar tracked images. */
229 
230  immBindTexture("image", texture);
231  immUniform1f("alpha", 1.0f);
232 
234 
235  immAttr2f(texCoord, 0.0f, 1.0f);
236  immVertex3f(pos, 0.0f, 0.0f, 0.0f);
237 
238  immAttr2f(texCoord, 1.0f, 1.0f);
239  immVertex3f(pos, 1.0f, 0.0f, 0.0f);
240 
241  immAttr2f(texCoord, 1.0f, 0.0f);
242  immVertex3f(pos, 1.0f, 1.0f, 0.0f);
243 
244  immAttr2f(texCoord, 0.0f, 0.0f);
245  immVertex3f(pos, 0.0f, 1.0f, 0.0f);
246 
247  immEnd();
248 
250 
251  GPU_matrix_pop();
252  GPU_texture_unbind(texture);
253  GPU_texture_free(texture);
254 
256 }
257 
258 static void wm_software_cursor_draw_crosshair(const int event_xy[2])
259 {
260  /* Draw a primitive cross-hair cursor.
261  * NOTE: the `win->cursor` could be used for drawing although it's complicated as some cursors
262  * are set by the operating-system, where the pixel information isn't easily available. */
263  const float unit = max_ff(U.dpi_fac, 1.0f);
267 
268  immUniformColor4f(1, 1, 1, 1);
269  {
270  const int ofs_line = (8 * unit);
271  const int ofs_size = (2 * unit);
272  immRecti(pos,
273  event_xy[0] - ofs_line,
274  event_xy[1] - ofs_size,
275  event_xy[0] + ofs_line,
276  event_xy[1] + ofs_size);
277  immRecti(pos,
278  event_xy[0] - ofs_size,
279  event_xy[1] - ofs_line,
280  event_xy[0] + ofs_size,
281  event_xy[1] + ofs_line);
282  }
283  immUniformColor4f(0, 0, 0, 1);
284  {
285  const int ofs_line = (7 * unit);
286  const int ofs_size = (1 * unit);
287  immRecti(pos,
288  event_xy[0] - ofs_line,
289  event_xy[1] - ofs_size,
290  event_xy[0] + ofs_line,
291  event_xy[1] + ofs_size);
292  immRecti(pos,
293  event_xy[0] - ofs_size,
294  event_xy[1] - ofs_line,
295  event_xy[0] + ofs_size,
296  event_xy[1] + ofs_line);
297  }
299 }
300 
301 static void wm_software_cursor_draw(wmWindow *win, const struct GrabState *grab_state)
302 {
303  int event_xy[2] = {UNPACK2(win->eventstate->xy)};
304 
305  if (grab_state->wrap_axis & GHOST_kAxisX) {
306  const int min = grab_state->bounds[0];
307  const int max = grab_state->bounds[2];
308  if (min != max) {
309  event_xy[0] = mod_i(event_xy[0] - min, max - min) + min;
310  }
311  }
312  if (grab_state->wrap_axis & GHOST_kAxisY) {
313  const int height = WM_window_pixels_y(win);
314  const int min = height - grab_state->bounds[1];
315  const int max = height - grab_state->bounds[3];
316  if (min != max) {
317  event_xy[1] = mod_i(event_xy[1] - max, min - max) + max;
318  }
319  }
320 
321  GHOST_CursorBitmapRef bitmap = {0};
322  if (GHOST_GetCursorBitmap(win->ghostwin, &bitmap) == GHOST_kSuccess) {
323  wm_software_cursor_draw_bitmap(event_xy, &bitmap);
324  }
325  else {
327  }
328 }
329 
332 /* -------------------------------------------------------------------- */
337 {
338  wmWindow *win = CTX_wm_window(C);
339 
340  wmViewport(&region->winrct);
341  UI_SetTheme(area->spacetype, region->regiontype);
342  region->type->draw_overlay(C, region);
343  wmWindowViewport(win);
344 }
345 
348 /* -------------------------------------------------------------------- */
352 static bool wm_draw_region_stereo_set(Main *bmain,
353  ScrArea *area,
354  ARegion *region,
355  eStereoViews sview)
356 {
357  /* We could detect better when stereo is actually needed, by inspecting the
358  * image in the image editor and sequencer. */
360  return false;
361  }
362 
363  switch (area->spacetype) {
364  case SPACE_IMAGE: {
365  if (region->regiontype == RGN_TYPE_WINDOW) {
366  SpaceImage *sima = area->spacedata.first;
367  sima->iuser.multiview_eye = sview;
368  return true;
369  }
370  break;
371  }
372  case SPACE_VIEW3D: {
373  if (region->regiontype == RGN_TYPE_WINDOW) {
374  View3D *v3d = area->spacedata.first;
375  if (v3d->camera && v3d->camera->type == OB_CAMERA) {
376  RegionView3D *rv3d = region->regiondata;
377  RenderEngine *engine = rv3d->render_engine;
378  if (engine && !(engine->type->flag & RE_USE_STEREO_VIEWPORT)) {
379  return false;
380  }
381 
382  Camera *cam = v3d->camera->data;
383  CameraBGImage *bgpic = cam->bg_images.first;
384  v3d->multiview_eye = sview;
385  if (bgpic) {
386  bgpic->iuser.multiview_eye = sview;
387  }
388  return true;
389  }
390  }
391  break;
392  }
393  case SPACE_NODE: {
394  if (region->regiontype == RGN_TYPE_WINDOW) {
395  SpaceNode *snode = area->spacedata.first;
396  if ((snode->flag & SNODE_BACKDRAW) && ED_node_is_compositor(snode)) {
397  Image *ima = BKE_image_ensure_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node");
398  ima->eye = sview;
399  return true;
400  }
401  }
402  break;
403  }
404  case SPACE_SEQ: {
405  SpaceSeq *sseq = area->spacedata.first;
406  sseq->multiview_eye = sview;
407 
408  if (region->regiontype == RGN_TYPE_PREVIEW) {
409  return true;
410  }
411  if (region->regiontype == RGN_TYPE_WINDOW) {
412  return (sseq->draw_flag & SEQ_DRAW_BACKDROP) != 0;
413  }
414  }
415  }
416 
417  return false;
418 }
419 
421  ScrArea *area,
422  ARegion *region,
423  bool tag_redraw)
424 {
425  if (region->gizmo_map == NULL) {
426  return;
427  }
428 
429  wmGizmoMap *gzmap = region->gizmo_map;
431  if (tag_redraw && (gzgroup->type->flag & WM_GIZMOGROUPTYPE_VR_REDRAWS)) {
432  ScrArea *ctx_area = CTX_wm_area(C);
433  ARegion *ctx_region = CTX_wm_region(C);
434 
436  CTX_wm_region_set(C, region);
437 
438  if (WM_gizmo_group_type_poll(C, gzgroup->type)) {
440  }
441 
442  /* Reset. */
443  CTX_wm_area_set(C, ctx_area);
444  CTX_wm_region_set(C, ctx_region);
445  }
446 
447  LISTBASE_FOREACH (wmGizmo *, gz, &gzgroup->gizmos) {
448  if (gz->do_draw) {
449  if (tag_redraw) {
451  }
452  gz->do_draw = false;
453  }
454  }
455  }
456 }
457 
459  struct Depsgraph *depsgraph,
460  ScrArea *area,
461  ARegion *region)
462 {
463  /* tag region for redraw from render engine preview running inside of it */
464  if (area->spacetype == SPACE_VIEW3D && region->regiontype == RGN_TYPE_WINDOW) {
465  RegionView3D *rv3d = region->regiondata;
466  RenderEngine *engine = rv3d->render_engine;
467  GPUViewport *viewport = WM_draw_region_get_viewport(region);
468 
469  if (engine && (engine->flag & RE_ENGINE_DO_DRAW)) {
470  View3D *v3d = area->spacedata.first;
471  rcti border_rect;
472 
473  /* do partial redraw when possible */
474  if (ED_view3d_calc_render_border(scene, depsgraph, v3d, region, &border_rect)) {
475  ED_region_tag_redraw_partial(region, &border_rect, false);
476  }
477  else {
479  }
480 
481  engine->flag &= ~RE_ENGINE_DO_DRAW;
482  }
483  else if (viewport && GPU_viewport_do_update(viewport)) {
485  }
486  }
487 }
488 
489 #ifdef WITH_XR_OPENXR
490 static void wm_region_test_xr_do_draw(const wmWindowManager *wm,
491  const ScrArea *area,
492  ARegion *region)
493 {
494  if ((area->spacetype == SPACE_VIEW3D) && (region->regiontype == RGN_TYPE_WINDOW)) {
495  if (ED_view3d_is_region_xr_mirror_active(wm, area->spacedata.first, region)) {
497  }
498  }
499 }
500 #endif
501 
502 static bool wm_region_use_viewport_by_type(short space_type, short region_type)
503 {
504  return (ELEM(space_type, SPACE_VIEW3D, SPACE_IMAGE, SPACE_NODE) &&
505  region_type == RGN_TYPE_WINDOW) ||
506  ((space_type == SPACE_SEQ) && ELEM(region_type, RGN_TYPE_PREVIEW, RGN_TYPE_WINDOW));
507 }
508 
510 {
511  return wm_region_use_viewport_by_type(area->spacetype, region->regiontype);
512 }
513 
514 static const char *wm_area_name(ScrArea *area)
515 {
516 #define SPACE_NAME(space) \
517  case space: \
518  return #space;
519 
520  switch (area->spacetype) {
540  default:
541  return "Unknown Space";
542  }
543 }
544 
547 /* -------------------------------------------------------------------- */
553 typedef struct WindowDrawCB {
554  struct WindowDrawCB *next, *prev;
555 
556  void (*draw)(const struct wmWindow *, void *);
557  void *customdata;
558 
560 
562  void (*draw)(const struct wmWindow *, void *),
563  void *customdata)
564 {
565  WindowDrawCB *wdc = MEM_callocN(sizeof(*wdc), "WindowDrawCB");
566 
567  BLI_addtail(&win->drawcalls, wdc);
568  wdc->draw = draw;
569  wdc->customdata = customdata;
570 
571  return wdc;
572 }
573 
574 void WM_draw_cb_exit(wmWindow *win, void *handle)
575 {
576  LISTBASE_FOREACH (WindowDrawCB *, wdc, &win->drawcalls) {
577  if (wdc == (WindowDrawCB *)handle) {
578  BLI_remlink(&win->drawcalls, wdc);
579  MEM_freeN(wdc);
580  return;
581  }
582  }
583 }
584 
585 static void wm_draw_callbacks(wmWindow *win)
586 {
587  LISTBASE_FOREACH (WindowDrawCB *, wdc, &win->drawcalls) {
588  wdc->draw(win, wdc->customdata);
589  }
590 }
591 
594 /* -------------------------------------------------------------------- */
604 {
605  if (region->draw_buffer) {
606  if (region->draw_buffer->viewport) {
608  }
609  if (region->draw_buffer->offscreen) {
611  }
612 
613  MEM_freeN(region->draw_buffer);
614  region->draw_buffer = NULL;
615  }
616 }
617 
619 {
620  /* Setup offscreen color texture for drawing. */
621  GPUTexture *texture = GPU_offscreen_color_texture(offscreen);
622 
623  /* No mipmaps or filtering. */
624  GPU_texture_mipmap_mode(texture, false, false);
625 }
626 
627 static void wm_draw_region_buffer_create(ARegion *region, bool stereo, bool use_viewport)
628 {
629  if (region->draw_buffer) {
630  if (region->draw_buffer->stereo != stereo) {
631  /* Free draw buffer on stereo changes. */
633  }
634  else {
635  /* Free offscreen buffer on size changes. Viewport auto resizes. */
636  GPUOffScreen *offscreen = region->draw_buffer->offscreen;
637  if (offscreen && (GPU_offscreen_width(offscreen) != region->winx ||
638  GPU_offscreen_height(offscreen) != region->winy)) {
640  }
641  }
642  }
643 
644  if (!region->draw_buffer) {
645  if (use_viewport) {
646  /* Allocate viewport which includes an offscreen buffer with depth
647  * multisample, etc. */
648  region->draw_buffer = MEM_callocN(sizeof(wmDrawBuffer), "wmDrawBuffer");
649  region->draw_buffer->viewport = stereo ? GPU_viewport_stereo_create() :
651  }
652  else {
653  /* Allocate offscreen buffer if it does not exist. This one has no
654  * depth or multisample buffers. 3D view creates own buffers with
655  * the data it needs. */
656  GPUOffScreen *offscreen = GPU_offscreen_create(
657  region->winx, region->winy, false, GPU_RGBA8, NULL);
658  if (!offscreen) {
659  WM_report(RPT_ERROR, "Region could not be drawn!");
660  return;
661  }
662 
664 
665  region->draw_buffer = MEM_callocN(sizeof(wmDrawBuffer), "wmDrawBuffer");
666  region->draw_buffer->offscreen = offscreen;
667  }
668 
669  region->draw_buffer->bound_view = -1;
670  region->draw_buffer->stereo = stereo;
671  }
672 }
673 
674 static bool wm_draw_region_bind(bContext *C, ARegion *region, int view)
675 {
676  if (!region->draw_buffer) {
677  return true;
678  }
679 
680  if (region->draw_buffer->viewport) {
681  if (G.is_rendering && C != NULL && U.experimental.use_draw_manager_acquire_lock) {
683  RenderEngineType *render_engine_type = RE_engines_find(scene->r.engine);
684  if (RE_engine_is_opengl(render_engine_type)) {
685  /* Do not try to acquire the viewport as this would be locking at the moment.
686  * But tag the viewport to update after the rendering finishes. */
688  return false;
689  }
690  }
691 
692  GPU_viewport_bind(region->draw_buffer->viewport, view, &region->winrct);
693  }
694  else {
695  GPU_offscreen_bind(region->draw_buffer->offscreen, false);
696 
697  /* For now scissor is expected by region drawing, we could disable it
698  * and do the enable/disable in the specific cases that setup scissor. */
699  GPU_scissor_test(true);
700  GPU_scissor(0, 0, region->winx, region->winy);
701  }
702 
703  region->draw_buffer->bound_view = view;
704  return true;
705 }
706 
707 static void wm_draw_region_unbind(ARegion *region)
708 {
709  if (!region->draw_buffer) {
710  return;
711  }
712 
713  region->draw_buffer->bound_view = -1;
714 
715  if (region->draw_buffer->viewport) {
717  }
718  else {
719  GPU_scissor_test(false);
720  GPU_offscreen_unbind(region->draw_buffer->offscreen, false);
721  }
722 }
723 
724 static void wm_draw_region_blit(ARegion *region, int view)
725 {
726  if (!region->draw_buffer) {
727  return;
728  }
729 
730  if (view == -1) {
731  /* Non-stereo drawing. */
732  view = 0;
733  }
734  else if (view > 0) {
735  if (region->draw_buffer->viewport == NULL) {
736  /* Region does not need stereo or failed to allocate stereo buffers. */
737  view = 0;
738  }
739  }
740 
741  if (region->draw_buffer->viewport) {
743  }
744  else {
746  region->draw_buffer->offscreen, region->winrct.xmin, region->winrct.ymin);
747  }
748 }
749 
751 {
752  if (!region->draw_buffer) {
753  return NULL;
754  }
755 
756  GPUViewport *viewport = region->draw_buffer->viewport;
757  if (viewport) {
758  return GPU_viewport_color_texture(viewport, view);
759  }
761 }
762 
763 void wm_draw_region_blend(ARegion *region, int view, bool blend)
764 {
765  if (!region->draw_buffer) {
766  return;
767  }
768 
769  /* Alpha is always 1, except when blend timer is running. */
770  float alpha = ED_region_blend_alpha(region);
771  if (alpha <= 0.0f) {
772  return;
773  }
774 
775  if (!blend) {
776  alpha = 1.0f;
777  }
778 
779  /* wmOrtho for the screen has this same offset */
780  const float halfx = GLA_PIXEL_OFS / (BLI_rcti_size_x(&region->winrct) + 1);
781  const float halfy = GLA_PIXEL_OFS / (BLI_rcti_size_y(&region->winrct) + 1);
782 
783  rcti rect_geo = region->winrct;
784  rect_geo.xmax += 1;
785  rect_geo.ymax += 1;
786 
787  rctf rect_tex;
788  rect_tex.xmin = halfx;
789  rect_tex.ymin = halfy;
790  rect_tex.xmax = 1.0f + halfx;
791  rect_tex.ymax = 1.0f + halfy;
792 
793  float alpha_easing = 1.0f - alpha;
794  alpha_easing = 1.0f - alpha_easing * alpha_easing;
795 
796  /* Slide vertical panels */
797  float ofs_x = BLI_rcti_size_x(&region->winrct) * (1.0f - alpha_easing);
799  rect_geo.xmin += ofs_x;
800  rect_tex.xmax *= alpha_easing;
801  alpha = 1.0f;
802  }
803  else if (RGN_ALIGN_ENUM_FROM_MASK(region->alignment) == RGN_ALIGN_LEFT) {
804  rect_geo.xmax -= ofs_x;
805  rect_tex.xmin += 1.0f - alpha_easing;
806  alpha = 1.0f;
807  }
808 
809  /* Not the same layout as rectf/recti. */
810  const float rectt[4] = {rect_tex.xmin, rect_tex.ymin, rect_tex.xmax, rect_tex.ymax};
811  const float rectg[4] = {rect_geo.xmin, rect_geo.ymin, rect_geo.xmax, rect_geo.ymax};
812 
813  if (blend) {
814  /* Regions drawn offscreen have premultiplied alpha. */
816  }
817 
818  /* setup actual texture */
819  GPUTexture *texture = wm_draw_region_texture(region, view);
820 
822  GPU_shader_bind(shader);
823 
824  int color_loc = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_COLOR);
825  int rect_tex_loc = GPU_shader_get_uniform(shader, "rect_icon");
826  int rect_geo_loc = GPU_shader_get_uniform(shader, "rect_geom");
827  int texture_bind_loc = GPU_shader_get_texture_binding(shader, "image");
828 
829  GPU_texture_bind(texture, texture_bind_loc);
830 
831  GPU_shader_uniform_vector(shader, rect_tex_loc, 4, 1, rectt);
832  GPU_shader_uniform_vector(shader, rect_geo_loc, 4, 1, rectg);
833  GPU_shader_uniform_vector(shader, color_loc, 4, 1, (const float[4]){1, 1, 1, 1});
834 
836  GPU_batch_set_shader(quad, shader);
838 
839  GPU_texture_unbind(texture);
840 
841  if (blend) {
843  }
844 }
845 
847 {
848  if (!region->draw_buffer) {
849  return NULL;
850  }
851 
852  GPUViewport *viewport = region->draw_buffer->viewport;
853  return viewport;
854 }
855 
857 {
858  if (!region->draw_buffer || region->draw_buffer->bound_view == -1) {
859  return NULL;
860  }
861 
862  GPUViewport *viewport = region->draw_buffer->viewport;
863  return viewport;
864 }
865 
866 static void wm_draw_window_offscreen(bContext *C, wmWindow *win, bool stereo)
867 {
868  Main *bmain = CTX_data_main(C);
870  bScreen *screen = WM_window_get_active_screen(win);
871 
872  /* Draw screen areas into own frame buffer. */
873  ED_screen_areas_iter (win, screen, area) {
876 
877  /* Compute UI layouts for dynamically size regions. */
878  LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
879  /* Dynamic region may have been flagged as too small because their size on init is 0.
880  * ARegion.visible is false then, as expected. The layout should still be created then, so
881  * the region size can be updated (it may turn out to be not too small then). */
882  const bool ignore_visibility = (region->flag & RGN_FLAG_DYNAMIC_SIZE) &&
883  (region->flag & RGN_FLAG_TOO_SMALL) &&
884  !(region->flag & RGN_FLAG_HIDDEN);
885 
886  if ((region->visible || ignore_visibility) && region->do_draw && region->type &&
887  region->type->layout) {
888  CTX_wm_region_set(C, region);
889  ED_region_do_layout(C, region);
891  }
892  }
893 
895 
896  if (area->flag & AREA_FLAG_ACTIVE_TOOL_UPDATE) {
897  if ((1 << area->spacetype) & WM_TOOLSYSTEM_SPACE_MASK) {
899  }
901  }
902 
903  /* Then do actual drawing of regions. */
904  LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
905  if (!region->visible || !region->do_draw) {
906  continue;
907  }
908 
909  CTX_wm_region_set(C, region);
910  bool use_viewport = WM_region_use_viewport(area, region);
911 
912  GPU_debug_group_begin(use_viewport ? "Viewport" : "ARegion");
913 
914  if (stereo && wm_draw_region_stereo_set(bmain, area, region, STEREO_LEFT_ID)) {
915  wm_draw_region_buffer_create(region, true, use_viewport);
916  bool views_valid = true;
917 
918  for (int view = 0; view < 2; view++) {
919  eStereoViews sview;
920  if (view == 0) {
921  sview = STEREO_LEFT_ID;
922  }
923  else {
924  sview = STEREO_RIGHT_ID;
925  wm_draw_region_stereo_set(bmain, area, region, sview);
926  }
927 
928  if (wm_draw_region_bind(C, region, view)) {
929  ED_region_do_draw(C, region);
930  wm_draw_region_unbind(region);
931  }
932  else {
933  views_valid = false;
934  }
935  }
936  if (use_viewport && views_valid) {
937  GPUViewport *viewport = region->draw_buffer->viewport;
939  }
940  }
941  else {
942  wm_draw_region_buffer_create(region, false, use_viewport);
943  if (wm_draw_region_bind(C, region, 0)) {
944  ED_region_do_draw(C, region);
945  wm_draw_region_unbind(region);
946  }
947  }
948 
950 
951  region->do_draw = false;
953  }
954 
956 
958  }
959 
960  /* Draw menus into their own frame-buffer. */
961  LISTBASE_FOREACH (ARegion *, region, &screen->regionbase) {
962  if (!region->visible) {
963  continue;
964  }
965  CTX_wm_menu_set(C, region);
966 
967  GPU_debug_group_begin("Menu");
968 
969  if (region->type && region->type->layout) {
970  /* UI code reads the OpenGL state, but we have to refresh
971  * the UI layout beforehand in case the menu size changes. */
972  wmViewport(&region->winrct);
973  region->type->layout(C, region);
974  }
975 
976  wm_draw_region_buffer_create(region, false, false);
977  if (wm_draw_region_bind(C, region, 0)) {
978  GPU_clear_color(0.0f, 0.0f, 0.0f, 0.0f);
979  ED_region_do_draw(C, region);
980  wm_draw_region_unbind(region);
981  }
982 
984 
985  region->do_draw = false;
987  }
988 }
989 
991 {
993  bScreen *screen = WM_window_get_active_screen(win);
994 
995  GPU_debug_group_begin("Window Redraw");
996 
997  /* Draw into the window frame-buffer, in full window coordinates. */
998  wmWindowViewport(win);
999 
1000  /* We draw on all pixels of the windows so we don't need to clear them before.
1001  * Actually this is only a problem when resizing the window.
1002  * If it becomes a problem we should clear only when window size changes. */
1003 #if 0
1004  GPU_clear_color(0, 0, 0, 0);
1005 #endif
1006 
1007  /* Blit non-overlapping area regions. */
1008  ED_screen_areas_iter (win, screen, area) {
1009  LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
1010  if (!region->visible) {
1011  continue;
1012  }
1013 
1014  if (region->overlap == false) {
1015  /* Blit from off-screen buffer. */
1016  wm_draw_region_blit(region, view);
1017  }
1018  }
1019  }
1020 
1021  /* Draw overlays and paint cursors. */
1022  ED_screen_areas_iter (win, screen, area) {
1023  LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
1024  if (!region->visible) {
1025  continue;
1026  }
1027  const bool do_paint_cursor = (wm->paintcursors.first && region == screen->active_region);
1028  const bool do_draw_overlay = (region->type && region->type->draw_overlay);
1029  if (!(do_paint_cursor || do_draw_overlay)) {
1030  continue;
1031  }
1032 
1034  CTX_wm_region_set(C, region);
1035  if (do_draw_overlay) {
1036  wm_region_draw_overlay(C, area, region);
1037  }
1038  if (do_paint_cursor) {
1039  wm_paintcursor_draw(C, area, region);
1040  }
1043  }
1044  }
1045  wmWindowViewport(win);
1046 
1047  /* Blend in overlapping area regions */
1048  ED_screen_areas_iter (win, screen, area) {
1049  LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
1050  if (!region->visible) {
1051  continue;
1052  }
1053  if (region->overlap) {
1054  wm_draw_region_blend(region, 0, true);
1055  }
1056  }
1057  }
1058 
1059  /* After area regions so we can do area 'overlay' drawing. */
1060  UI_SetTheme(0, 0);
1061  ED_screen_draw_edges(win);
1062  wm_draw_callbacks(win);
1063  wmWindowViewport(win);
1064 
1065  /* Blend in floating regions (menus). */
1066  LISTBASE_FOREACH (ARegion *, region, &screen->regionbase) {
1067  if (!region->visible) {
1068  continue;
1069  }
1070  wm_draw_region_blend(region, 0, true);
1071  }
1072 
1073  /* always draw, not only when screen tagged */
1074  if (win->gesture.first) {
1075  wm_gesture_draw(win);
1076  wmWindowViewport(win);
1077  }
1078 
1079  /* Needs pixel coords in screen. */
1080  if (wm->drags.first) {
1081  wm_drags_draw(C, win);
1082  wmWindowViewport(win);
1083  }
1084 
1085  if (wm_software_cursor_needed()) {
1086  struct GrabState grab_state;
1087  if (wm_software_cursor_needed_for_window(win, &grab_state)) {
1088  wm_software_cursor_draw(win, &grab_state);
1090  }
1091  else {
1093  }
1094  }
1095 
1097 }
1098 
1099 static void wm_draw_window(bContext *C, wmWindow *win)
1100 {
1102 
1103  bScreen *screen = WM_window_get_active_screen(win);
1104  bool stereo = WM_stereo3d_enabled(win, false);
1105 
1106  /* Avoid any BGL call issued before this to alter the window drawin. */
1107  GPU_bgl_end();
1108 
1109  /* Draw area regions into their own frame-buffer. This way we can redraw
1110  * the areas that need it, and blit the rest from existing frame-buffers. */
1111  wm_draw_window_offscreen(C, win, stereo);
1112 
1113  /* Now we draw into the window frame-buffer, in full window coordinates. */
1114  if (!stereo) {
1115  /* Regular mono drawing. */
1116  wm_draw_window_onscreen(C, win, -1);
1117  }
1119  /* For page-flip we simply draw to both back buffers. */
1121  wm_draw_window_onscreen(C, win, 1);
1122 
1124  wm_draw_window_onscreen(C, win, 0);
1125  }
1127  /* For anaglyph and interlace, we draw individual regions with
1128  * stereo frame-buffers using different shaders. */
1129  wm_draw_window_onscreen(C, win, -1);
1130  }
1131  else {
1132  /* For side-by-side and top-bottom, we need to render each view to an
1133  * an off-screen texture and then draw it. This used to happen for all
1134  * stereo methods, but it's less efficient than drawing directly. */
1135  const int width = WM_window_pixels_x(win);
1136  const int height = WM_window_pixels_y(win);
1137  GPUOffScreen *offscreen = GPU_offscreen_create(width, height, false, GPU_RGBA8, NULL);
1138 
1139  if (offscreen) {
1140  GPUTexture *texture = GPU_offscreen_color_texture(offscreen);
1142 
1143  for (int view = 0; view < 2; view++) {
1144  /* Draw view into offscreen buffer. */
1145  GPU_offscreen_bind(offscreen, false);
1147  GPU_offscreen_unbind(offscreen, false);
1148 
1149  /* Draw offscreen buffer to screen. */
1150  GPU_texture_bind(texture, 0);
1151 
1152  wmWindowViewport(win);
1155  }
1156  else {
1158  }
1159 
1160  GPU_texture_unbind(texture);
1161  }
1162 
1163  GPU_offscreen_free(offscreen);
1164  }
1165  else {
1166  /* Still draw something in case of allocation failure. */
1167  wm_draw_window_onscreen(C, win, 0);
1168  }
1169  }
1170 
1171  screen->do_draw = false;
1172 
1174 }
1175 
1180 {
1183 
1184  GPU_context_begin_frame(surface->gpu_ctx);
1185 
1186  surface->draw(C);
1187 
1188  GPU_context_end_frame(surface->gpu_ctx);
1189 
1190  /* Avoid interference with window drawable */
1192 }
1193 
1196 /* -------------------------------------------------------------------- */
1200 /* quick test to prevent changing window drawable */
1202 {
1203  const wmWindowManager *wm = CTX_wm_manager(C);
1205  ViewLayer *view_layer = WM_window_get_active_view_layer(win);
1206  struct Depsgraph *depsgraph = BKE_scene_ensure_depsgraph(bmain, scene, view_layer);
1207  bScreen *screen = WM_window_get_active_screen(win);
1208  bool do_draw = false;
1209 
1210  LISTBASE_FOREACH (ARegion *, region, &screen->regionbase) {
1211  if (region->do_draw_paintcursor) {
1212  screen->do_draw_paintcursor = true;
1213  region->do_draw_paintcursor = false;
1214  }
1215  if (region->visible && region->do_draw) {
1216  do_draw = true;
1217  }
1218  }
1219 
1220  ED_screen_areas_iter (win, screen, area) {
1221  LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
1222  wm_region_test_gizmo_do_draw(C, area, region, true);
1224 #ifdef WITH_XR_OPENXR
1225  wm_region_test_xr_do_draw(wm, area, region);
1226 #endif
1227 
1228  if (region->visible && region->do_draw) {
1229  do_draw = true;
1230  }
1231  }
1232  }
1233 
1234  if (do_draw) {
1235  return true;
1236  }
1237 
1238  if (screen->do_refresh) {
1239  return true;
1240  }
1241  if (screen->do_draw) {
1242  return true;
1243  }
1244  if (screen->do_draw_gesture) {
1245  return true;
1246  }
1247  if (screen->do_draw_paintcursor) {
1248  return true;
1249  }
1250  if (screen->do_draw_drag) {
1251  return true;
1252  }
1253 
1254  if (wm_software_cursor_needed()) {
1255  struct GrabState grab_state;
1256  if (wm_software_cursor_needed_for_window(win, &grab_state)) {
1257  if (wm_software_cursor_motion_test(win)) {
1258  return true;
1259  }
1260  }
1261  else {
1262  /* Detect the edge case when the previous draw used the software cursor but this one doesn't,
1263  * it's important to redraw otherwise the software cursor will remain displayed. */
1264  if (g_software_cursor.winid != -1) {
1265  return true;
1266  }
1267  }
1268  }
1269 
1270 #ifndef WITH_XR_OPENXR
1271  UNUSED_VARS(wm);
1272 #endif
1273 
1274  return false;
1275 }
1276 
1277 /* Clear drawing flags, after drawing is complete so any draw flags set during
1278  * drawing don't cause any additional redraws. */
1280 {
1281  bScreen *screen = WM_window_get_active_screen(win);
1282 
1283  ED_screen_areas_iter (win, screen, area) {
1284  LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
1285  wm_region_test_gizmo_do_draw(C, area, region, false);
1286  }
1287  }
1288 
1289  screen->do_draw_gesture = false;
1290  screen->do_draw_paintcursor = false;
1291  screen->do_draw_drag = false;
1292 }
1293 
1295 {
1296  if (win) {
1297  bScreen *screen = WM_window_get_active_screen(win);
1298  screen->do_draw_paintcursor = true;
1299  }
1300 }
1301 
1303 {
1304  Main *bmain = CTX_data_main(C);
1306 
1308 
1309  GPU_render_begin();
1310  GPU_render_step();
1311 
1313 
1314  LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
1315 #ifdef WIN32
1317 
1319  /* do not update minimized windows, gives issues on Intel (see T33223)
1320  * and AMD (see T50856). it seems logical to skip update for invisible
1321  * window anyway.
1322  */
1323  continue;
1324  }
1325 #endif
1326 
1327  CTX_wm_window_set(C, win);
1328 
1329  if (wm_draw_update_test_window(bmain, C, win)) {
1330  bScreen *screen = WM_window_get_active_screen(win);
1331 
1332  /* sets context window+screen */
1333  wm_window_make_drawable(wm, win);
1334 
1335  /* notifiers for screen redraw */
1336  ED_screen_ensure_updated(wm, win, screen);
1337 
1338  wm_draw_window(C, win);
1340 
1342  }
1343  }
1344 
1346 
1347  /* Draw non-windows (surfaces) */
1349 
1350  GPU_render_end();
1352 }
1353 
1355 {
1356  bScreen *screen = WM_window_get_active_screen(win);
1357  screen->do_draw = true;
1358 }
1359 
1360 void WM_draw_region_free(ARegion *region, bool hide)
1361 {
1363  if (hide) {
1364  region->visible = 0;
1365  }
1366 }
1367 
1369 {
1370  /* Function for redraw timer benchmark. */
1371  bool use_viewport = WM_region_use_viewport(area, region);
1372  wm_draw_region_buffer_create(region, false, use_viewport);
1373  if (wm_draw_region_bind(C, region, 0)) {
1374  ED_region_do_draw(C, region);
1375  wm_draw_region_unbind(region);
1376  region->do_draw = false;
1377  }
1378 }
1379 
1381 {
1382  wmWindow *win_prev = CTX_wm_window(C);
1383  ScrArea *area_prev = CTX_wm_area(C);
1384  ARegion *region_prev = CTX_wm_region(C);
1385 
1386  wm_draw_update(C);
1387 
1388  CTX_wm_window_set(C, win_prev);
1389  CTX_wm_area_set(C, area_prev);
1390  CTX_wm_region_set(C, region_prev);
1391 }
1392 
1395 /* -------------------------------------------------------------------- */
1405 void WM_draw_region_viewport_ensure(ARegion *region, short space_type)
1406 {
1407  bool use_viewport = wm_region_use_viewport_by_type(space_type, region->regiontype);
1408  wm_draw_region_buffer_create(region, false, use_viewport);
1409 }
1410 
1412 {
1413  wm_draw_region_bind(NULL, region, 0);
1414 }
1415 
1417 {
1418  wm_draw_region_unbind(region);
1419 }
1420 
struct WorkSpace * CTX_wm_workspace(const bContext *C)
Definition: context.c:728
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:738
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
void CTX_wm_region_set(bContext *C, struct ARegion *region)
Definition: context.c:1009
void CTX_wm_menu_set(bContext *C, struct ARegion *menu)
Definition: context.c:1020
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:713
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1100
void CTX_wm_window_set(bContext *C, struct wmWindow *win)
Definition: context.c:966
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:749
void CTX_wm_area_set(bContext *C, struct ScrArea *area)
Definition: context.c:997
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1074
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:723
void BKE_image_free_unused_gpu_textures(void)
Definition: image_gpu.cc:481
struct Image * BKE_image_ensure_viewer(struct Main *bmain, int type, const char *name)
struct Depsgraph * BKE_scene_ensure_depsgraph(struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer)
Definition: scene.cc:3456
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
Definition: BLI_listbase.h:354
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:100
MINLINE float max_ff(float a, float b)
MINLINE int mod_i(int i, int n)
void unit_m4(float m[4][4])
Definition: rct.c:1090
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition: BLI_rect.h:190
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition: BLI_rect.h:186
unsigned int uint
Definition: BLI_sys_types.h:67
#define UNPACK2(a)
#define UNUSED_VARS(...)
#define UNUSED(x)
#define UNLIKELY(x)
#define ELEM(...)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
@ IMA_TYPE_COMPOSITE
These structs are the foundation for all linked lists in the library system.
Object is a sort of wrapper for general info.
@ OB_CAMERA
@ S3D_DISPLAY_ANAGLYPH
@ S3D_DISPLAY_INTERLACE
@ S3D_DISPLAY_SIDEBYSIDE
@ S3D_DISPLAY_PAGEFLIP
eStereoViews
@ STEREO_LEFT_ID
@ STEREO_RIGHT_ID
@ AREA_FLAG_ACTIVE_TOOL_UPDATE
#define RGN_ALIGN_ENUM_FROM_MASK(align)
@ RGN_FLAG_DYNAMIC_SIZE
@ RGN_FLAG_HIDDEN
@ RGN_FLAG_TOO_SMALL
@ RGN_TYPE_WINDOW
@ RGN_TYPE_PREVIEW
@ RGN_ALIGN_LEFT
@ RGN_ALIGN_RIGHT
#define RGN_TYPE_ANY
@ SNODE_BACKDRAW
@ SPACE_TEXT
@ SPACE_CLIP
@ SPACE_ACTION
@ SPACE_CONSOLE
@ SPACE_OUTLINER
@ SPACE_STATUSBAR
@ SPACE_TOPBAR
@ SPACE_NODE
@ SPACE_USERPREF
@ SPACE_FILE
@ SPACE_PROPERTIES
@ SPACE_NLA
@ SPACE_SEQ
@ SPACE_EMPTY
@ SPACE_SCRIPT
@ SPACE_IMAGE
@ SPACE_GRAPH
@ SPACE_VIEW3D
@ SPACE_INFO
@ SEQ_DRAW_BACKDROP
#define SPACE_TYPE_ANY
bool ED_node_is_compositor(struct SpaceNode *snode)
Definition: node_edit.cc:466
void ED_area_update_region_sizes(struct wmWindowManager *wm, struct wmWindow *win, struct ScrArea *area)
Definition: area.c:1862
void ED_region_do_layout(struct bContext *C, struct ARegion *region)
Definition: area.c:494
float ED_region_blend_alpha(struct ARegion *region)
Definition: screen_ops.c:5311
void ED_region_tag_redraw_partial(struct ARegion *region, const struct rcti *rct, bool rebuild)
void ED_region_tag_redraw_editor_overlays(struct ARegion *region)
Definition: area.c:690
#define ED_screen_areas_iter(win, screen, area_name)
Definition: ED_screen.h:267
void ED_region_tag_redraw_no_rebuild(struct ARegion *region)
Definition: area.c:674
void ED_screen_draw_edges(struct wmWindow *win)
Definition: screen_draw.c:151
void ED_region_do_draw(struct bContext *C, struct ARegion *region)
Definition: area.c:517
void ED_screen_ensure_updated(struct wmWindowManager *wm, struct wmWindow *win, struct bScreen *screen)
Definition: screen_edit.c:670
bool ED_view3d_calc_render_border(const struct Scene *scene, struct Depsgraph *depsgraph, struct View3D *v3d, struct ARegion *region, struct rcti *rect)
static AppView * view
GHOST C-API function and type declarations.
GHOST_TWindowState GHOST_GetWindowState(GHOST_WindowHandle windowhandle)
bool GHOST_SupportsCursorWarp(void)
void GHOST_GetCursorGrabState(GHOST_WindowHandle windowhandle, GHOST_TGrabCursorMode *r_mode, GHOST_TAxisFlag *r_axis_flag, int r_bounds[4], bool *r_use_software_cursor)
GHOST_TSuccess GHOST_GetCursorBitmap(GHOST_WindowHandle windowhandle, GHOST_CursorBitmapRef *bitmap)
bool GHOST_GetCursorVisibility(GHOST_WindowHandle windowhandle)
GHOST_TWindowState
Definition: GHOST_Types.h:129
@ GHOST_kWindowStateMinimized
Definition: GHOST_Types.h:132
GHOST_TAxisFlag
Definition: GHOST_Types.h:420
@ GHOST_kAxisX
Definition: GHOST_Types.h:423
@ GHOST_kAxisY
Definition: GHOST_Types.h:424
@ GHOST_kSuccess
Definition: GHOST_Types.h:74
GHOST_TGrabCursorMode
Definition: GHOST_Types.h:404
@ GHOST_kGrabWrap
Definition: GHOST_Types.h:410
@ GHOST_kGrabHide
Definition: GHOST_Types.h:415
GPUBatch
Definition: GPU_batch.h:78
void GPU_batch_set_shader(GPUBatch *batch, GPUShader *shader)
Definition: gpu_batch.cc:211
void GPU_batch_draw(GPUBatch *batch)
Definition: gpu_batch.cc:223
struct GPUBatch * GPU_batch_preset_quad(void)
void GPU_context_main_lock(void)
Definition: gpu_context.cc:171
void GPU_render_begin(void)
Definition: gpu_context.cc:190
void GPU_context_begin_frame(GPUContext *ctx)
Definition: gpu_context.cc:147
void GPU_context_end_frame(GPUContext *ctx)
Definition: gpu_context.cc:155
void GPU_context_main_unlock(void)
Definition: gpu_context.cc:176
void GPU_render_end(void)
Definition: gpu_context.cc:196
void GPU_render_step(void)
Definition: gpu_context.cc:202
void GPU_debug_group_end(void)
Definition: gpu_debug.cc:32
void GPU_debug_group_begin(const char *name)
Definition: gpu_debug.cc:21
@ GPU_BACKBUFFER_LEFT
@ GPU_BACKBUFFER_RIGHT
void immUniformColor4f(float r, float g, float b, float a)
void immUnbindProgram(void)
void immBindBuiltinProgram(eGPUBuiltinShader shader_id)
void immBindTexture(const char *name, GPUTexture *tex)
void immVertex3f(uint attr_id, float x, float y, float z)
void immUniform1f(const char *name, float x)
GPUVertFormat * immVertexFormat(void)
void immAttr2f(uint attr_id, float x, float y)
void immBegin(GPUPrimType, uint vertex_len)
void immEnd(void)
void immRecti(uint pos, int x1, int y1, int x2, int y2)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
void GPU_matrix_pop(void)
Definition: gpu_matrix.cc:126
#define GPU_matrix_mul(x)
Definition: GPU_matrix.h:224
void GPU_matrix_push(void)
Definition: gpu_matrix.cc:119
@ GPU_PRIM_TRI_FAN
Definition: GPU_primitive.h:25
int GPU_shader_get_uniform(GPUShader *shader, const char *name)
Definition: gpu_shader.cc:559
struct GPUShader GPUShader
Definition: GPU_shader.h:20
void GPU_shader_uniform_vector(GPUShader *shader, int location, int length, int arraysize, const float *value)
Definition: gpu_shader.cc:630
GPUShader * GPU_shader_get_builtin_shader(eGPUBuiltinShader shader)
void GPU_shader_bind(GPUShader *shader)
Definition: gpu_shader.cc:491
@ GPU_UNIFORM_COLOR
Definition: GPU_shader.h:129
@ GPU_SHADER_3D_IMAGE_MODULATE_ALPHA
Definition: GPU_shader.h:300
@ GPU_SHADER_2D_UNIFORM_COLOR
Definition: GPU_shader.h:201
@ GPU_SHADER_2D_IMAGE_RECT_COLOR
Definition: GPU_shader.h:219
int GPU_shader_get_texture_binding(GPUShader *shader, const char *name)
Definition: gpu_shader.cc:599
int GPU_shader_get_builtin_uniform(GPUShader *shader, int builtin)
Definition: gpu_shader.cc:566
@ GPU_BLEND_NONE
Definition: GPU_state.h:60
@ GPU_BLEND_ALPHA
Definition: GPU_state.h:62
@ GPU_BLEND_ALPHA_PREMULT
Definition: GPU_state.h:63
void GPU_blend(eGPUBlend blend)
Definition: gpu_state.cc:39
void GPU_bgl_end(void)
Definition: gpu_state.cc:346
void GPU_scissor_test(bool enable)
Definition: gpu_state.cc:180
void GPU_scissor(int x, int y, int width, int height)
Definition: gpu_state.cc:185
struct GPUTexture GPUTexture
Definition: GPU_texture.h:17
void GPU_texture_mipmap_mode(GPUTexture *tex, bool use_mipmap, bool use_filter)
Definition: gpu_texture.cc:527
@ GPU_DATA_UBYTE
Definition: GPU_texture.h:174
void GPU_texture_update(GPUTexture *tex, eGPUDataFormat data_format, const void *data)
Definition: gpu_texture.cc:444
void GPU_texture_free(GPUTexture *tex)
Definition: gpu_texture.cc:564
void GPU_texture_filter_mode(GPUTexture *tex, bool use_filter)
Definition: gpu_texture.cc:518
void GPU_texture_unbind(GPUTexture *tex)
Definition: gpu_texture.cc:472
GPUTexture * GPU_texture_create_2d(const char *name, int w, int h, int mip_len, eGPUTextureFormat format, const float *data)
Definition: gpu_texture.cc:291
@ GPU_RGBA8
Definition: GPU_texture.h:87
void GPU_texture_bind(GPUTexture *tex, int unit)
Definition: gpu_texture.cc:466
@ GPU_FETCH_FLOAT
@ GPU_FETCH_INT_TO_FLOAT
uint GPU_vertformat_attr_add(GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
@ GPU_COMP_F32
@ GPU_COMP_I32
void GPU_viewport_bind(GPUViewport *viewport, int view, const rcti *rect)
Definition: gpu_viewport.c:170
GPUTexture * GPU_viewport_color_texture(GPUViewport *viewport, int view)
Definition: gpu_viewport.c:559
void GPU_viewport_draw_to_screen(GPUViewport *viewport, int view, const rcti *rect)
Definition: gpu_viewport.c:503
GPUViewport * GPU_viewport_create(void)
Definition: gpu_viewport.c:98
bool GPU_viewport_do_update(GPUViewport *viewport)
Definition: gpu_viewport.c:91
GPUViewport * GPU_viewport_stereo_create(void)
Definition: gpu_viewport.c:107
void GPU_viewport_free(GPUViewport *viewport)
Definition: gpu_viewport.c:585
void GPU_viewport_stereo_composite(GPUViewport *viewport, Stereo3dFormat *stereo_format)
Definition: gpu_viewport.c:259
void GPU_viewport_tag_update(GPUViewport *viewport)
Definition: gpu_viewport.c:86
void GPU_viewport_unbind(GPUViewport *viewport)
Read Guarded memory(de)allocation.
#define RE_USE_STEREO_VIEWPORT
Definition: RE_engine.h:51
#define RE_ENGINE_DO_DRAW
Definition: RE_engine.h:60
#define C
Definition: RandGen.cpp:25
void UI_SetTheme(int spacetype, int regionid)
Definition: resources.c:1045
@ WM_GIZMOGROUPTYPE_VR_REDRAWS
#define WM_TOOLSYSTEM_SPACE_MASK
Definition: WM_toolsystem.h:29
unsigned int U
Definition: btGjkEpa3.h:78
Scene scene
const Depsgraph * depsgraph
SyclQueue void void size_t num_bytes void
struct @211::@212 surface
RenderEngineType * RE_engines_find(const char *idname)
Definition: engine.c:98
bool RE_engine_is_opengl(RenderEngineType *render_type)
Definition: engine.c:115
uint pos
GPUBatch * quad
void GPU_offscreen_free(GPUOffScreen *ofs)
void GPU_offscreen_unbind(GPUOffScreen *UNUSED(ofs), bool restore)
GPUOffScreen * GPU_offscreen_create(int width, int height, bool depth, eGPUTextureFormat format, char err_out[256])
void GPU_backbuffer_bind(eGPUBackBuffer buffer)
void GPU_clear_color(float red, float green, float blue, float alpha)
void GPU_offscreen_draw_to_screen(GPUOffScreen *ofs, int x, int y)
int GPU_offscreen_width(const GPUOffScreen *ofs)
void GPU_offscreen_bind(GPUOffScreen *ofs, bool save)
GPUTexture * GPU_offscreen_color_texture(const GPUOffScreen *ofs)
int GPU_offscreen_height(const GPUOffScreen *ofs)
const int state
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
#define G(x, y, z)
static void area(int d1, int d2, int e1, int e2, float weights[2])
#define min(a, b)
Definition: sort.c:35
signed char int8_t
Definition: stdint.h:75
void(* draw_overlay)(const struct bContext *C, struct ARegion *region)
Definition: BKE_screen.h:159
void(* layout)(const struct bContext *C, struct ARegion *region)
Definition: BKE_screen.h:161
short do_draw_paintcursor
void * regiondata
short alignment
struct wmDrawBuffer * draw_buffer
short regiontype
struct wmGizmoMap * gizmo_map
struct ARegionType * type
struct ImageUser iuser
struct ListBase bg_images
const uint8_t * data
Definition: GHOST_Types.h:52
GHOST_TAxisFlag wrap_axis
Definition: wm_draw.c:144
GHOST_TGrabCursorMode mode
Definition: wm_draw.c:143
int bounds[4]
Definition: wm_draw.c:145
char multiview_eye
void * first
Definition: DNA_listBase.h:31
Definition: BKE_main.h:121
void * data
struct RenderEngine * render_engine
char engine[32]
RenderEngineType * type
Definition: RE_engine.h:128
struct RenderData r
struct ImageUser iuser
char multiview_eye
char multiview_eye
struct Object * camera
struct WindowDrawCB * next
Definition: wm_draw.c:554
struct WindowDrawCB * prev
Definition: wm_draw.c:554
void * customdata
Definition: wm_draw.c:557
void(* draw)(const struct wmWindow *, void *)
Definition: wm_draw.c:556
char do_draw_drag
char do_refresh
ListBase regionbase
char do_draw_paintcursor
char do_draw_gesture
struct ARegion * active_region
float xmax
Definition: DNA_vec_types.h:69
float xmin
Definition: DNA_vec_types.h:69
float ymax
Definition: DNA_vec_types.h:70
float ymin
Definition: DNA_vec_types.h:70
int ymin
Definition: DNA_vec_types.h:64
int ymax
Definition: DNA_vec_types.h:64
int xmin
Definition: DNA_vec_types.h:63
int xmax
Definition: DNA_vec_types.h:63
int bound_view
Definition: wm_draw.h:22
struct GPUViewport * viewport
Definition: wm_draw.h:20
bool stereo
Definition: wm_draw.h:21
struct GPUOffScreen * offscreen
Definition: wm_draw.h:19
int xy[2]
Definition: WM_types.h:682
struct wmEvent * eventstate
struct Stereo3dFormat * stereo3d_format
static int blend(const Tex *tex, const float texvec[3], TexResult *texres)
float max
void wm_drags_draw(bContext *C, wmWindow *win)
Definition: wm_dragdrop.cc:966
static void wm_draw_callbacks(wmWindow *win)
Definition: wm_draw.c:585
void WM_draw_region_viewport_unbind(ARegion *region)
Definition: wm_draw.c:1416
static void wm_draw_offscreen_texture_parameters(GPUOffScreen *offscreen)
Definition: wm_draw.c:618
static void wm_draw_region_unbind(ARegion *region)
Definition: wm_draw.c:707
static bool wm_software_cursor_needed(void)
Definition: wm_draw.c:148
int8_t enabled
Definition: wm_draw.c:133
static bool wm_software_cursor_needed_for_window(const wmWindow *win, struct GrabState *grab_state)
Definition: wm_draw.c:156
static void wm_software_cursor_motion_clear(void)
Definition: wm_draw.c:190
static bool wm_region_use_viewport_by_type(short space_type, short region_type)
Definition: wm_draw.c:502
static void wm_draw_surface(bContext *C, wmSurface *surface)
Definition: wm_draw.c:1179
static void wm_draw_window_offscreen(bContext *C, wmWindow *win, bool stereo)
Definition: wm_draw.c:866
void WM_draw_region_free(ARegion *region, bool hide)
Definition: wm_draw.c:1360
void WM_redraw_windows(bContext *C)
Definition: wm_draw.c:1380
int xy[2]
Definition: wm_draw.c:135
static void wm_draw_region_buffer_free(ARegion *region)
Definition: wm_draw.c:603
GPUTexture * wm_draw_region_texture(ARegion *region, int view)
Definition: wm_draw.c:750
static void wm_paintcursor_draw(bContext *C, ScrArea *area, ARegion *region)
Definition: wm_draw.c:70
void wm_draw_region_blend(ARegion *region, int view, bool blend)
Definition: wm_draw.c:763
static void wm_draw_update_clear_window(bContext *C, wmWindow *win)
Definition: wm_draw.c:1279
struct WindowDrawCB WindowDrawCB
static void wm_software_cursor_draw(wmWindow *win, const struct GrabState *grab_state)
Definition: wm_draw.c:301
bool WM_region_use_viewport(ScrArea *area, ARegion *region)
Definition: wm_draw.c:509
#define SPACE_NAME(space)
static void wm_region_draw_overlay(bContext *C, ScrArea *area, ARegion *region)
Definition: wm_draw.c:336
static bool wm_draw_region_stereo_set(Main *bmain, ScrArea *area, ARegion *region, eStereoViews sview)
Definition: wm_draw.c:352
void WM_draw_cb_exit(wmWindow *win, void *handle)
Definition: wm_draw.c:574
void * WM_draw_cb_activate(wmWindow *win, void(*draw)(const struct wmWindow *, void *), void *customdata)
Definition: wm_draw.c:561
static void wm_region_test_gizmo_do_draw(bContext *C, ScrArea *area, ARegion *region, bool tag_redraw)
Definition: wm_draw.c:420
static bool wm_software_cursor_motion_test(const wmWindow *win)
Definition: wm_draw.c:175
void WM_draw_region_viewport_bind(ARegion *region)
Definition: wm_draw.c:1411
static bool wm_draw_region_bind(bContext *C, ARegion *region, int view)
Definition: wm_draw.c:674
static void wm_region_test_render_do_draw(const Scene *scene, struct Depsgraph *depsgraph, ScrArea *area, ARegion *region)
Definition: wm_draw.c:458
static void wm_software_cursor_draw_crosshair(const int event_xy[2])
Definition: wm_draw.c:258
int winid
Definition: wm_draw.c:134
void wm_draw_region_test(bContext *C, ScrArea *area, ARegion *region)
Definition: wm_draw.c:1368
static struct @1189 g_software_cursor
static void wm_draw_region_buffer_create(ARegion *region, bool stereo, bool use_viewport)
Definition: wm_draw.c:627
static void wm_draw_region_blit(ARegion *region, int view)
Definition: wm_draw.c:724
void wm_draw_region_clear(wmWindow *win, ARegion *UNUSED(region))
Definition: wm_draw.c:1354
GPUViewport * WM_draw_region_get_viewport(ARegion *region)
Definition: wm_draw.c:846
static void wm_software_cursor_motion_update(const wmWindow *win)
Definition: wm_draw.c:182
static void wm_draw_window(bContext *C, wmWindow *win)
Definition: wm_draw.c:1099
static void wm_software_cursor_draw_bitmap(const int event_xy[2], const GHOST_CursorBitmapRef *bitmap)
Definition: wm_draw.c:197
void WM_draw_region_viewport_ensure(ARegion *region, short space_type)
Definition: wm_draw.c:1405
void wm_draw_update(bContext *C)
Definition: wm_draw.c:1302
static bool wm_draw_update_test_window(Main *bmain, bContext *C, wmWindow *win)
Definition: wm_draw.c:1201
static void wm_draw_window_onscreen(bContext *C, wmWindow *win, int view)
Definition: wm_draw.c:990
GPUViewport * WM_draw_region_get_bound_viewport(ARegion *region)
Definition: wm_draw.c:856
static const char * wm_area_name(ScrArea *area)
Definition: wm_draw.c:514
void WM_paint_cursor_tag_redraw(wmWindow *win, ARegion *UNUSED(region))
Definition: wm_draw.c:1294
void WM_report(eReportType type, const char *message)
void wm_gesture_draw(wmWindow *win)
Definition: wm_gesture.c:433
bool WM_gizmo_group_type_poll(const bContext *C, const wmGizmoGroupType *gzgt)
const ListBase * WM_gizmomap_group_list(wmGizmoMap *gzmap)
Definition: wm_gizmo_map.c:222
void wm_stereo3d_draw_sidebyside(wmWindow *win, int view)
Definition: wm_stereo.c:42
bool WM_stereo3d_enabled(wmWindow *win, bool skip_stereo3d_check)
Definition: wm_stereo.c:141
void wm_stereo3d_draw_topbottom(wmWindow *win, int view)
Definition: wm_stereo.c:92
void wmViewport(const rcti *winrct)
Definition: wm_subwindow.c:21
void wmWindowViewport(wmWindow *win)
Definition: wm_subwindow.c:72
void wm_surface_clear_drawable(void)
Definition: wm_surface.c:52
void wm_surface_make_drawable(wmSurface *surface)
Definition: wm_surface.c:81
void wm_surfaces_iter(bContext *C, void(*cb)(bContext *C, wmSurface *))
Definition: wm_surface.c:32
void WM_toolsystem_update_from_context(bContext *C, WorkSpace *workspace, ViewLayer *view_layer, ScrArea *area)
int WM_window_pixels_y(const wmWindow *win)
Definition: wm_window.c:2082
void wm_window_swap_buffers(wmWindow *win)
Push rendered buffer to the screen.
Definition: wm_window.c:1883
void wm_window_clear_drawable(wmWindowManager *wm)
Definition: wm_window.c:1021
bScreen * WM_window_get_active_screen(const wmWindow *win)
Definition: wm_window.c:2300
void wm_window_make_drawable(wmWindowManager *wm, wmWindow *win)
Definition: wm_window.c:1028
ViewLayer * WM_window_get_active_view_layer(const wmWindow *win)
Definition: wm_window.c:2217
int WM_window_pixels_x(const wmWindow *win)
Definition: wm_window.c:2076
Scene * WM_window_get_active_scene(const wmWindow *win)
Definition: wm_window.c:2183
void wm_cursor_position_get(wmWindow *win, int *r_x, int *r_y)
Definition: wm_window.c:960