diff options
Diffstat (limited to 'source/blender/windowmanager/intern/wm_draw.c')
-rw-r--r-- | source/blender/windowmanager/intern/wm_draw.c | 1382 |
1 files changed, 695 insertions, 687 deletions
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index 08ece1fd5c5..6ecbf4ef5ac 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -77,201 +77,195 @@ # include "BKE_subsurf.h" #endif - /* ******************* paint cursor *************** */ static void wm_paintcursor_draw(bContext *C, ScrArea *sa, ARegion *ar) { - wmWindowManager *wm = CTX_wm_manager(C); - wmWindow *win = CTX_wm_window(C); - bScreen *screen = WM_window_get_active_screen(win); - wmPaintCursor *pc; - - if (ar->visible && ar == screen->active_region) { - for (pc = wm->paintcursors.first; pc; pc = pc->next) { - - if ((pc->space_type != SPACE_TYPE_ANY) && (sa->spacetype != pc->space_type)) { - continue; - } - - if ((pc->region_type != RGN_TYPE_ANY) && (ar->regiontype != pc->region_type)) { - continue; - } - - if (pc->poll == NULL || pc->poll(C)) { - /* Prevent drawing outside region. */ - glEnable(GL_SCISSOR_TEST); - glScissor(ar->winrct.xmin, - ar->winrct.ymin, - BLI_rcti_size_x(&ar->winrct) + 1, - BLI_rcti_size_y(&ar->winrct) + 1); - - if (ELEM(win->grabcursor, GHOST_kGrabWrap, GHOST_kGrabHide)) { - int x = 0, y = 0; - wm_get_cursor_position(win, &x, &y); - pc->draw(C, x, y, pc->customdata); - } - else { - pc->draw(C, win->eventstate->x, win->eventstate->y, pc->customdata); - } - - glDisable(GL_SCISSOR_TEST); - } - } - } + wmWindowManager *wm = CTX_wm_manager(C); + wmWindow *win = CTX_wm_window(C); + bScreen *screen = WM_window_get_active_screen(win); + wmPaintCursor *pc; + + if (ar->visible && ar == screen->active_region) { + for (pc = wm->paintcursors.first; pc; pc = pc->next) { + + if ((pc->space_type != SPACE_TYPE_ANY) && (sa->spacetype != pc->space_type)) { + continue; + } + + if ((pc->region_type != RGN_TYPE_ANY) && (ar->regiontype != pc->region_type)) { + continue; + } + + if (pc->poll == NULL || pc->poll(C)) { + /* Prevent drawing outside region. */ + glEnable(GL_SCISSOR_TEST); + glScissor(ar->winrct.xmin, + ar->winrct.ymin, + BLI_rcti_size_x(&ar->winrct) + 1, + BLI_rcti_size_y(&ar->winrct) + 1); + + if (ELEM(win->grabcursor, GHOST_kGrabWrap, GHOST_kGrabHide)) { + int x = 0, y = 0; + wm_get_cursor_position(win, &x, &y); + pc->draw(C, x, y, pc->customdata); + } + else { + pc->draw(C, win->eventstate->x, win->eventstate->y, pc->customdata); + } + + glDisable(GL_SCISSOR_TEST); + } + } + } } - static bool wm_draw_region_stereo_set(Main *bmain, ScrArea *sa, ARegion *ar, eStereoViews sview) { - /* We could detect better when stereo is actually needed, by inspecting the - * image in the image editor and sequencer. */ - if (!ELEM(ar->regiontype, RGN_TYPE_WINDOW, RGN_TYPE_PREVIEW)) { - return false; - } - - switch (sa->spacetype) { - case SPACE_IMAGE: - { - if (ar->regiontype == RGN_TYPE_WINDOW) { - SpaceImage *sima = sa->spacedata.first; - sima->iuser.multiview_eye = sview; - return true; - } - break; - } - case SPACE_VIEW3D: - { - if (ar->regiontype == RGN_TYPE_WINDOW) { - View3D *v3d = sa->spacedata.first; - if (v3d->camera && v3d->camera->type == OB_CAMERA) { - Camera *cam = v3d->camera->data; - CameraBGImage *bgpic = cam->bg_images.first; - v3d->multiview_eye = sview; - if (bgpic) { - bgpic->iuser.multiview_eye = sview; - } - return true; - } - } - break; - } - case SPACE_NODE: - { - if (ar->regiontype == RGN_TYPE_WINDOW) { - SpaceNode *snode = sa->spacedata.first; - if ((snode->flag & SNODE_BACKDRAW) && ED_node_is_compositor(snode)) { - Image *ima = BKE_image_verify_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node"); - ima->eye = sview; - return true; - } - } - break; - } - case SPACE_SEQ: - { - SpaceSeq *sseq = sa->spacedata.first; - sseq->multiview_eye = sview; - - if (ar->regiontype == RGN_TYPE_PREVIEW) { - return true; - } - else if (ar->regiontype == RGN_TYPE_WINDOW) { - return (sseq->draw_flag & SEQ_DRAW_BACKDROP) != 0; - } - } - } - - return false; + /* We could detect better when stereo is actually needed, by inspecting the + * image in the image editor and sequencer. */ + if (!ELEM(ar->regiontype, RGN_TYPE_WINDOW, RGN_TYPE_PREVIEW)) { + return false; + } + + switch (sa->spacetype) { + case SPACE_IMAGE: { + if (ar->regiontype == RGN_TYPE_WINDOW) { + SpaceImage *sima = sa->spacedata.first; + sima->iuser.multiview_eye = sview; + return true; + } + break; + } + case SPACE_VIEW3D: { + if (ar->regiontype == RGN_TYPE_WINDOW) { + View3D *v3d = sa->spacedata.first; + if (v3d->camera && v3d->camera->type == OB_CAMERA) { + Camera *cam = v3d->camera->data; + CameraBGImage *bgpic = cam->bg_images.first; + v3d->multiview_eye = sview; + if (bgpic) { + bgpic->iuser.multiview_eye = sview; + } + return true; + } + } + break; + } + case SPACE_NODE: { + if (ar->regiontype == RGN_TYPE_WINDOW) { + SpaceNode *snode = sa->spacedata.first; + if ((snode->flag & SNODE_BACKDRAW) && ED_node_is_compositor(snode)) { + Image *ima = BKE_image_verify_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node"); + ima->eye = sview; + return true; + } + } + break; + } + case SPACE_SEQ: { + SpaceSeq *sseq = sa->spacedata.first; + sseq->multiview_eye = sview; + + if (ar->regiontype == RGN_TYPE_PREVIEW) { + return true; + } + else if (ar->regiontype == RGN_TYPE_WINDOW) { + return (sseq->draw_flag & SEQ_DRAW_BACKDROP) != 0; + } + } + } + + return false; } /* ********************* drawing ****************** */ static void wm_area_mark_invalid_backbuf(ScrArea *sa) { - if (sa->spacetype == SPACE_VIEW3D) { - ((View3D *)sa->spacedata.first)->flag |= V3D_INVALID_BACKBUF; - } + if (sa->spacetype == SPACE_VIEW3D) { + ((View3D *)sa->spacedata.first)->flag |= V3D_INVALID_BACKBUF; + } } -static void wm_region_test_render_do_draw(const Scene *scene, struct Depsgraph *depsgraph, - ScrArea *sa, ARegion *ar) +static void wm_region_test_render_do_draw(const Scene *scene, + struct Depsgraph *depsgraph, + ScrArea *sa, + ARegion *ar) { - /* tag region for redraw from render engine preview running inside of it */ - if (sa->spacetype == SPACE_VIEW3D && ar->regiontype == RGN_TYPE_WINDOW) { - RegionView3D *rv3d = ar->regiondata; - RenderEngine *engine = rv3d->render_engine; - GPUViewport *viewport = WM_draw_region_get_viewport(ar, 0); - - if (engine && (engine->flag & RE_ENGINE_DO_DRAW)) { - View3D *v3d = sa->spacedata.first; - rcti border_rect; - - /* do partial redraw when possible */ - if (ED_view3d_calc_render_border(scene, depsgraph, v3d, ar, &border_rect)) { - ED_region_tag_redraw_partial(ar, &border_rect); - } - else { - ED_region_tag_redraw(ar); - } - - engine->flag &= ~RE_ENGINE_DO_DRAW; - } - else if (viewport && GPU_viewport_do_update(viewport)) { - ED_region_tag_redraw(ar); - } - } + /* tag region for redraw from render engine preview running inside of it */ + if (sa->spacetype == SPACE_VIEW3D && ar->regiontype == RGN_TYPE_WINDOW) { + RegionView3D *rv3d = ar->regiondata; + RenderEngine *engine = rv3d->render_engine; + GPUViewport *viewport = WM_draw_region_get_viewport(ar, 0); + + if (engine && (engine->flag & RE_ENGINE_DO_DRAW)) { + View3D *v3d = sa->spacedata.first; + rcti border_rect; + + /* do partial redraw when possible */ + if (ED_view3d_calc_render_border(scene, depsgraph, v3d, ar, &border_rect)) { + ED_region_tag_redraw_partial(ar, &border_rect); + } + else { + ED_region_tag_redraw(ar); + } + + engine->flag &= ~RE_ENGINE_DO_DRAW; + } + else if (viewport && GPU_viewport_do_update(viewport)) { + ED_region_tag_redraw(ar); + } + } } static bool wm_region_use_viewport(ScrArea *sa, ARegion *ar) { - return (ELEM(sa->spacetype, SPACE_VIEW3D, SPACE_IMAGE) && ar->regiontype == RGN_TYPE_WINDOW); + return (ELEM(sa->spacetype, SPACE_VIEW3D, SPACE_IMAGE) && ar->regiontype == RGN_TYPE_WINDOW); } /********************** draw all **************************/ /* - reference method, draw all each time */ typedef struct WindowDrawCB { - struct WindowDrawCB *next, *prev; + struct WindowDrawCB *next, *prev; - void(*draw)(const struct wmWindow *, void *); - void *customdata; + void (*draw)(const struct wmWindow *, void *); + void *customdata; } WindowDrawCB; -void *WM_draw_cb_activate( - wmWindow *win, - void(*draw)(const struct wmWindow *, void *), - void *customdata) +void *WM_draw_cb_activate(wmWindow *win, + void (*draw)(const struct wmWindow *, void *), + void *customdata) { - WindowDrawCB *wdc = MEM_callocN(sizeof(*wdc), "WindowDrawCB"); + WindowDrawCB *wdc = MEM_callocN(sizeof(*wdc), "WindowDrawCB"); - BLI_addtail(&win->drawcalls, wdc); - wdc->draw = draw; - wdc->customdata = customdata; + BLI_addtail(&win->drawcalls, wdc); + wdc->draw = draw; + wdc->customdata = customdata; - return wdc; + return wdc; } void WM_draw_cb_exit(wmWindow *win, void *handle) { - for (WindowDrawCB *wdc = win->drawcalls.first; wdc; wdc = wdc->next) { - if (wdc == (WindowDrawCB *)handle) { - BLI_remlink(&win->drawcalls, wdc); - MEM_freeN(wdc); - return; - } - } + for (WindowDrawCB *wdc = win->drawcalls.first; wdc; wdc = wdc->next) { + if (wdc == (WindowDrawCB *)handle) { + BLI_remlink(&win->drawcalls, wdc); + MEM_freeN(wdc); + return; + } + } } static void wm_draw_callbacks(wmWindow *win) { - for (WindowDrawCB *wdc = win->drawcalls.first; wdc; wdc = wdc->next) { - wdc->draw(win, wdc->customdata); - } + for (WindowDrawCB *wdc = win->drawcalls.first; wdc; wdc = wdc->next) { + wdc->draw(win, wdc->customdata); + } } - /************************* Region drawing. ******************************** * * Each region draws into its own framebuffer, which is then blit on the @@ -281,508 +275,521 @@ static void wm_draw_callbacks(wmWindow *win) static void wm_draw_region_buffer_free(ARegion *ar) { - if (ar->draw_buffer) { - for (int view = 0; view < 2; view++) { - if (ar->draw_buffer->offscreen[view]) { - GPU_offscreen_free(ar->draw_buffer->offscreen[view]); - } - if (ar->draw_buffer->viewport[view]) { - GPU_viewport_free(ar->draw_buffer->viewport[view]); - } - } - - MEM_freeN(ar->draw_buffer); - ar->draw_buffer = NULL; - } + if (ar->draw_buffer) { + for (int view = 0; view < 2; view++) { + if (ar->draw_buffer->offscreen[view]) { + GPU_offscreen_free(ar->draw_buffer->offscreen[view]); + } + if (ar->draw_buffer->viewport[view]) { + GPU_viewport_free(ar->draw_buffer->viewport[view]); + } + } + + MEM_freeN(ar->draw_buffer); + ar->draw_buffer = NULL; + } } static void wm_draw_offscreen_texture_parameters(GPUOffScreen *offscreen) { - /* Setup offscreen color texture for drawing. */ - GPUTexture *texture = GPU_offscreen_color_texture(offscreen); + /* Setup offscreen color texture for drawing. */ + GPUTexture *texture = GPU_offscreen_color_texture(offscreen); - /* We don't support multisample textures here. */ - BLI_assert(GPU_texture_target(texture) == GL_TEXTURE_2D); + /* We don't support multisample textures here. */ + BLI_assert(GPU_texture_target(texture) == GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, GPU_texture_opengl_bindcode(texture)); + glBindTexture(GL_TEXTURE_2D, GPU_texture_opengl_bindcode(texture)); - /* No mipmaps or filtering. */ - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); - /* GL_TEXTURE_BASE_LEVEL = 0 by default */ - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + /* No mipmaps or filtering. */ + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + /* GL_TEXTURE_BASE_LEVEL = 0 by default */ + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glBindTexture(GL_TEXTURE_2D, 0); + glBindTexture(GL_TEXTURE_2D, 0); } static void wm_draw_region_buffer_create(ARegion *ar, bool stereo, bool use_viewport) { - if (ar->draw_buffer) { - if (ar->draw_buffer->stereo != stereo) { - /* Free draw buffer on stereo changes. */ - wm_draw_region_buffer_free(ar); - } - else { - /* Free offscreen buffer on size changes. Viewport auto resizes. */ - GPUOffScreen *offscreen = ar->draw_buffer->offscreen[0]; - if (offscreen && (GPU_offscreen_width(offscreen) != ar->winx || - GPU_offscreen_height(offscreen) != ar->winy)) - { - wm_draw_region_buffer_free(ar); - } - } - } - - if (!ar->draw_buffer) { - if (use_viewport) { - /* Allocate viewport which includes an offscreen buffer with depth - * multisample, etc. */ - ar->draw_buffer = MEM_callocN(sizeof(wmDrawBuffer), "wmDrawBuffer"); - ar->draw_buffer->viewport[0] = GPU_viewport_create(); - ar->draw_buffer->viewport[1] = (stereo) ? GPU_viewport_create() : NULL; - } - else { - /* Allocate offscreen buffer if it does not exist. This one has no - * depth or multisample buffers. 3D view creates own buffers with - * the data it needs. */ - GPUOffScreen *offscreen = GPU_offscreen_create(ar->winx, ar->winy, 0, false, false, NULL); - if (!offscreen) { - return; - } - - wm_draw_offscreen_texture_parameters(offscreen); - - GPUOffScreen *offscreen_right = NULL; - if (stereo) { - offscreen_right = GPU_offscreen_create(ar->winx, ar->winy, 0, false, false, NULL); - - if (!offscreen_right) { - GPU_offscreen_free(offscreen); - return; - } - - wm_draw_offscreen_texture_parameters(offscreen_right); - } - - ar->draw_buffer = MEM_callocN(sizeof(wmDrawBuffer), "wmDrawBuffer"); - ar->draw_buffer->offscreen[0] = offscreen; - ar->draw_buffer->offscreen[1] = offscreen_right; - } - - ar->draw_buffer->bound_view = -1; - ar->draw_buffer->stereo = stereo; - } + if (ar->draw_buffer) { + if (ar->draw_buffer->stereo != stereo) { + /* Free draw buffer on stereo changes. */ + wm_draw_region_buffer_free(ar); + } + else { + /* Free offscreen buffer on size changes. Viewport auto resizes. */ + GPUOffScreen *offscreen = ar->draw_buffer->offscreen[0]; + if (offscreen && (GPU_offscreen_width(offscreen) != ar->winx || + GPU_offscreen_height(offscreen) != ar->winy)) { + wm_draw_region_buffer_free(ar); + } + } + } + + if (!ar->draw_buffer) { + if (use_viewport) { + /* Allocate viewport which includes an offscreen buffer with depth + * multisample, etc. */ + ar->draw_buffer = MEM_callocN(sizeof(wmDrawBuffer), "wmDrawBuffer"); + ar->draw_buffer->viewport[0] = GPU_viewport_create(); + ar->draw_buffer->viewport[1] = (stereo) ? GPU_viewport_create() : NULL; + } + else { + /* Allocate offscreen buffer if it does not exist. This one has no + * depth or multisample buffers. 3D view creates own buffers with + * the data it needs. */ + GPUOffScreen *offscreen = GPU_offscreen_create(ar->winx, ar->winy, 0, false, false, NULL); + if (!offscreen) { + return; + } + + wm_draw_offscreen_texture_parameters(offscreen); + + GPUOffScreen *offscreen_right = NULL; + if (stereo) { + offscreen_right = GPU_offscreen_create(ar->winx, ar->winy, 0, false, false, NULL); + + if (!offscreen_right) { + GPU_offscreen_free(offscreen); + return; + } + + wm_draw_offscreen_texture_parameters(offscreen_right); + } + + ar->draw_buffer = MEM_callocN(sizeof(wmDrawBuffer), "wmDrawBuffer"); + ar->draw_buffer->offscreen[0] = offscreen; + ar->draw_buffer->offscreen[1] = offscreen_right; + } + + ar->draw_buffer->bound_view = -1; + ar->draw_buffer->stereo = stereo; + } } static void wm_draw_region_bind(ARegion *ar, int view) { - if (!ar->draw_buffer) { - return; - } - - if (ar->draw_buffer->viewport[view]) { - GPU_viewport_bind(ar->draw_buffer->viewport[view], &ar->winrct); - } - else { - GPU_offscreen_bind(ar->draw_buffer->offscreen[view], false); - - /* For now scissor is expected by region drawing, we could disable it - * and do the enable/disable in the specific cases that setup scissor. */ - glEnable(GL_SCISSOR_TEST); - glScissor(0, 0, ar->winx, ar->winy); - } - - ar->draw_buffer->bound_view = view; + if (!ar->draw_buffer) { + return; + } + + if (ar->draw_buffer->viewport[view]) { + GPU_viewport_bind(ar->draw_buffer->viewport[view], &ar->winrct); + } + else { + GPU_offscreen_bind(ar->draw_buffer->offscreen[view], false); + + /* For now scissor is expected by region drawing, we could disable it + * and do the enable/disable in the specific cases that setup scissor. */ + glEnable(GL_SCISSOR_TEST); + glScissor(0, 0, ar->winx, ar->winy); + } + + ar->draw_buffer->bound_view = view; } static void wm_draw_region_unbind(ARegion *ar, int view) { - if (!ar->draw_buffer) { - return; - } - - ar->draw_buffer->bound_view = -1; - - if (ar->draw_buffer->viewport[view]) { - GPU_viewport_unbind(ar->draw_buffer->viewport[view]); - } - else { - glDisable(GL_SCISSOR_TEST); - GPU_offscreen_unbind(ar->draw_buffer->offscreen[view], false); - } + if (!ar->draw_buffer) { + return; + } + + ar->draw_buffer->bound_view = -1; + + if (ar->draw_buffer->viewport[view]) { + GPU_viewport_unbind(ar->draw_buffer->viewport[view]); + } + else { + glDisable(GL_SCISSOR_TEST); + GPU_offscreen_unbind(ar->draw_buffer->offscreen[view], false); + } } static void wm_draw_region_blit(ARegion *ar, int view) { - if (!ar->draw_buffer) { - return; - } - - if (ar->draw_buffer->viewport[view]) { - GPU_viewport_draw_to_screen(ar->draw_buffer->viewport[view], &ar->winrct); - } - else { - GPU_offscreen_draw_to_screen(ar->draw_buffer->offscreen[view], ar->winrct.xmin, ar->winrct.ymin); - } + if (!ar->draw_buffer) { + return; + } + + if (ar->draw_buffer->viewport[view]) { + GPU_viewport_draw_to_screen(ar->draw_buffer->viewport[view], &ar->winrct); + } + else { + GPU_offscreen_draw_to_screen( + ar->draw_buffer->offscreen[view], ar->winrct.xmin, ar->winrct.ymin); + } } GPUTexture *wm_draw_region_texture(ARegion *ar, int view) { - if (!ar->draw_buffer) { - return NULL; - } - - if (ar->draw_buffer->viewport[view]) { - return GPU_viewport_color_texture(ar->draw_buffer->viewport[view]); - } - else { - return GPU_offscreen_color_texture(ar->draw_buffer->offscreen[view]); - } + if (!ar->draw_buffer) { + return NULL; + } + + if (ar->draw_buffer->viewport[view]) { + return GPU_viewport_color_texture(ar->draw_buffer->viewport[view]); + } + else { + return GPU_offscreen_color_texture(ar->draw_buffer->offscreen[view]); + } } void wm_draw_region_blend(ARegion *ar, int view, bool blend) { - if (!ar->draw_buffer) { - return; - } - - /* Alpha is always 1, except when blend timer is running. */ - float alpha = ED_region_blend_alpha(ar); - if (alpha <= 0.0f) { - return; - } - - if (!blend) { - alpha = 1.0f; - } - - /* setup actual texture */ - GPUTexture *texture = wm_draw_region_texture(ar, view); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, GPU_texture_opengl_bindcode(texture)); - - /* wmOrtho for the screen has this same offset */ - const float halfx = GLA_PIXEL_OFS / (BLI_rcti_size_x(&ar->winrct) + 1); - const float halfy = GLA_PIXEL_OFS / (BLI_rcti_size_y(&ar->winrct) + 1); - - if (blend) { - /* GL_ONE because regions drawn offscreen have premultiplied alpha. */ - GPU_blend(true); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - } - - GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_RECT_COLOR); - GPU_shader_bind(shader); - - rcti rect_geo = ar->winrct; - rect_geo.xmax += 1; - rect_geo.ymax += 1; - - rctf rect_tex; - rect_tex.xmin = halfx; - rect_tex.ymin = halfy; - rect_tex.xmax = 1.0f + halfx; - rect_tex.ymax = 1.0f + halfy; - - float alpha_easing = 1.0f - alpha; - alpha_easing = 1.0f - alpha_easing * alpha_easing; - - /* Slide vertical panels */ - float ofs_x = BLI_rcti_size_x(&ar->winrct) * (1.0f - alpha_easing); - if (ar->alignment == RGN_ALIGN_RIGHT) { - rect_geo.xmin += ofs_x; - rect_tex.xmax *= alpha_easing; - alpha = 1.0f; - } - else if (ar->alignment == RGN_ALIGN_LEFT) { - rect_geo.xmax -= ofs_x; - rect_tex.xmin += 1.0f - alpha_easing; - alpha = 1.0f; - } - - glUniform1i(GPU_shader_get_uniform_ensure(shader, "image"), 0); - glUniform4f(GPU_shader_get_uniform_ensure(shader, "rect_icon"), rect_tex.xmin, rect_tex.ymin, rect_tex.xmax, rect_tex.ymax); - glUniform4f(GPU_shader_get_uniform_ensure(shader, "rect_geom"), rect_geo.xmin, rect_geo.ymin, rect_geo.xmax, rect_geo.ymax); - glUniform4f(GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_COLOR), alpha, alpha, alpha, alpha); - - GPU_draw_primitive(GPU_PRIM_TRI_STRIP, 4); - - glBindTexture(GL_TEXTURE_2D, 0); - - if (blend) { - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - GPU_blend(false); - } + if (!ar->draw_buffer) { + return; + } + + /* Alpha is always 1, except when blend timer is running. */ + float alpha = ED_region_blend_alpha(ar); + if (alpha <= 0.0f) { + return; + } + + if (!blend) { + alpha = 1.0f; + } + + /* setup actual texture */ + GPUTexture *texture = wm_draw_region_texture(ar, view); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, GPU_texture_opengl_bindcode(texture)); + + /* wmOrtho for the screen has this same offset */ + const float halfx = GLA_PIXEL_OFS / (BLI_rcti_size_x(&ar->winrct) + 1); + const float halfy = GLA_PIXEL_OFS / (BLI_rcti_size_y(&ar->winrct) + 1); + + if (blend) { + /* GL_ONE because regions drawn offscreen have premultiplied alpha. */ + GPU_blend(true); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + } + + GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_RECT_COLOR); + GPU_shader_bind(shader); + + rcti rect_geo = ar->winrct; + rect_geo.xmax += 1; + rect_geo.ymax += 1; + + rctf rect_tex; + rect_tex.xmin = halfx; + rect_tex.ymin = halfy; + rect_tex.xmax = 1.0f + halfx; + rect_tex.ymax = 1.0f + halfy; + + float alpha_easing = 1.0f - alpha; + alpha_easing = 1.0f - alpha_easing * alpha_easing; + + /* Slide vertical panels */ + float ofs_x = BLI_rcti_size_x(&ar->winrct) * (1.0f - alpha_easing); + if (ar->alignment == RGN_ALIGN_RIGHT) { + rect_geo.xmin += ofs_x; + rect_tex.xmax *= alpha_easing; + alpha = 1.0f; + } + else if (ar->alignment == RGN_ALIGN_LEFT) { + rect_geo.xmax -= ofs_x; + rect_tex.xmin += 1.0f - alpha_easing; + alpha = 1.0f; + } + + glUniform1i(GPU_shader_get_uniform_ensure(shader, "image"), 0); + glUniform4f(GPU_shader_get_uniform_ensure(shader, "rect_icon"), + rect_tex.xmin, + rect_tex.ymin, + rect_tex.xmax, + rect_tex.ymax); + glUniform4f(GPU_shader_get_uniform_ensure(shader, "rect_geom"), + rect_geo.xmin, + rect_geo.ymin, + rect_geo.xmax, + rect_geo.ymax); + glUniform4f( + GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_COLOR), alpha, alpha, alpha, alpha); + + GPU_draw_primitive(GPU_PRIM_TRI_STRIP, 4); + + glBindTexture(GL_TEXTURE_2D, 0); + + if (blend) { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + GPU_blend(false); + } } GPUViewport *WM_draw_region_get_viewport(ARegion *ar, int view) { - if (!ar->draw_buffer) { - return NULL; - } + if (!ar->draw_buffer) { + return NULL; + } - return ar->draw_buffer->viewport[view]; + return ar->draw_buffer->viewport[view]; } GPUViewport *WM_draw_region_get_bound_viewport(ARegion *ar) { - if (!ar->draw_buffer || ar->draw_buffer->bound_view == -1) { - return NULL; - } + if (!ar->draw_buffer || ar->draw_buffer->bound_view == -1) { + return NULL; + } - int view = ar->draw_buffer->bound_view; - return ar->draw_buffer->viewport[view]; + int view = ar->draw_buffer->bound_view; + return ar->draw_buffer->viewport[view]; } static void wm_draw_window_offscreen(bContext *C, wmWindow *win, bool stereo) { - Main *bmain = CTX_data_main(C); - wmWindowManager *wm = CTX_wm_manager(C); - bScreen *screen = WM_window_get_active_screen(win); - - /* Draw screen areas into own frame buffer. */ - ED_screen_areas_iter(win, screen, sa) { - CTX_wm_area_set(C, sa); - - /* Compute UI layouts for dynamically size regions. */ - for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { - if (ar->visible && ar->do_draw && ar->type && ar->type->layout) { - CTX_wm_region_set(C, ar); - ED_region_do_layout(C, ar); - CTX_wm_region_set(C, NULL); - } - } - - ED_area_update_region_sizes(wm, win, sa); - - if (sa->flag & AREA_FLAG_ACTIVE_TOOL_UPDATE) { - if ((1 << sa->spacetype) & WM_TOOLSYSTEM_SPACE_MASK) { - WM_toolsystem_update_from_context(C, CTX_wm_workspace(C), CTX_data_view_layer(C), sa); - } - sa->flag &= ~AREA_FLAG_ACTIVE_TOOL_UPDATE; - } - - /* Then do actual drawing of regions. */ - for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { - if (ar->visible && ar->do_draw) { - CTX_wm_region_set(C, ar); - bool use_viewport = wm_region_use_viewport(sa, ar); - - if (stereo && wm_draw_region_stereo_set(bmain, sa, ar, STEREO_LEFT_ID)) { - wm_draw_region_buffer_create(ar, true, use_viewport); - - for (int view = 0; view < 2; view++) { - eStereoViews sview; - if (view == 0) { - sview = STEREO_LEFT_ID; - } - else { - sview = STEREO_RIGHT_ID; - wm_draw_region_stereo_set(bmain, sa, ar, sview); - } - - wm_draw_region_bind(ar, view); - ED_region_do_draw(C, ar); - wm_draw_region_unbind(ar, view); - } - } - else { - wm_draw_region_buffer_create(ar, false, use_viewport); - wm_draw_region_bind(ar, 0); - ED_region_do_draw(C, ar); - wm_draw_region_unbind(ar, 0); - } - - ar->do_draw = false; - CTX_wm_region_set(C, NULL); - } - } - - wm_area_mark_invalid_backbuf(sa); - CTX_wm_area_set(C, NULL); - } - - /* Draw menus into their own framebuffer. */ - for (ARegion *ar = screen->regionbase.first; ar; ar = ar->next) { - if (ar->visible) { - CTX_wm_menu_set(C, ar); - - if (ar->type && ar->type->layout) { - /* UI code reads the OpenGL state, but we have to refresh - * the UI layout beforehand in case the menu size changes. */ - wmViewport(&ar->winrct); - ar->type->layout(C, ar); - } - - wm_draw_region_buffer_create(ar, false, false); - wm_draw_region_bind(ar, 0); - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT); - ED_region_do_draw(C, ar); - wm_draw_region_unbind(ar, 0); - - ar->do_draw = false; - CTX_wm_menu_set(C, NULL); - } - } + Main *bmain = CTX_data_main(C); + wmWindowManager *wm = CTX_wm_manager(C); + bScreen *screen = WM_window_get_active_screen(win); + + /* Draw screen areas into own frame buffer. */ + ED_screen_areas_iter(win, screen, sa) + { + CTX_wm_area_set(C, sa); + + /* Compute UI layouts for dynamically size regions. */ + for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { + if (ar->visible && ar->do_draw && ar->type && ar->type->layout) { + CTX_wm_region_set(C, ar); + ED_region_do_layout(C, ar); + CTX_wm_region_set(C, NULL); + } + } + + ED_area_update_region_sizes(wm, win, sa); + + if (sa->flag & AREA_FLAG_ACTIVE_TOOL_UPDATE) { + if ((1 << sa->spacetype) & WM_TOOLSYSTEM_SPACE_MASK) { + WM_toolsystem_update_from_context(C, CTX_wm_workspace(C), CTX_data_view_layer(C), sa); + } + sa->flag &= ~AREA_FLAG_ACTIVE_TOOL_UPDATE; + } + + /* Then do actual drawing of regions. */ + for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { + if (ar->visible && ar->do_draw) { + CTX_wm_region_set(C, ar); + bool use_viewport = wm_region_use_viewport(sa, ar); + + if (stereo && wm_draw_region_stereo_set(bmain, sa, ar, STEREO_LEFT_ID)) { + wm_draw_region_buffer_create(ar, true, use_viewport); + + for (int view = 0; view < 2; view++) { + eStereoViews sview; + if (view == 0) { + sview = STEREO_LEFT_ID; + } + else { + sview = STEREO_RIGHT_ID; + wm_draw_region_stereo_set(bmain, sa, ar, sview); + } + + wm_draw_region_bind(ar, view); + ED_region_do_draw(C, ar); + wm_draw_region_unbind(ar, view); + } + } + else { + wm_draw_region_buffer_create(ar, false, use_viewport); + wm_draw_region_bind(ar, 0); + ED_region_do_draw(C, ar); + wm_draw_region_unbind(ar, 0); + } + + ar->do_draw = false; + CTX_wm_region_set(C, NULL); + } + } + + wm_area_mark_invalid_backbuf(sa); + CTX_wm_area_set(C, NULL); + } + + /* Draw menus into their own framebuffer. */ + for (ARegion *ar = screen->regionbase.first; ar; ar = ar->next) { + if (ar->visible) { + CTX_wm_menu_set(C, ar); + + if (ar->type && ar->type->layout) { + /* UI code reads the OpenGL state, but we have to refresh + * the UI layout beforehand in case the menu size changes. */ + wmViewport(&ar->winrct); + ar->type->layout(C, ar); + } + + wm_draw_region_buffer_create(ar, false, false); + wm_draw_region_bind(ar, 0); + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + ED_region_do_draw(C, ar); + wm_draw_region_unbind(ar, 0); + + ar->do_draw = false; + CTX_wm_menu_set(C, NULL); + } + } } static void wm_draw_window_onscreen(bContext *C, wmWindow *win, int view) { - wmWindowManager *wm = CTX_wm_manager(C); - bScreen *screen = WM_window_get_active_screen(win); + wmWindowManager *wm = CTX_wm_manager(C); + bScreen *screen = WM_window_get_active_screen(win); - /* Draw into the window framebuffer, in full window coordinates. */ - wmWindowViewport(win); + /* Draw into the window framebuffer, in full window coordinates. */ + wmWindowViewport(win); - /* We draw on all pixels of the windows so we don't need to clear them before. - * Actually this is only a problem when resizing the window. - * If it becomes a problem we should clear only when window size changes. */ + /* We draw on all pixels of the windows so we don't need to clear them before. + * Actually this is only a problem when resizing the window. + * If it becomes a problem we should clear only when window size changes. */ #if 0 - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT); + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); #endif - /* Blit non-overlapping area regions. */ - ED_screen_areas_iter(win, screen, sa) { - for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { - if (ar->visible && ar->overlap == false) { - if (view == -1 && ar->draw_buffer && ar->draw_buffer->stereo) { - /* Stereo drawing from textures. */ - if (win->stereo3d_format->display_mode == S3D_DISPLAY_ANAGLYPH) { - wm_stereo3d_draw_anaglyph(win, ar); - } - else { - wm_stereo3d_draw_interlace(win, ar); - } - } - else { - /* Blit from offscreen buffer. */ - wm_draw_region_blit(ar, 0); - } - } - } - } - - /* Draw paint cursors. */ - if (wm->paintcursors.first) { - ED_screen_areas_iter(win, screen, sa) { - for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { - if (ar->visible && ar == screen->active_region) { - CTX_wm_area_set(C, sa); - CTX_wm_region_set(C, ar); - - /* make region ready for draw, scissor, pixelspace */ - wm_paintcursor_draw(C, sa, ar); - - CTX_wm_region_set(C, NULL); - CTX_wm_area_set(C, NULL); - } - } - } - - wmWindowViewport(win); - } - - /* Blend in overlapping area regions */ - ED_screen_areas_iter(win, screen, sa) { - for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { - if (ar->visible && ar->overlap) { - wm_draw_region_blend(ar, 0, true); - } - } - } - - /* After area regions so we can do area 'overlay' drawing. */ - ED_screen_draw_edges(win); - wm_draw_callbacks(win); - - /* Blend in floating regions (menus). */ - for (ARegion *ar = screen->regionbase.first; ar; ar = ar->next) { - if (ar->visible) { - wm_draw_region_blend(ar, 0, true); - } - } - - /* always draw, not only when screen tagged */ - if (win->gesture.first) { - wm_gesture_draw(win); - } - - /* needs pixel coords in screen */ - if (wm->drags.first) { - wm_drags_draw(C, win, NULL); - } + /* Blit non-overlapping area regions. */ + ED_screen_areas_iter(win, screen, sa) + { + for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { + if (ar->visible && ar->overlap == false) { + if (view == -1 && ar->draw_buffer && ar->draw_buffer->stereo) { + /* Stereo drawing from textures. */ + if (win->stereo3d_format->display_mode == S3D_DISPLAY_ANAGLYPH) { + wm_stereo3d_draw_anaglyph(win, ar); + } + else { + wm_stereo3d_draw_interlace(win, ar); + } + } + else { + /* Blit from offscreen buffer. */ + wm_draw_region_blit(ar, 0); + } + } + } + } + + /* Draw paint cursors. */ + if (wm->paintcursors.first) { + ED_screen_areas_iter(win, screen, sa) + { + for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { + if (ar->visible && ar == screen->active_region) { + CTX_wm_area_set(C, sa); + CTX_wm_region_set(C, ar); + + /* make region ready for draw, scissor, pixelspace */ + wm_paintcursor_draw(C, sa, ar); + + CTX_wm_region_set(C, NULL); + CTX_wm_area_set(C, NULL); + } + } + } + + wmWindowViewport(win); + } + + /* Blend in overlapping area regions */ + ED_screen_areas_iter(win, screen, sa) + { + for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { + if (ar->visible && ar->overlap) { + wm_draw_region_blend(ar, 0, true); + } + } + } + + /* After area regions so we can do area 'overlay' drawing. */ + ED_screen_draw_edges(win); + wm_draw_callbacks(win); + + /* Blend in floating regions (menus). */ + for (ARegion *ar = screen->regionbase.first; ar; ar = ar->next) { + if (ar->visible) { + wm_draw_region_blend(ar, 0, true); + } + } + + /* always draw, not only when screen tagged */ + if (win->gesture.first) { + wm_gesture_draw(win); + } + + /* needs pixel coords in screen */ + if (wm->drags.first) { + wm_drags_draw(C, win, NULL); + } } static void wm_draw_window(bContext *C, wmWindow *win) { - bScreen *screen = WM_window_get_active_screen(win); - bool stereo = WM_stereo3d_enabled(win, false); - - /* Draw area regions into their own framebuffer. This way we can redraw - * the areas that need it, and blit the rest from existing framebuffers. */ - wm_draw_window_offscreen(C, win, stereo); - - /* Now we draw into the window framebuffer, in full window coordinates. */ - if (!stereo) { - /* Regular mono drawing. */ - wm_draw_window_onscreen(C, win, -1); - } - else if (win->stereo3d_format->display_mode == S3D_DISPLAY_PAGEFLIP) { - /* For pageflip we simply draw to both back buffers. */ - glDrawBuffer(GL_BACK_LEFT); - wm_draw_window_onscreen(C, win, 0); - glDrawBuffer(GL_BACK_RIGHT); - wm_draw_window_onscreen(C, win, 1); - glDrawBuffer(GL_BACK); - } - else if (ELEM(win->stereo3d_format->display_mode, S3D_DISPLAY_ANAGLYPH, S3D_DISPLAY_INTERLACE)) { - /* For anaglyph and interlace, we draw individual regions with - * stereo framebuffers using different shaders. */ - wm_draw_window_onscreen(C, win, -1); - } - else { - /* For side-by-side and top-bottom, we need to render each view to an - * an offscreen texture and then draw it. This used to happen for all - * stereo methods, but it's less efficient than drawing directly. */ - const int width = WM_window_pixels_x(win); - const int height = WM_window_pixels_y(win); - GPUOffScreen *offscreen = GPU_offscreen_create(width, height, 0, false, false, NULL); - - if (offscreen) { - GPUTexture *texture = GPU_offscreen_color_texture(offscreen); - wm_draw_offscreen_texture_parameters(offscreen); - - for (int view = 0; view < 2; view++) { - /* Draw view into offscreen buffer. */ - GPU_offscreen_bind(offscreen, false); - wm_draw_window_onscreen(C, win, view); - GPU_offscreen_unbind(offscreen, false); - - /* Draw offscreen buffer to screen. */ - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, GPU_texture_opengl_bindcode(texture)); - - if (win->stereo3d_format->display_mode == S3D_DISPLAY_SIDEBYSIDE) { - wm_stereo3d_draw_sidebyside(win, view); - } - else { - wm_stereo3d_draw_topbottom(win, view); - } - - glBindTexture(GL_TEXTURE_2D, 0); - } - - GPU_offscreen_free(offscreen); - } - else { - /* Still draw something in case of allocation failure. */ - wm_draw_window_onscreen(C, win, 0); - } - } - - screen->do_draw = false; + bScreen *screen = WM_window_get_active_screen(win); + bool stereo = WM_stereo3d_enabled(win, false); + + /* Draw area regions into their own framebuffer. This way we can redraw + * the areas that need it, and blit the rest from existing framebuffers. */ + wm_draw_window_offscreen(C, win, stereo); + + /* Now we draw into the window framebuffer, in full window coordinates. */ + if (!stereo) { + /* Regular mono drawing. */ + wm_draw_window_onscreen(C, win, -1); + } + else if (win->stereo3d_format->display_mode == S3D_DISPLAY_PAGEFLIP) { + /* For pageflip we simply draw to both back buffers. */ + glDrawBuffer(GL_BACK_LEFT); + wm_draw_window_onscreen(C, win, 0); + glDrawBuffer(GL_BACK_RIGHT); + wm_draw_window_onscreen(C, win, 1); + glDrawBuffer(GL_BACK); + } + else if (ELEM(win->stereo3d_format->display_mode, S3D_DISPLAY_ANAGLYPH, S3D_DISPLAY_INTERLACE)) { + /* For anaglyph and interlace, we draw individual regions with + * stereo framebuffers using different shaders. */ + wm_draw_window_onscreen(C, win, -1); + } + else { + /* For side-by-side and top-bottom, we need to render each view to an + * an offscreen texture and then draw it. This used to happen for all + * stereo methods, but it's less efficient than drawing directly. */ + const int width = WM_window_pixels_x(win); + const int height = WM_window_pixels_y(win); + GPUOffScreen *offscreen = GPU_offscreen_create(width, height, 0, false, false, NULL); + + if (offscreen) { + GPUTexture *texture = GPU_offscreen_color_texture(offscreen); + wm_draw_offscreen_texture_parameters(offscreen); + + for (int view = 0; view < 2; view++) { + /* Draw view into offscreen buffer. */ + GPU_offscreen_bind(offscreen, false); + wm_draw_window_onscreen(C, win, view); + GPU_offscreen_unbind(offscreen, false); + + /* Draw offscreen buffer to screen. */ + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, GPU_texture_opengl_bindcode(texture)); + + if (win->stereo3d_format->display_mode == S3D_DISPLAY_SIDEBYSIDE) { + wm_stereo3d_draw_sidebyside(win, view); + } + else { + wm_stereo3d_draw_topbottom(win, view); + } + + glBindTexture(GL_TEXTURE_2D, 0); + } + + GPU_offscreen_free(offscreen); + } + else { + /* Still draw something in case of allocation failure. */ + wm_draw_window_onscreen(C, win, 0); + } + } + + screen->do_draw = false; } /****************** main update call **********************/ @@ -790,134 +797,135 @@ static void wm_draw_window(bContext *C, wmWindow *win) /* quick test to prevent changing window drawable */ static bool wm_draw_update_test_window(wmWindow *win) { - Scene *scene = WM_window_get_active_scene(win); - ViewLayer *view_layer = WM_window_get_active_view_layer(win); - struct Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer, true); - bScreen *screen = WM_window_get_active_screen(win); - ARegion *ar; - bool do_draw = false; - - for (ar = screen->regionbase.first; ar; ar = ar->next) { - if (ar->do_draw_overlay) { - screen->do_draw_paintcursor = true; - ar->do_draw_overlay = false; - } - if (ar->visible && ar->do_draw) { - do_draw = true; - } - } - - ED_screen_areas_iter(win, screen, sa) { - for (ar = sa->regionbase.first; ar; ar = ar->next) { - wm_region_test_render_do_draw(scene, depsgraph, sa, ar); - - if (ar->visible && ar->do_draw) { - do_draw = true; - } - } - } - - if (do_draw) { - return true; - } - - if (screen->do_refresh) { - return true; - } - if (screen->do_draw) { - return true; - } - if (screen->do_draw_gesture) { - return true; - } - if (screen->do_draw_paintcursor) { - return true; - } - if (screen->do_draw_drag) { - return true; - } - - return false; + Scene *scene = WM_window_get_active_scene(win); + ViewLayer *view_layer = WM_window_get_active_view_layer(win); + struct Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer, true); + bScreen *screen = WM_window_get_active_screen(win); + ARegion *ar; + bool do_draw = false; + + for (ar = screen->regionbase.first; ar; ar = ar->next) { + if (ar->do_draw_overlay) { + screen->do_draw_paintcursor = true; + ar->do_draw_overlay = false; + } + if (ar->visible && ar->do_draw) { + do_draw = true; + } + } + + ED_screen_areas_iter(win, screen, sa) + { + for (ar = sa->regionbase.first; ar; ar = ar->next) { + wm_region_test_render_do_draw(scene, depsgraph, sa, ar); + + if (ar->visible && ar->do_draw) { + do_draw = true; + } + } + } + + if (do_draw) { + return true; + } + + if (screen->do_refresh) { + return true; + } + if (screen->do_draw) { + return true; + } + if (screen->do_draw_gesture) { + return true; + } + if (screen->do_draw_paintcursor) { + return true; + } + if (screen->do_draw_drag) { + return true; + } + + return false; } void WM_paint_cursor_tag_redraw(wmWindow *win, ARegion *UNUSED(ar)) { - if (win) { - bScreen *screen = WM_window_get_active_screen(win); - screen->do_draw_paintcursor = true; - } + if (win) { + bScreen *screen = WM_window_get_active_screen(win); + screen->do_draw_paintcursor = true; + } } void wm_draw_update(bContext *C) { - Main *bmain = CTX_data_main(C); - wmWindowManager *wm = CTX_wm_manager(C); - wmWindow *win; + Main *bmain = CTX_data_main(C); + wmWindowManager *wm = CTX_wm_manager(C); + wmWindow *win; #ifdef WITH_OPENSUBDIV - BKE_subsurf_free_unused_buffers(); + BKE_subsurf_free_unused_buffers(); #endif - GPU_free_unused_buffers(bmain); + GPU_free_unused_buffers(bmain); - for (win = wm->windows.first; win; win = win->next) { + for (win = wm->windows.first; win; win = win->next) { #ifdef WIN32 - GHOST_TWindowState state = GHOST_GetWindowState(win->ghostwin); - - if (state == GHOST_kWindowStateMinimized) { - /* do not update minimized windows, gives issues on Intel (see T33223) - * and AMD (see T50856). it seems logical to skip update for invisible - * window anyway. - */ - continue; - } + GHOST_TWindowState state = GHOST_GetWindowState(win->ghostwin); + + if (state == GHOST_kWindowStateMinimized) { + /* do not update minimized windows, gives issues on Intel (see T33223) + * and AMD (see T50856). it seems logical to skip update for invisible + * window anyway. + */ + continue; + } #endif - if (wm_draw_update_test_window(win)) { - bScreen *screen = WM_window_get_active_screen(win); + if (wm_draw_update_test_window(win)) { + bScreen *screen = WM_window_get_active_screen(win); - CTX_wm_window_set(C, win); + CTX_wm_window_set(C, win); - /* sets context window+screen */ - wm_window_make_drawable(wm, win); + /* sets context window+screen */ + wm_window_make_drawable(wm, win); - /* notifiers for screen redraw */ - ED_screen_ensure_updated(wm, win, screen); + /* notifiers for screen redraw */ + ED_screen_ensure_updated(wm, win, screen); - wm_draw_window(C, win); + wm_draw_window(C, win); - screen->do_draw_gesture = false; - screen->do_draw_paintcursor = false; - screen->do_draw_drag = false; + screen->do_draw_gesture = false; + screen->do_draw_paintcursor = false; + screen->do_draw_drag = false; - wm_window_swap_buffers(win); + wm_window_swap_buffers(win); - CTX_wm_window_set(C, NULL); - } - } + CTX_wm_window_set(C, NULL); + } + } } void wm_draw_region_clear(wmWindow *win, ARegion *UNUSED(ar)) { - bScreen *screen = WM_window_get_active_screen(win); - screen->do_draw = true; + bScreen *screen = WM_window_get_active_screen(win); + screen->do_draw = true; } void WM_draw_region_free(ARegion *ar) { - wm_draw_region_buffer_free(ar); - ar->visible = 0; + wm_draw_region_buffer_free(ar); + ar->visible = 0; } void WM_redraw_windows(bContext *C) { - wmWindow *win_prev = CTX_wm_window(C); - ScrArea *area_prev = CTX_wm_area(C); - ARegion *ar_prev = CTX_wm_region(C); + wmWindow *win_prev = CTX_wm_window(C); + ScrArea *area_prev = CTX_wm_area(C); + ARegion *ar_prev = CTX_wm_region(C); - wm_draw_update(C); + wm_draw_update(C); - CTX_wm_window_set(C, win_prev); - CTX_wm_area_set(C, area_prev); - CTX_wm_region_set(C, ar_prev); + CTX_wm_window_set(C, win_prev); + CTX_wm_area_set(C, area_prev); + CTX_wm_region_set(C, ar_prev); } |