diff options
author | Julian Eisel <julian@blender.org> | 2020-08-07 14:04:31 +0300 |
---|---|---|
committer | Julian Eisel <julian@blender.org> | 2020-08-07 14:04:31 +0300 |
commit | 0d2d4a6d4a75ac38c41f872c88255eab70e88ab7 (patch) | |
tree | b7a7518af86dddba48e05a98b3c2be55e8804721 /source/blender/editors/screen | |
parent | 9b416c66fb714bdfd15a481489dbf650d0f389ea (diff) | |
parent | cfc6f9eb18e701f5be601b95c45004e8cf7fbc81 (diff) |
Merge branch 'master' into temp-ui-button-type-refactortemp-ui-button-type-refactor
Diffstat (limited to 'source/blender/editors/screen')
-rw-r--r-- | source/blender/editors/screen/area.c | 83 | ||||
-rw-r--r-- | source/blender/editors/screen/glutil.c | 394 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_context.c | 118 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_draw.c | 6 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_edit.c | 55 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_geometry.c | 31 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_intern.h | 15 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_ops.c | 133 | ||||
-rw-r--r-- | source/blender/editors/screen/screendump.c | 8 | ||||
-rw-r--r-- | source/blender/editors/screen/workspace_edit.c | 31 | ||||
-rw-r--r-- | source/blender/editors/screen/workspace_layout_edit.c | 60 |
11 files changed, 393 insertions, 541 deletions
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index a182dd662af..9616b8114ba 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -135,7 +135,7 @@ static void region_draw_emboss(const ARegion *region, const rcti *scirct, int si immUnbindProgram(); GPU_blend(false); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + GPU_blend_set_func(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA); } void ED_region_pixelspace(ARegion *region) @@ -357,12 +357,12 @@ static void region_draw_status_text(ScrArea *area, ARegion *region) bool overlap = ED_region_is_overlap(area->spacetype, region->regiontype); if (overlap) { - GPU_clear_color(0.0, 0.0, 0.0, 0.0); - glClear(GL_COLOR_BUFFER_BIT); + GPU_clear_color(0.0f, 0.0f, 0.0f, 0.0f); + GPU_clear(GPU_COLOR_BIT); } else { UI_ThemeClearColor(TH_HEADER); - glClear(GL_COLOR_BUFFER_BIT); + GPU_clear(GPU_COLOR_BIT); } int fontid = BLF_set_default(); @@ -527,11 +527,11 @@ void ED_region_do_draw(bContext *C, ARegion *region) if (area && area_is_pseudo_minimized(area)) { UI_ThemeClearColor(TH_EDITOR_OUTLINE); - glClear(GL_COLOR_BUFFER_BIT); + GPU_clear(GPU_COLOR_BIT); return; } /* optional header info instead? */ - else if (region->headerstr) { + if (region->headerstr) { region_draw_status_text(area, region); } else if (at->draw) { @@ -813,7 +813,7 @@ void ED_workspace_status_text(bContext *C, const char *str) /* ************************************************************ */ -static void area_azone_initialize(wmWindow *win, const bScreen *screen, ScrArea *area) +static void area_azone_init(wmWindow *win, const bScreen *screen, ScrArea *area) { AZone *az; @@ -883,7 +883,7 @@ static void area_azone_initialize(wmWindow *win, const bScreen *screen, ScrArea } } -static void fullscreen_azone_initialize(ScrArea *area, ARegion *region) +static void fullscreen_azone_init(ScrArea *area, ARegion *region) { AZone *az; @@ -1007,10 +1007,10 @@ static bool region_azone_edge_poll(const ARegion *region, const bool is_fullscre return true; } -static void region_azone_edge_initialize(ScrArea *area, - ARegion *region, - AZEdge edge, - const bool is_fullscreen) +static void region_azone_edge_init(ScrArea *area, + ARegion *region, + AZEdge edge, + const bool is_fullscreen) { AZone *az = NULL; const bool is_hidden = (region->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL)); @@ -1033,9 +1033,9 @@ static void region_azone_edge_initialize(ScrArea *area, } } -static void region_azone_scrollbar_initialize(ScrArea *area, - ARegion *region, - AZScrollDirection direction) +static void region_azone_scrollbar_init(ScrArea *area, + ARegion *region, + AZScrollDirection direction) { rcti scroller_vert = (direction == AZ_SCROLL_VERT) ? region->v2d.vert : region->v2d.hor; AZone *az = MEM_callocN(sizeof(*az), __func__); @@ -1061,16 +1061,16 @@ static void region_azone_scrollbar_initialize(ScrArea *area, BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2); } -static void region_azones_scrollbars_initialize(ScrArea *area, ARegion *region) +static void region_azones_scrollbars_init(ScrArea *area, ARegion *region) { const View2D *v2d = ®ion->v2d; if ((v2d->scroll & V2D_SCROLL_VERTICAL) && ((v2d->scroll & V2D_SCROLL_VERTICAL_HANDLES) == 0)) { - region_azone_scrollbar_initialize(area, region, AZ_SCROLL_VERT); + region_azone_scrollbar_init(area, region, AZ_SCROLL_VERT); } if ((v2d->scroll & V2D_SCROLL_HORIZONTAL) && ((v2d->scroll & V2D_SCROLL_HORIZONTAL_HANDLES) == 0)) { - region_azone_scrollbar_initialize(area, region, AZ_SCROLL_HOR); + region_azone_scrollbar_init(area, region, AZ_SCROLL_HOR); } } @@ -1083,16 +1083,16 @@ static void region_azones_add_edge(ScrArea *area, /* edge code (t b l r) is along which area edge azone will be drawn */ if (alignment == RGN_ALIGN_TOP) { - region_azone_edge_initialize(area, region, AE_BOTTOM_TO_TOPLEFT, is_fullscreen); + region_azone_edge_init(area, region, AE_BOTTOM_TO_TOPLEFT, is_fullscreen); } else if (alignment == RGN_ALIGN_BOTTOM) { - region_azone_edge_initialize(area, region, AE_TOP_TO_BOTTOMRIGHT, is_fullscreen); + region_azone_edge_init(area, region, AE_TOP_TO_BOTTOMRIGHT, is_fullscreen); } else if (alignment == RGN_ALIGN_RIGHT) { - region_azone_edge_initialize(area, region, AE_LEFT_TO_TOPRIGHT, is_fullscreen); + region_azone_edge_init(area, region, AE_LEFT_TO_TOPRIGHT, is_fullscreen); } else if (alignment == RGN_ALIGN_LEFT) { - region_azone_edge_initialize(area, region, AE_RIGHT_TO_TOPLEFT, is_fullscreen); + region_azone_edge_init(area, region, AE_RIGHT_TO_TOPLEFT, is_fullscreen); } } @@ -1116,10 +1116,10 @@ static void region_azones_add(const bScreen *screen, ScrArea *area, ARegion *reg } if (is_fullscreen) { - fullscreen_azone_initialize(area, region); + fullscreen_azone_init(area, region); } - region_azones_scrollbars_initialize(area, region); + region_azones_scrollbars_init(area, region); } /* dir is direction to check, not the splitting edge direction! */ @@ -1128,9 +1128,8 @@ static int rct_fits(const rcti *rect, char dir, int size) if (dir == 'h') { return BLI_rcti_size_x(rect) + 1 - size; } - else { /* 'v' */ - return BLI_rcti_size_y(rect) + 1 - size; - } + /* 'v' */ + return BLI_rcti_size_y(rect) + 1 - size; } /* *************************************************************** */ @@ -1176,18 +1175,14 @@ static void region_overlap_fix(ScrArea *area, ARegion *region) region->flag |= RGN_FLAG_TOO_SMALL; return; } - else { - BLI_rcti_translate(®ion->winrct, ar1->winx, 0); - } + BLI_rcti_translate(®ion->winrct, ar1->winx, 0); } else if (align1 == RGN_ALIGN_RIGHT) { if (region->winrct.xmin - ar1->winx < U.widget_unit) { region->flag |= RGN_FLAG_TOO_SMALL; return; } - else { - BLI_rcti_translate(®ion->winrct, -ar1->winx, 0); - } + BLI_rcti_translate(®ion->winrct, -ar1->winx, 0); } } @@ -1833,7 +1828,7 @@ void ED_area_update_region_sizes(wmWindowManager *wm, wmWindow *win, ScrArea *ar region_rect_recursive(area, area->regionbase.first, &rect, &overlap_rect, 0); /* Dynamically sized regions may have changed region sizes, so we have to force azone update. */ - area_azone_initialize(win, screen, area); + area_azone_init(win, screen, area); LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { region_subwindow(region); @@ -1852,7 +1847,7 @@ void ED_area_update_region_sizes(wmWindowManager *wm, wmWindow *win, ScrArea *ar } /* called in screen_refresh, or screens_init, also area size changes */ -void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *area) +void ED_area_init(wmWindowManager *wm, wmWindow *win, ScrArea *area) { WorkSpace *workspace = WM_window_get_active_workspace(win); const bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook); @@ -1895,7 +1890,7 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *area) } /* clear all azones, add the area triangle widgets */ - area_azone_initialize(win, screen, area); + area_azone_init(win, screen, area); /* region windows, default and own handlers */ for (region = area->regionbase.first; region; region = region->next) { @@ -1949,7 +1944,7 @@ void ED_region_update_rect(ARegion *region) } /* externally called for floating regions like menus */ -void ED_region_floating_initialize(ARegion *region) +void ED_region_floating_init(ARegion *region) { BLI_assert(region->alignment == RGN_ALIGN_FLOAT); @@ -1985,7 +1980,7 @@ void ED_region_visibility_change_update(bContext *C, ScrArea *area, ARegion *reg WM_event_remove_handlers(C, ®ion->handlers); } - ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), area); + ED_area_init(CTX_wm_manager(C), CTX_wm_window(C), area); ED_area_tag_redraw(area); } @@ -2071,8 +2066,8 @@ void ED_area_swapspace(bContext *C, ScrArea *sa1, ScrArea *sa2) ED_area_data_copy(tmp, sa1, false); ED_area_data_copy(sa1, sa2, true); ED_area_data_copy(sa2, tmp, true); - ED_area_initialize(CTX_wm_manager(C), win, sa1); - ED_area_initialize(CTX_wm_manager(C), win, sa2); + ED_area_init(CTX_wm_manager(C), win, sa1); + ED_area_init(CTX_wm_manager(C), win, sa2); BKE_screen_area_free(tmp); MEM_freeN(tmp); @@ -2131,7 +2126,7 @@ void ED_area_newspace(bContext *C, ScrArea *area, int type, const bool skip_regi area->spacetype = type; area->type = st; - /* If st->new may be called, don't use context until then. The + /* If st->create may be called, don't use context until then. The * area->type->context() callback has changed but data may be invalid * (e.g. with properties editor) until space-data is properly created */ @@ -2171,7 +2166,7 @@ void ED_area_newspace(bContext *C, ScrArea *area, int type, const bool skip_regi if (st) { /* Don't get scene from context here which may depend on space-data. */ Scene *scene = WM_window_get_active_scene(win); - sl = st->new (area, scene); + sl = st->create(area, scene); BLI_addhead(&area->spacedata, sl); /* swap regions */ @@ -2209,7 +2204,7 @@ void ED_area_newspace(bContext *C, ScrArea *area, int type, const bool skip_regi } } - ED_area_initialize(CTX_wm_manager(C), win, area); + ED_area_init(CTX_wm_manager(C), win, area); /* tell WM to refresh, cursor types etc */ WM_event_add_mousemove(win); @@ -3014,7 +3009,7 @@ ScrArea *ED_screen_areas_iter_first(const wmWindow *win, const bScreen *screen) if (!global_area) { return screen->areabase.first; } - else if ((global_area->global->flag & GLOBAL_AREA_IS_HIDDEN) == 0) { + if ((global_area->global->flag & GLOBAL_AREA_IS_HIDDEN) == 0) { return global_area; } /* Find next visible area. */ diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c index 8df1172dda1..07a122c7094 100644 --- a/source/blender/editors/screen/glutil.c +++ b/source/blender/editors/screen/glutil.c @@ -39,6 +39,7 @@ #include "GPU_immediate.h" #include "GPU_matrix.h" +#include "GPU_texture.h" #ifdef __APPLE__ # include "GPU_state.h" @@ -48,30 +49,6 @@ /* ******************************************** */ -static int get_cached_work_texture(int *r_w, int *r_h) -{ - static GLint texid = -1; - static int tex_w = 256; - static int tex_h = 256; - - if (texid == -1) { - glGenTextures(1, (GLuint *)&texid); - - glBindTexture(GL_TEXTURE_2D, texid); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, tex_w, tex_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - - glBindTexture(GL_TEXTURE_2D, 0); - } - - *r_w = tex_w; - *r_h = tex_h; - return texid; -} - static void immDrawPixelsTexSetupAttributes(IMMDrawPixelsTexState *state) { GPUVertFormat *vert_format = immVertexFormat(); @@ -118,9 +95,8 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state, float y, int img_w, int img_h, - int format, - int type, - int zoomfilter, + eGPUTextureFormat gpu_format, + bool use_filter, void *rect, float scaleX, float scaleY, @@ -132,61 +108,45 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state, float yzoom, float color[4]) { - uchar *uc_rect = (uchar *)rect; - const float *f_rect = (float *)rect; - int subpart_x, subpart_y, tex_w, tex_h; + int subpart_x, subpart_y, tex_w = 256, tex_h = 256; int seamless, offset_x, offset_y, nsubparts_x, nsubparts_y; - int texid = get_cached_work_texture(&tex_w, &tex_h); int components; const bool use_clipping = ((clip_min_x < clip_max_x) && (clip_min_y < clip_max_y)); float white[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - GLint unpack_row_length; - glGetIntegerv(GL_UNPACK_ROW_LENGTH, &unpack_row_length); - - glPixelStorei(GL_UNPACK_ROW_LENGTH, img_w); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, texid); - glBindSampler(0, 0); - - /* don't want nasty border artifacts */ - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, zoomfilter); - - /* setup seamless 2=on, 0=off */ - seamless = ((tex_w < img_w || tex_h < img_h) && tex_w > 2 && tex_h > 2) ? 2 : 0; - - offset_x = tex_w - seamless; - offset_y = tex_h - seamless; - - nsubparts_x = (img_w + (offset_x - 1)) / (offset_x); - nsubparts_y = (img_h + (offset_y - 1)) / (offset_y); - - if (format == GL_RGBA) { + if (ELEM(gpu_format, GPU_RGBA8, GPU_RGBA16F)) { components = 4; } - else if (format == GL_RGB) { + else if (ELEM(gpu_format, GPU_RGB16F)) { components = 3; } - else if (format == GL_RED) { + else if (ELEM(gpu_format, GPU_R8, GPU_R16F)) { components = 1; } else { - BLI_assert(!"Incompatible format passed to glaDrawPixelsTexScaled"); + BLI_assert(!"Incompatible format passed to immDrawPixels"); return; } - if (type == GL_FLOAT) { - /* need to set internal format to higher range float */ - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, tex_w, tex_h, 0, format, GL_FLOAT, NULL); - } - else { - /* switch to 8bit RGBA for byte buffer */ - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, tex_w, tex_h, 0, format, GL_UNSIGNED_BYTE, NULL); - } + const bool use_float_data = ELEM(gpu_format, GPU_RGBA16F, GPU_RGB16F, GPU_R16F); + eGPUDataFormat gpu_data = (use_float_data) ? GPU_DATA_FLOAT : GPU_DATA_UNSIGNED_BYTE; + size_t stride = components * ((use_float_data) ? sizeof(float) : sizeof(uchar)); - uint pos = state->pos, texco = state->texco; + GPUTexture *tex = GPU_texture_create_2d(tex_w, tex_h, gpu_format, NULL, NULL); + + GPU_texture_filter_mode(tex, use_filter); + GPU_texture_wrap_mode(tex, false, true); + + GPU_texture_bind(tex, 0); + + /* setup seamless 2=on, 0=off */ + seamless = ((tex_w < img_w || tex_h < img_h) && tex_w > 2 && tex_h > 2) ? 2 : 0; + + offset_x = tex_w - seamless; + offset_y = tex_h - seamless; + + nsubparts_x = (img_w + (offset_x - 1)) / (offset_x); + nsubparts_y = (img_h + (offset_y - 1)) / (offset_y); /* optional */ /* NOTE: Shader could be null for GLSL OCIO drawing, it is fine, since @@ -196,6 +156,8 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state, immUniformColor4fv((color) ? color : white); } + GPU_unpack_row_length_set(img_w); + for (subpart_y = 0; subpart_y < nsubparts_y; subpart_y++) { for (subpart_x = 0; subpart_x < nsubparts_x; subpart_x++) { int remainder_x = img_w - subpart_x * offset_x; @@ -213,141 +175,68 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state, continue; } + int right = subpart_w - offset_right; + int top = subpart_h - offset_top; + int bottom = 0 + offset_bot; + int left = 0 + offset_left; + if (use_clipping) { - if (rast_x + (float)(subpart_w - offset_right) * xzoom * scaleX < clip_min_x || - rast_y + (float)(subpart_h - offset_top) * yzoom * scaleY < clip_min_y) { + if (rast_x + right * xzoom * scaleX < clip_min_x || + rast_y + top * yzoom * scaleY < clip_min_y) { continue; } - if (rast_x + (float)offset_left * xzoom > clip_max_x || - rast_y + (float)offset_bot * yzoom > clip_max_y) { + if (rast_x + left * xzoom > clip_max_x || rast_y + bottom * yzoom > clip_max_y) { continue; } } - if (type == GL_FLOAT) { - glTexSubImage2D(GL_TEXTURE_2D, - 0, - 0, - 0, - subpart_w, - subpart_h, - format, - GL_FLOAT, - &f_rect[((size_t)subpart_y) * offset_y * img_w * components + - subpart_x * offset_x * components]); - - /* add an extra border of pixels so linear looks ok at edges of full image */ - if (subpart_w < tex_w) { - glTexSubImage2D(GL_TEXTURE_2D, - 0, - subpart_w, - 0, - 1, - subpart_h, - format, - GL_FLOAT, - &f_rect[((size_t)subpart_y) * offset_y * img_w * components + - (subpart_x * offset_x + subpart_w - 1) * components]); - } - if (subpart_h < tex_h) { - glTexSubImage2D( - GL_TEXTURE_2D, - 0, - 0, - subpart_h, - subpart_w, - 1, - format, - GL_FLOAT, - &f_rect[(((size_t)subpart_y) * offset_y + subpart_h - 1) * img_w * components + - subpart_x * offset_x * components]); - } - if (subpart_w < tex_w && subpart_h < tex_h) { - glTexSubImage2D( - GL_TEXTURE_2D, - 0, - subpart_w, - subpart_h, - 1, - 1, - format, - GL_FLOAT, - &f_rect[(((size_t)subpart_y) * offset_y + subpart_h - 1) * img_w * components + - (subpart_x * offset_x + subpart_w - 1) * components]); - } - } - else { - glTexSubImage2D(GL_TEXTURE_2D, - 0, - 0, - 0, - subpart_w, - subpart_h, - format, - GL_UNSIGNED_BYTE, - &uc_rect[((size_t)subpart_y) * offset_y * img_w * components + - subpart_x * offset_x * components]); + { + int src_y = subpart_y * offset_y; + int src_x = subpart_x * offset_x; +#define DATA(_y, _x) ((char *)rect + stride * ((size_t)(_y)*img_w + (_x))) + { + void *data = DATA(src_y, src_x); + GPU_texture_update_sub(tex, gpu_data, data, 0, 0, 0, subpart_w, subpart_h, 0); + } + /* Add an extra border of pixels so linear interpolation looks ok + * at edges of full image. */ if (subpart_w < tex_w) { - glTexSubImage2D(GL_TEXTURE_2D, - 0, - subpart_w, - 0, - 1, - subpart_h, - format, - GL_UNSIGNED_BYTE, - &uc_rect[((size_t)subpart_y) * offset_y * img_w * components + - (subpart_x * offset_x + subpart_w - 1) * components]); + void *data = DATA(src_y, src_x + subpart_w - 1); + int offset[2] = {subpart_w, 0}; + int extent[2] = {1, subpart_h}; + GPU_texture_update_sub(tex, gpu_data, data, UNPACK2(offset), 0, UNPACK2(extent), 0); } if (subpart_h < tex_h) { - glTexSubImage2D( - GL_TEXTURE_2D, - 0, - 0, - subpart_h, - subpart_w, - 1, - format, - GL_UNSIGNED_BYTE, - &uc_rect[(((size_t)subpart_y) * offset_y + subpart_h - 1) * img_w * components + - subpart_x * offset_x * components]); + void *data = DATA(src_y + subpart_h - 1, src_x); + int offset[2] = {0, subpart_h}; + int extent[2] = {subpart_w, 1}; + GPU_texture_update_sub(tex, gpu_data, data, UNPACK2(offset), 0, UNPACK2(extent), 0); } + if (subpart_w < tex_w && subpart_h < tex_h) { - glTexSubImage2D( - GL_TEXTURE_2D, - 0, - subpart_w, - subpart_h, - 1, - 1, - format, - GL_UNSIGNED_BYTE, - &uc_rect[(((size_t)subpart_y) * offset_y + subpart_h - 1) * img_w * components + - (subpart_x * offset_x + subpart_w - 1) * components]); + void *data = DATA(src_y + subpart_h - 1, src_x + subpart_w - 1); + int offset[2] = {subpart_w, subpart_h}; + int extent[2] = {1, 1}; + GPU_texture_update_sub(tex, gpu_data, data, UNPACK2(offset), 0, UNPACK2(extent), 0); } +#undef DATA } + uint pos = state->pos, texco = state->texco; + immBegin(GPU_PRIM_TRI_FAN, 4); - immAttr2f(texco, (float)(0 + offset_left) / tex_w, (float)(0 + offset_bot) / tex_h); - immVertex2f(pos, rast_x + (float)offset_left * xzoom, rast_y + (float)offset_bot * yzoom); - - immAttr2f(texco, (float)(subpart_w - offset_right) / tex_w, (float)(0 + offset_bot) / tex_h); - immVertex2f(pos, - rast_x + (float)(subpart_w - offset_right) * xzoom * scaleX, - rast_y + (float)offset_bot * yzoom); - - immAttr2f(texco, - (float)(subpart_w - offset_right) / tex_w, - (float)(subpart_h - offset_top) / tex_h); - immVertex2f(pos, - rast_x + (float)(subpart_w - offset_right) * xzoom * scaleX, - rast_y + (float)(subpart_h - offset_top) * yzoom * scaleY); - - immAttr2f(texco, (float)(0 + offset_left) / tex_w, (float)(subpart_h - offset_top) / tex_h); - immVertex2f(pos, - rast_x + (float)offset_left * xzoom, - rast_y + (float)(subpart_h - offset_top) * yzoom * scaleY); + immAttr2f(texco, left / (float)tex_w, bottom / (float)tex_h); + immVertex2f(pos, rast_x + offset_left * xzoom, rast_y + offset_bot * yzoom); + + immAttr2f(texco, right / (float)tex_w, bottom / (float)tex_h); + immVertex2f(pos, rast_x + right * xzoom * scaleX, rast_y + offset_bot * yzoom); + + immAttr2f(texco, right / (float)tex_w, top / (float)tex_h); + immVertex2f(pos, rast_x + right * xzoom * scaleX, rast_y + top * yzoom * scaleY); + + immAttr2f(texco, left / (float)tex_w, top / (float)tex_h); + immVertex2f(pos, rast_x + offset_left * xzoom, rast_y + top * yzoom * scaleY); immEnd(); /* NOTE: Weirdly enough this is only required on macOS. Without this there is some sort of @@ -364,8 +253,11 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state, immUnbindProgram(); } - glBindTexture(GL_TEXTURE_2D, 0); - glPixelStorei(GL_UNPACK_ROW_LENGTH, unpack_row_length); + GPU_texture_unbind(tex); + GPU_texture_free(tex); + + /* Restore default. */ + GPU_unpack_row_length_set(0); } void immDrawPixelsTexScaled(IMMDrawPixelsTexState *state, @@ -373,9 +265,8 @@ void immDrawPixelsTexScaled(IMMDrawPixelsTexState *state, float y, int img_w, int img_h, - int format, - int type, - int zoomfilter, + eGPUTextureFormat gpu_format, + bool use_filter, void *rect, float scaleX, float scaleY, @@ -388,9 +279,8 @@ void immDrawPixelsTexScaled(IMMDrawPixelsTexState *state, y, img_w, img_h, - format, - type, - zoomfilter, + gpu_format, + use_filter, rect, scaleX, scaleY, @@ -408,9 +298,8 @@ void immDrawPixelsTex(IMMDrawPixelsTexState *state, float y, int img_w, int img_h, - int format, - int type, - int zoomfilter, + eGPUTextureFormat gpu_format, + bool use_filter, void *rect, float xzoom, float yzoom, @@ -421,9 +310,8 @@ void immDrawPixelsTex(IMMDrawPixelsTexState *state, y, img_w, img_h, - format, - type, - zoomfilter, + gpu_format, + use_filter, rect, 1.0f, 1.0f, @@ -441,9 +329,8 @@ void immDrawPixelsTex_clipping(IMMDrawPixelsTexState *state, float y, int img_w, int img_h, - int format, - int type, - int zoomfilter, + eGPUTextureFormat gpu_format, + bool use_filter, void *rect, float clip_min_x, float clip_min_y, @@ -458,9 +345,8 @@ void immDrawPixelsTex_clipping(IMMDrawPixelsTexState *state, y, img_w, img_h, - format, - type, - zoomfilter, + gpu_format, + use_filter, rect, 1.0f, 1.0f, @@ -473,76 +359,13 @@ void immDrawPixelsTex_clipping(IMMDrawPixelsTexState *state, color); } -/* *************** glPolygonOffset hack ************* */ - -float bglPolygonOffsetCalc(const float winmat[16], float viewdist, float dist) -{ - /* Seems like we have a factor of 2 more offset than 2.79 for some reason. Correct for this. */ - dist *= 0.5f; - - if (winmat[15] > 0.5f) { -#if 1 - return 0.00001f * dist * viewdist; // ortho tweaking -#else - static float depth_fac = 0.0f; - if (depth_fac == 0.0f) { - int depthbits; - glGetIntegerv(GL_DEPTH_BITS, &depthbits); - depth_fac = 1.0f / (float)((1 << depthbits) - 1); - } - offs = (-1.0 / winmat[10]) * dist * depth_fac; - - UNUSED_VARS(viewdist); -#endif - } - else { - /* This adjustment effectively results in reducing the Z value by 0.25%. - * - * winmat[14] actually evaluates to `-2 * far * near / (far - near)`, - * is very close to -0.2 with default clip range, - * and is used as the coefficient multiplied by `w / z`, - * thus controlling the z dependent part of the depth value. - */ - return winmat[14] * -0.0025f * dist; - } -} - -/** - * \note \a viewdist is only for ortho at the moment. - */ -void bglPolygonOffset(float viewdist, float dist) -{ - static float winmat[16], offset = 0.0f; - - if (dist != 0.0f) { - // glEnable(GL_POLYGON_OFFSET_FILL); - // glPolygonOffset(-1.0, -1.0); - - /* hack below is to mimic polygon offset */ - GPU_matrix_projection_get(winmat); - - /* dist is from camera to center point */ - - float offs = bglPolygonOffsetCalc(winmat, viewdist, dist); - - winmat[14] -= offs; - offset += offs; - } - else { - winmat[14] += offset; - offset = 0.0; - } - - GPU_matrix_projection_set(winmat); -} - /* **** Color management helper functions for GLSL display/transform ***** */ /* Draw given image buffer on a screen using GLSL for display transform */ void ED_draw_imbuf_clipping(ImBuf *ibuf, float x, float y, - int zoomfilter, + bool use_filter, ColorManagedViewSettings *view_settings, ColorManagedDisplaySettings *display_settings, float clip_min_x, @@ -592,13 +415,13 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf, if (ok) { if (ibuf->rect_float) { - int format = 0; + eGPUTextureFormat format = 0; if (ibuf->channels == 3) { - format = GL_RGB; + format = GPU_RGB16F; } else if (ibuf->channels == 4) { - format = GL_RGBA; + format = GPU_RGBA16F; } else { BLI_assert(!"Incompatible number of channels for GLSL display"); @@ -611,8 +434,7 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf, ibuf->x, ibuf->y, format, - GL_FLOAT, - zoomfilter, + use_filter, ibuf->rect_float, clip_min_x, clip_min_y, @@ -630,9 +452,8 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf, y, ibuf->x, ibuf->y, - GL_RGBA, - GL_UNSIGNED_BYTE, - zoomfilter, + GPU_RGBA8, + use_filter, ibuf->rect, clip_min_x, clip_min_y, @@ -664,9 +485,8 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf, y, ibuf->x, ibuf->y, - GL_RGBA, - GL_UNSIGNED_BYTE, - zoomfilter, + GPU_RGBA8, + use_filter, display_buffer, clip_min_x, clip_min_y, @@ -684,7 +504,7 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf, void ED_draw_imbuf(ImBuf *ibuf, float x, float y, - int zoomfilter, + bool use_filter, ColorManagedViewSettings *view_settings, ColorManagedDisplaySettings *display_settings, float zoom_x, @@ -693,7 +513,7 @@ void ED_draw_imbuf(ImBuf *ibuf, ED_draw_imbuf_clipping(ibuf, x, y, - zoomfilter, + use_filter, view_settings, display_settings, 0.0f, @@ -708,7 +528,7 @@ void ED_draw_imbuf_ctx_clipping(const bContext *C, ImBuf *ibuf, float x, float y, - int zoomfilter, + bool use_filter, float clip_min_x, float clip_min_y, float clip_max_x, @@ -724,7 +544,7 @@ void ED_draw_imbuf_ctx_clipping(const bContext *C, ED_draw_imbuf_clipping(ibuf, x, y, - zoomfilter, + use_filter, view_settings, display_settings, clip_min_x, @@ -736,9 +556,9 @@ void ED_draw_imbuf_ctx_clipping(const bContext *C, } void ED_draw_imbuf_ctx( - const bContext *C, ImBuf *ibuf, float x, float y, int zoomfilter, float zoom_x, float zoom_y) + const bContext *C, ImBuf *ibuf, float x, float y, bool use_filter, float zoom_x, float zoom_y) { - ED_draw_imbuf_ctx_clipping(C, ibuf, x, y, zoomfilter, 0.0f, 0.0f, 0.0f, 0.0f, zoom_x, zoom_y); + ED_draw_imbuf_ctx_clipping(C, ibuf, x, y, use_filter, 0.0f, 0.0f, 0.0f, 0.0f, zoom_x, zoom_y); } int ED_draw_imbuf_method(ImBuf *ibuf) @@ -752,9 +572,7 @@ int ED_draw_imbuf_method(ImBuf *ibuf) return (size > threshold) ? IMAGE_DRAW_METHOD_2DTEXTURE : IMAGE_DRAW_METHOD_GLSL; } - else { - return U.image_draw_method; - } + return U.image_draw_method; } /* don't move to GPU_immediate_util.h because this uses user-prefs diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c index 3202dc68f37..c17a34f97b9 100644 --- a/source/blender/editors/screen/screen_context.c +++ b/source/blender/editors/screen/screen_context.c @@ -125,11 +125,11 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult CTX_data_dir_set(result, screen_context_dir); return 1; } - else if (CTX_data_equals(member, "scene")) { + if (CTX_data_equals(member, "scene")) { CTX_data_id_pointer_set(result, &scene->id); return 1; } - else if (CTX_data_equals(member, "visible_objects")) { + if (CTX_data_equals(member, "visible_objects")) { LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) { if (BASE_VISIBLE(v3d, base)) { CTX_data_id_list_add(result, &base->object->id); @@ -138,7 +138,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } - else if (CTX_data_equals(member, "selectable_objects")) { + if (CTX_data_equals(member, "selectable_objects")) { LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) { if (BASE_SELECTABLE(v3d, base)) { CTX_data_id_list_add(result, &base->object->id); @@ -147,7 +147,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } - else if (CTX_data_equals(member, "selected_objects")) { + if (CTX_data_equals(member, "selected_objects")) { LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) { if (BASE_SELECTED(v3d, base)) { CTX_data_id_list_add(result, &base->object->id); @@ -156,7 +156,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } - else if (CTX_data_equals(member, "selected_editable_objects")) { + if (CTX_data_equals(member, "selected_editable_objects")) { LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) { if (BASE_SELECTED_EDITABLE(v3d, base)) { CTX_data_id_list_add(result, &base->object->id); @@ -165,7 +165,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } - else if (CTX_data_equals(member, "editable_objects")) { + if (CTX_data_equals(member, "editable_objects")) { /* Visible + Editable, but not necessarily selected */ LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) { if (BASE_EDITABLE(v3d, base)) { @@ -175,7 +175,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } - else if (CTX_data_equals(member, "objects_in_mode")) { + if (CTX_data_equals(member, "objects_in_mode")) { if (obact && (obact->mode != OB_MODE_OBJECT)) { FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, obact->type, obact->mode, ob_iter) { CTX_data_id_list_add(result, &ob_iter->id); @@ -185,7 +185,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } - else if (CTX_data_equals(member, "objects_in_mode_unique_data")) { + if (CTX_data_equals(member, "objects_in_mode_unique_data")) { if (obact && (obact->mode != OB_MODE_OBJECT)) { FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, obact->type, obact->mode, ob_iter) { ob_iter->id.tag |= LIB_TAG_DOIT; @@ -202,7 +202,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } - else if (CTX_data_equals(member, "visible_bones") || CTX_data_equals(member, "editable_bones")) { + if (CTX_data_equals(member, "visible_bones") || CTX_data_equals(member, "editable_bones")) { bArmature *arm = (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL; EditBone *ebone, *flipbone = NULL; const bool editable_bones = CTX_data_equals(member, "editable_bones"); @@ -257,9 +257,10 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } + return -1; /* found but not available */ } - else if (CTX_data_equals(member, "selected_bones") || - CTX_data_equals(member, "selected_editable_bones")) { + if (CTX_data_equals(member, "selected_bones") || + CTX_data_equals(member, "selected_editable_bones")) { bArmature *arm = (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL; EditBone *ebone, *flipbone = NULL; const bool selected_editable_bones = CTX_data_equals(member, "selected_editable_bones"); @@ -314,8 +315,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } + return -1; /* found but not available */ } - else if (CTX_data_equals(member, "visible_pose_bones")) { + if (CTX_data_equals(member, "visible_pose_bones")) { Object *obpose = BKE_object_pose_armature_get(obact); if (obpose && obpose->pose && obpose->data) { if (obpose != obact) { @@ -336,8 +338,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } + return -1; /* found but not available */ } - else if (CTX_data_equals(member, "selected_pose_bones")) { + if (CTX_data_equals(member, "selected_pose_bones")) { Object *obpose = BKE_object_pose_armature_get(obact); if (obpose && obpose->pose && obpose->data) { if (obpose != obact) { @@ -358,8 +361,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } + return -1; /* found but not available */ } - else if (CTX_data_equals(member, "selected_pose_bones_from_active_object")) { + if (CTX_data_equals(member, "selected_pose_bones_from_active_object")) { Object *obpose = BKE_object_pose_armature_get(obact); if (obpose && obpose->pose && obpose->data) { if (obpose != obact) { @@ -377,8 +381,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } + return -1; /* found but not available */ } - else if (CTX_data_equals(member, "active_bone")) { + if (CTX_data_equals(member, "active_bone")) { if (obact && obact->type == OB_ARMATURE) { bArmature *arm = obact->data; if (arm->edbo) { @@ -394,8 +399,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult } } } + return -1; /* found but not available */ } - else if (CTX_data_equals(member, "active_pose_bone")) { + if (CTX_data_equals(member, "active_pose_bone")) { bPoseChannel *pchan; Object *obpose = BKE_object_pose_armature_get(obact); @@ -404,22 +410,23 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult CTX_data_pointer_set(result, &obpose->id, &RNA_PoseBone, pchan); return 1; } + return -1; /* found but not available */ } - else if (CTX_data_equals(member, "active_object")) { + if (CTX_data_equals(member, "active_object")) { if (obact) { CTX_data_id_pointer_set(result, &obact->id); } return 1; } - else if (CTX_data_equals(member, "object")) { + if (CTX_data_equals(member, "object")) { if (obact) { CTX_data_id_pointer_set(result, &obact->id); } return 1; } - else if (CTX_data_equals(member, "edit_object")) { + if (CTX_data_equals(member, "edit_object")) { /* convenience for now, 1 object per scene in editmode */ if (obedit) { CTX_data_id_pointer_set(result, &obedit->id); @@ -427,49 +434,49 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult return 1; } - else if (CTX_data_equals(member, "sculpt_object")) { + if (CTX_data_equals(member, "sculpt_object")) { if (obact && (obact->mode & OB_MODE_SCULPT)) { CTX_data_id_pointer_set(result, &obact->id); } return 1; } - else if (CTX_data_equals(member, "vertex_paint_object")) { + if (CTX_data_equals(member, "vertex_paint_object")) { if (obact && (obact->mode & OB_MODE_VERTEX_PAINT)) { CTX_data_id_pointer_set(result, &obact->id); } return 1; } - else if (CTX_data_equals(member, "weight_paint_object")) { + if (CTX_data_equals(member, "weight_paint_object")) { if (obact && (obact->mode & OB_MODE_WEIGHT_PAINT)) { CTX_data_id_pointer_set(result, &obact->id); } return 1; } - else if (CTX_data_equals(member, "image_paint_object")) { + if (CTX_data_equals(member, "image_paint_object")) { if (obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) { CTX_data_id_pointer_set(result, &obact->id); } return 1; } - else if (CTX_data_equals(member, "particle_edit_object")) { + if (CTX_data_equals(member, "particle_edit_object")) { if (obact && (obact->mode & OB_MODE_PARTICLE_EDIT)) { CTX_data_id_pointer_set(result, &obact->id); } return 1; } - else if (CTX_data_equals(member, "pose_object")) { + if (CTX_data_equals(member, "pose_object")) { Object *obpose = BKE_object_pose_armature_get(obact); if (obpose) { CTX_data_id_pointer_set(result, &obpose->id); } return 1; } - else if (CTX_data_equals(member, "sequences")) { + if (CTX_data_equals(member, "sequences")) { Editing *ed = BKE_sequencer_editing_get(scene, false); if (ed) { Sequence *seq; @@ -479,8 +486,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } + return -1; /* found but not available */ } - else if (CTX_data_equals(member, "selected_sequences")) { + if (CTX_data_equals(member, "selected_sequences")) { Editing *ed = BKE_sequencer_editing_get(scene, false); if (ed) { Sequence *seq; @@ -492,8 +500,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } + return -1; /* found but not available */ } - else if (CTX_data_equals(member, "selected_editable_sequences")) { + if (CTX_data_equals(member, "selected_editable_sequences")) { Editing *ed = BKE_sequencer_editing_get(scene, false); if (ed) { Sequence *seq; @@ -505,8 +514,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } + return -1; /* found but not available */ } - else if (CTX_data_equals(member, "selected_nla_strips")) { + if (CTX_data_equals(member, "selected_nla_strips")) { bAnimContext ac; if (ANIM_animdata_get_context(C, &ac) != 0) { ListBase anim_data = {NULL, NULL}; @@ -530,8 +540,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } + return -1; /* found but not available */ } - else if (CTX_data_equals(member, "gpencil_data")) { + if (CTX_data_equals(member, "gpencil_data")) { /* FIXME: for some reason, CTX_data_active_object(C) returns NULL when called from these * situations (as outlined above - see Campbell's #ifdefs). * That causes the get_active function to fail when called from context. @@ -543,8 +554,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult CTX_data_id_pointer_set(result, &gpd->id); return 1; } + return -1; /* found but not available */ } - else if (CTX_data_equals(member, "gpencil_data_owner")) { + if (CTX_data_equals(member, "gpencil_data_owner")) { /* Pointer to which data/datablock owns the reference to the Grease Pencil data being used * (as gpencil_data). */ bGPdata **gpd_ptr = NULL; @@ -557,16 +569,18 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult CTX_data_pointer_set(result, ptr.owner_id, ptr.type, ptr.data); return 1; } + return -1; /* found but not available */ } - else if (CTX_data_equals(member, "annotation_data")) { + if (CTX_data_equals(member, "annotation_data")) { bGPdata *gpd = ED_annotation_data_get_active_direct((ID *)screen, area, scene); if (gpd) { CTX_data_id_pointer_set(result, &gpd->id); return 1; } + return -1; /* found but not available */ } - else if (CTX_data_equals(member, "annotation_data_owner")) { + if (CTX_data_equals(member, "annotation_data_owner")) { /* Pointer to which data/datablock owns the reference to the Grease Pencil data being used. */ bGPdata **gpd_ptr = NULL; PointerRNA ptr; @@ -578,8 +592,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult CTX_data_pointer_set(result, ptr.owner_id, ptr.type, ptr.data); return 1; } + return -1; /* found but not available */ } - else if (CTX_data_equals(member, "active_gpencil_layer")) { + if (CTX_data_equals(member, "active_gpencil_layer")) { bGPdata *gpd = ED_gpencil_data_get_active_direct(area, obact); if (gpd) { @@ -590,8 +605,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult return 1; } } + return -1; /* found but not available */ } - else if (CTX_data_equals(member, "active_annotation_layer")) { + if (CTX_data_equals(member, "active_annotation_layer")) { bGPdata *gpd = ED_annotation_data_get_active_direct((ID *)screen, area, scene); if (gpd) { @@ -602,8 +618,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult return 1; } } + return -1; /* found but not available */ } - else if (CTX_data_equals(member, "active_gpencil_frame")) { + if (CTX_data_equals(member, "active_gpencil_frame")) { bGPdata *gpd = ED_gpencil_data_get_active_direct(area, obact); if (gpd) { @@ -614,8 +631,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult return 1; } } + return -1; /* found but not available */ } - else if (CTX_data_equals(member, "visible_gpencil_layers")) { + if (CTX_data_equals(member, "visible_gpencil_layers")) { bGPdata *gpd = ED_gpencil_data_get_active_direct(area, obact); if (gpd) { @@ -629,8 +647,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } + return -1; /* found but not available */ } - else if (CTX_data_equals(member, "editable_gpencil_layers")) { + if (CTX_data_equals(member, "editable_gpencil_layers")) { bGPdata *gpd = ED_gpencil_data_get_active_direct(area, obact); if (gpd) { @@ -644,8 +663,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } + return -1; /* found but not available */ } - else if (CTX_data_equals(member, "editable_gpencil_strokes")) { + if (CTX_data_equals(member, "editable_gpencil_strokes")) { bGPdata *gpd = ED_gpencil_data_get_active_direct(area, obact); const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); @@ -684,8 +704,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } + return -1; /* found but not available */ } - else if (CTX_data_equals(member, "active_operator")) { + if (CTX_data_equals(member, "active_operator")) { wmOperator *op = NULL; SpaceFile *sfile = CTX_wm_space_file(C); @@ -706,11 +727,11 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult CTX_data_pointer_set(result, NULL, &RNA_Operator, op); return 1; } + return -1; /* found but not available */ } - else if (CTX_data_equals(member, "editable_fcurves") || - CTX_data_equals(member, "visible_fcurves") || - CTX_data_equals(member, "selected_editable_fcurves") || - CTX_data_equals(member, "selected_visible_fcurves")) { + if (CTX_data_equals(member, "editable_fcurves") || CTX_data_equals(member, "visible_fcurves") || + CTX_data_equals(member, "selected_editable_fcurves") || + CTX_data_equals(member, "selected_visible_fcurves")) { bAnimContext ac; if (ANIM_animdata_get_context(C, &ac) && ELEM(ac.spacetype, SPACE_ACTION, SPACE_GRAPH)) { @@ -740,8 +761,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); return 1; } + return -1; /* found but not available */ } - else if (CTX_data_equals(member, "active_editable_fcurve")) { + if (CTX_data_equals(member, "active_editable_fcurve")) { bAnimContext ac; if (ANIM_animdata_get_context(C, &ac) && ELEM(ac.spacetype, SPACE_GRAPH)) { @@ -762,10 +784,8 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult ANIM_animdata_freelist(&anim_data); return 1; } - } - else { - return 0; /* not found */ + return -1; /* found but not available */ } - return -1; /* found but not available */ + return 0; /* not found */ } diff --git a/source/blender/editors/screen/screen_draw.c b/source/blender/editors/screen/screen_draw.c index 3700deb8d77..40a452a5363 100644 --- a/source/blender/editors/screen/screen_draw.c +++ b/source/blender/editors/screen/screen_draw.c @@ -404,7 +404,7 @@ void ED_screen_draw_edges(wmWindow *win) /* It seems that all areas gets smaller when pixelsize is > 1. * So in order to avoid missing pixels we just disable de scissors. */ if (U.pixelsize <= 1.0f) { - glEnable(GL_SCISSOR_TEST); + GPU_scissor_test(true); } UI_GetThemeColor4fv(TH_EDITOR_OUTLINE, col); @@ -429,7 +429,7 @@ void ED_screen_draw_edges(wmWindow *win) GPU_blend(false); if (U.pixelsize <= 1.0f) { - glDisable(GL_SCISSOR_TEST); + GPU_scissor_test(false); } } @@ -619,7 +619,7 @@ void ED_screen_preview_render(const bScreen *screen, int size_x, int size_y, uin screen_preview_draw(screen, size_x, size_y); - GPU_offscreen_read_pixels(offscreen, GL_UNSIGNED_BYTE, r_rect); + GPU_offscreen_read_pixels(offscreen, GPU_DATA_UNSIGNED_BYTE, r_rect); GPU_offscreen_unbind(offscreen, true); GPU_offscreen_free(offscreen); diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index b6f210d7f13..62720d8ca37 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -516,7 +516,7 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win) ED_screen_areas_iter (win, screen, area) { /* set spacetype and region callbacks, calls init() */ /* sets subwindows for regions, adds handlers */ - ED_area_initialize(wm, win, area); + ED_area_init(wm, win, area); } /* wake up animtimer */ @@ -536,7 +536,7 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win) } /* file read, set all screens, ... */ -void ED_screens_initialize(Main *bmain, wmWindowManager *wm) +void ED_screens_init(Main *bmain, wmWindowManager *wm) { wmWindow *win; @@ -897,7 +897,7 @@ static void screen_global_area_refresh(wmWindow *win, else { area = screen_area_create_with_geometry(&win->global_areas, rect, space_type); SpaceType *stype = BKE_spacetype_from_id(space_type); - SpaceLink *slink = stype->new (area, WM_window_get_active_scene(win)); + SpaceLink *slink = stype->create(area, WM_window_get_active_scene(win)); area->regionbase = slink->regionbase; @@ -985,39 +985,14 @@ void ED_screen_global_areas_refresh(wmWindow *win) /* -------------------------------------------------------------------- */ /* Screen changing */ -static bScreen *screen_fullscreen_find_associated_normal_screen(const Main *bmain, bScreen *screen) -{ - for (bScreen *screen_iter = bmain->screens.first; screen_iter; - screen_iter = screen_iter->id.next) { - if ((screen_iter != screen) && ELEM(screen_iter->state, SCREENMAXIMIZED, SCREENFULL)) { - ScrArea *area = screen_iter->areabase.first; - if (area && area->full == screen) { - return screen_iter; - } - } - } - - return screen; -} - /** * \return the screen to activate. * \warning The returned screen may not always equal \a screen_new! */ -bScreen *screen_change_prepare( +void screen_change_prepare( bScreen *screen_old, bScreen *screen_new, Main *bmain, bContext *C, wmWindow *win) { - /* validate screen, it's called with notifier reference */ - if (BLI_findindex(&bmain->screens, screen_new) == -1) { - return NULL; - } - - screen_new = screen_fullscreen_find_associated_normal_screen(bmain, screen_new); - - /* check for valid winid */ - if (!(screen_new->winid == 0 || screen_new->winid == win->winid)) { - return NULL; - } + BLI_assert(BLI_findindex(&bmain->screens, screen_new) != -1); if (screen_old != screen_new) { wmTimer *wt = screen_old->animtimer; @@ -1038,11 +1013,7 @@ bScreen *screen_change_prepare( if (wt) { screen_new->animtimer = wt; } - - return screen_new; } - - return NULL; } void screen_change_update(bContext *C, wmWindow *win, bScreen *screen) @@ -1075,12 +1046,20 @@ bool ED_screen_change(bContext *C, bScreen *screen) { Main *bmain = CTX_data_main(C); wmWindow *win = CTX_wm_window(C); + WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook); + WorkSpaceLayout *layout = BKE_workspace_layout_find(workspace, screen); bScreen *screen_old = CTX_wm_screen(C); - bScreen *screen_new = screen_change_prepare(screen_old, screen, bmain, C, win); - if (screen_new) { - WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook); - WM_window_set_active_screen(win, workspace, screen); + /* Get the actual layout/screen to be activated (guaranteed to be unused, even if that means + * having to duplicate an existing one). */ + WorkSpaceLayout *layout_new = ED_workspace_screen_change_ensure_unused_layout( + bmain, workspace, layout, layout, win); + bScreen *screen_new = BKE_workspace_layout_screen_get(layout_new); + + screen_change_prepare(screen_old, screen_new, bmain, C, win); + + if (screen_old != screen_new) { + WM_window_set_active_screen(win, workspace, screen_new); screen_change_update(C, win, screen_new); return true; diff --git a/source/blender/editors/screen/screen_geometry.c b/source/blender/editors/screen/screen_geometry.c index 47580c2f4b3..0b83a657265 100644 --- a/source/blender/editors/screen/screen_geometry.c +++ b/source/blender/editors/screen/screen_geometry.c @@ -327,27 +327,26 @@ short screen_geom_find_area_split_point(const ScrArea *area, return y; } - else { - x = area->v1->vec.x + round_fl_to_short(fac * cur_area_width); - area_min = area_min_x; + x = area->v1->vec.x + round_fl_to_short(fac * cur_area_width); - if (area->v1->vec.x > window_rect->xmin) { - area_min += U.pixelsize; - } - if (area->v4->vec.x < (window_rect->xmax - 1)) { - area_min += U.pixelsize; - } + area_min = area_min_x; - if (x - area->v1->vec.x < area_min) { - x = area->v1->vec.x + area_min; - } - else if (area->v4->vec.x - x < area_min) { - x = area->v4->vec.x - area_min; - } + if (area->v1->vec.x > window_rect->xmin) { + area_min += U.pixelsize; + } + if (area->v4->vec.x < (window_rect->xmax - 1)) { + area_min += U.pixelsize; + } - return x; + if (x - area->v1->vec.x < area_min) { + x = area->v1->vec.x + area_min; } + else if (area->v4->vec.x - x < area_min) { + x = area->v4->vec.x - area_min; + } + + return x; } /** diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h index 2d42313d528..a5b5e222ae9 100644 --- a/source/blender/editors/screen/screen_intern.h +++ b/source/blender/editors/screen/screen_intern.h @@ -21,8 +21,7 @@ * \ingroup edscr */ -#ifndef __SCREEN_INTERN_H__ -#define __SCREEN_INTERN_H__ +#pragma once struct Main; struct bContext; @@ -50,11 +49,11 @@ bScreen *screen_add(struct Main *bmain, const char *name, const rcti *rect); void screen_data_copy(bScreen *to, bScreen *from); void screen_new_activate_prepare(const wmWindow *win, bScreen *screen_new); void screen_change_update(struct bContext *C, wmWindow *win, bScreen *screen); -bScreen *screen_change_prepare(bScreen *screen_old, - bScreen *screen_new, - struct Main *bmain, - struct bContext *C, - wmWindow *win); +void screen_change_prepare(bScreen *screen_old, + bScreen *screen_new, + struct Main *bmain, + struct bContext *C, + wmWindow *win); ScrArea *area_split( const wmWindow *win, bScreen *screen, ScrArea *area, char dir, float fac, int merge); int screen_area_join(struct bContext *C, bScreen *screen, ScrArea *sa1, ScrArea *sa2); @@ -97,5 +96,3 @@ void SCREEN_OT_screenshot(struct wmOperatorType *ot); /* workspace_layout_edit.c */ bool workspace_layout_set_poll(const struct WorkSpaceLayout *layout); - -#endif /* __SCREEN_INTERN_H__ */ diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 5de8ccd404d..f4d36a15d30 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -89,6 +89,8 @@ #include "UI_resources.h" #include "UI_view2d.h" +#include "GPU_extensions.h" + #include "screen_intern.h" /* own module include */ #define KM_MODAL_CANCEL 1 @@ -260,9 +262,7 @@ bool ED_operator_outliner_active_no_editobject(bContext *C) if (ob && ob == obedit) { return 0; } - else { - return 1; - } + return 1; } return 0; } @@ -362,6 +362,13 @@ bool ED_operator_object_active_editable(bContext *C) return ED_operator_object_active_editable_ex(C, ob); } +/** Object must be editable and fully local (i.e. not an override). */ +bool ED_operator_object_active_local_editable(bContext *C) +{ + Object *ob = ED_object_active_context(C); + return ED_operator_object_active_editable_ex(C, ob) && !ID_IS_OVERRIDE_LIBRARY(ob); +} + bool ED_operator_object_active_editable_mesh(bContext *C) { Object *ob = ED_object_active_context(C); @@ -762,10 +769,10 @@ static AZone *area_actionzone_refresh_xy(ScrArea *area, const int xy[2], const b if (az->type == AZONE_AREA) { break; } - else if (az->type == AZONE_REGION) { + if (az->type == AZONE_REGION) { break; } - else if (az->type == AZONE_FULLSCREEN) { + if (az->type == AZONE_FULLSCREEN) { rcti click_rect; fullscreen_click_rcti_init(&click_rect, az->x1, az->y1, az->x2, az->y2); const bool click_isect = BLI_rcti_isect_pt_v(&click_rect, xy); @@ -997,14 +1004,13 @@ static int actionzone_invoke(bContext *C, wmOperator *op, const wmEvent *event) actionzone_exit(op); return OPERATOR_FINISHED; } - else { - BLI_assert(ELEM(sad->az->type, AZONE_AREA, AZONE_REGION_SCROLL)); - /* add modal handler */ - G.moving |= G_TRANSFORM_WM; - WM_event_add_modal_handler(C, op); - return OPERATOR_RUNNING_MODAL; - } + BLI_assert(ELEM(sad->az->type, AZONE_AREA, AZONE_REGION_SCROLL)); + + /* add modal handler */ + G.moving |= G_TRANSFORM_WM; + WM_event_add_modal_handler(C, op); + return OPERATOR_RUNNING_MODAL; } static int actionzone_modal(bContext *C, wmOperator *op, const wmEvent *event) @@ -1392,9 +1398,7 @@ finally: if (newwin) { return OPERATOR_FINISHED; } - else { - return OPERATOR_CANCELLED; - } + return OPERATOR_CANCELLED; } static void SCREEN_OT_area_dupli(wmOperatorType *ot) @@ -1492,21 +1496,21 @@ static void area_move_set_limits(wmWindow *win, return; } /* top edge */ - else if ((area->v2->editflag && area->v3->editflag)) { + if ((area->v2->editflag && area->v3->editflag)) { *smaller = area->v1->vec.y + size_min; *bigger = area->v1->vec.y + size_max; *use_bigger_smaller_snap = true; return; } /* right edge */ - else if ((area->v3->editflag && area->v4->editflag)) { + if ((area->v3->editflag && area->v4->editflag)) { *smaller = area->v1->vec.x + size_min; *bigger = area->v1->vec.x + size_max; *use_bigger_smaller_snap = true; return; } /* lower edge */ - else if ((area->v4->editflag && area->v1->editflag)) { + if ((area->v4->editflag && area->v1->editflag)) { *smaller = area->v2->vec.y - size_max; *bigger = area->v2->vec.y - size_min; *use_bigger_smaller_snap = true; @@ -2046,13 +2050,13 @@ static ScrEdge *area_findsharededge(bScreen *screen, ScrArea *area, ScrArea *sb) if (sav1 == sbv4 && sav2 == sbv3) { /* area to right of sb = W */ return BKE_screen_find_edge(screen, sav1, sav2); } - else if (sav2 == sbv1 && sav3 == sbv4) { /* area to bottom of sb = N */ + if (sav2 == sbv1 && sav3 == sbv4) { /* area to bottom of sb = N */ return BKE_screen_find_edge(screen, sav2, sav3); } - else if (sav3 == sbv2 && sav4 == sbv1) { /* area to left of sb = E */ + if (sav3 == sbv2 && sav4 == sbv1) { /* area to left of sb = E */ return BKE_screen_find_edge(screen, sav3, sav4); } - else if (sav1 == sbv2 && sav4 == sbv3) { /* area on top of sb = S*/ + if (sav1 == sbv2 && sav4 == sbv3) { /* area on top of sb = S*/ return BKE_screen_find_edge(screen, sav1, sav4); } @@ -3028,15 +3032,14 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - else { - areas_do_frame_follow(C, true); - DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK); + areas_do_frame_follow(C, true); - WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); + DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK); - return OPERATOR_FINISHED; - } + WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); + + return OPERATOR_FINISHED; } static void SCREEN_OT_keyframe_jump(wmOperatorType *ot) @@ -3092,17 +3095,16 @@ static int marker_jump_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - else { - CFRA = closest; - areas_do_frame_follow(C, true); + CFRA = closest; - DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK); + areas_do_frame_follow(C, true); - WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); + DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_SEEK); - return OPERATOR_FINISHED; - } + WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); + + return OPERATOR_FINISHED; } static void SCREEN_OT_marker_jump(wmOperatorType *ot) @@ -3366,10 +3368,8 @@ static int area_join_invoke(bContext *C, wmOperator *op, const wmEvent *event) if (sad->sa1 == sad->sa2) { return OPERATOR_PASS_THROUGH; } - else { - if (!area_join_init(C, op, sad->sa1, sad->sa2)) { - return OPERATOR_CANCELLED; - } + if (!area_join_init(C, op, sad->sa1, sad->sa2)) { + return OPERATOR_CANCELLED; } } @@ -3677,9 +3677,7 @@ static int repeat_last_exec(bContext *C, wmOperator *UNUSED(op)) if (lastop->type->flag & OPTYPE_REGISTER) { break; } - else { - lastop = lastop->prev; - } + lastop = lastop->prev; } if (lastop) { @@ -4131,12 +4129,6 @@ static void SCREEN_OT_header_toggle_menus(wmOperatorType *ot) /** \name Region Context Menu Operator (Header/Footer/Navbar) * \{ */ -static bool screen_region_context_menu_poll(bContext *C) -{ - ScrArea *area = CTX_wm_area(C); - return (area && area->spacetype != SPACE_STATUSBAR); -} - void ED_screens_header_tools_menu_create(bContext *C, uiLayout *layout, void *UNUSED(arg)) { ScrArea *area = CTX_wm_area(C); @@ -4225,15 +4217,35 @@ void ED_screens_navigation_bar_tools_menu_create(bContext *C, uiLayout *layout, uiItemO(layout, but_flip_str, ICON_NONE, "SCREEN_OT_region_flip"); } +static void ed_screens_statusbar_menu_create(uiLayout *layout, void *UNUSED(arg)) +{ + PointerRNA ptr; + + RNA_pointer_create(NULL, &RNA_PreferencesView, &U, &ptr); + uiItemR(layout, &ptr, "show_statusbar_stats", 0, IFACE_("Scene Statistics"), ICON_NONE); + uiItemR(layout, &ptr, "show_statusbar_memory", 0, IFACE_("System Memory"), ICON_NONE); + if (GPU_mem_stats_supported()) { + uiItemR(layout, &ptr, "show_statusbar_vram", 0, IFACE_("Video Memory"), ICON_NONE); + } + uiItemR(layout, &ptr, "show_statusbar_version", 0, IFACE_("Blender Version"), ICON_NONE); +} + static int screen_context_menu_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event)) { uiPopupMenu *pup; uiLayout *layout; + const ScrArea *area = CTX_wm_area(C); const ARegion *region = CTX_wm_region(C); - if (ELEM(region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER)) { + if (area && area->spacetype == SPACE_STATUSBAR) { + pup = UI_popup_menu_begin(C, IFACE_("Status Bar"), ICON_NONE); + layout = UI_popup_menu_layout(pup); + ed_screens_statusbar_menu_create(layout, NULL); + UI_popup_menu_end(C, pup); + } + else if (ELEM(region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER)) { pup = UI_popup_menu_begin(C, IFACE_("Header"), ICON_NONE); layout = UI_popup_menu_layout(pup); ED_screens_header_tools_menu_create(C, layout, NULL); @@ -4263,7 +4275,6 @@ static void SCREEN_OT_region_context_menu(wmOperatorType *ot) ot->idname = "SCREEN_OT_region_context_menu"; /* api callbacks */ - ot->poll = screen_region_context_menu_poll; ot->invoke = screen_context_menu_invoke; } @@ -4391,7 +4402,7 @@ static void screen_animation_region_tag_redraw(ScrArea *area, ED_region_tag_redraw(region); return; } - else if (scene->r.cfra > region->v2d.cur.xmax) { + if (scene->r.cfra > region->v2d.cur.xmax) { region->v2d.cur.xmin = scene->r.cfra; region->v2d.cur.xmax = region->v2d.cur.xmin + w; ED_region_tag_redraw(region); @@ -4916,10 +4927,8 @@ static int userpref_show_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } - else { - BKE_report(op->reports, RPT_ERROR, "Failed to open window!"); - return OPERATOR_CANCELLED; - } + BKE_report(op->reports, RPT_ERROR, "Failed to open window!"); + return OPERATOR_CANCELLED; } static void SCREEN_OT_userpref_show(struct wmOperatorType *ot) @@ -4994,10 +5003,8 @@ static int drivers_editor_show_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } - else { - BKE_report(op->reports, RPT_ERROR, "Failed to open window!"); - return OPERATOR_CANCELLED; - } + BKE_report(op->reports, RPT_ERROR, "Failed to open window!"); + return OPERATOR_CANCELLED; } static void SCREEN_OT_drivers_editor_show(struct wmOperatorType *ot) @@ -5038,10 +5045,8 @@ static int info_log_show_exec(bContext *C, wmOperator *op) false) != NULL) { return OPERATOR_FINISHED; } - else { - BKE_report(op->reports, RPT_ERROR, "Failed to open window!"); - return OPERATOR_CANCELLED; - } + BKE_report(op->reports, RPT_ERROR, "Failed to open window!"); + return OPERATOR_CANCELLED; } static void SCREEN_OT_info_log_show(struct wmOperatorType *ot) @@ -5179,7 +5184,7 @@ static void region_blend_end(bContext *C, ARegion *region, const bool is_running else { if (rgi->hidden) { rgi->region->flag |= rgi->hidden; - ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), rgi->area); + ED_area_init(CTX_wm_manager(C), CTX_wm_window(C), rgi->area); } /* area decoration needs redraw in end */ ED_area_tag_redraw(rgi->area); @@ -5210,7 +5215,7 @@ void ED_region_visibility_change_update_animated(bContext *C, ScrArea *area, ARe /* blend in, reinitialize regions because it got unhidden */ if (rgi->hidden == 0) { - ED_area_initialize(wm, win, area); + ED_area_init(wm, win, area); } else { WM_event_remove_handlers(C, ®ion->handlers); diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c index 83ded5b3503..f80c13a7fb7 100644 --- a/source/blender/editors/screen/screendump.c +++ b/source/blender/editors/screen/screendump.c @@ -91,10 +91,8 @@ static int screenshot_data_create(bContext *C, wmOperator *op) return true; } - else { - op->customdata = NULL; - return false; - } + op->customdata = NULL; + return false; } static void screenshot_data_free(wmOperator *op) @@ -207,6 +205,8 @@ static void screenshot_draw(bContext *UNUSED(C), wmOperator *op) ScreenshotData *scd = op->customdata; PointerRNA ptr; + uiLayoutSetPropSep(layout, true); + /* image template */ RNA_pointer_create(NULL, &RNA_ImageFormatSettings, &scd->im_format, &ptr); uiTemplateImageSettings(layout, &ptr, false); diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c index 478a0adfd9a..b20dc80d158 100644 --- a/source/blender/editors/screen/workspace_edit.c +++ b/source/blender/editors/screen/workspace_edit.c @@ -88,22 +88,15 @@ static void workspace_change_update(WorkSpace *workspace_new, #endif } -static bool workspace_change_find_new_layout_cb(const WorkSpaceLayout *layout, void *UNUSED(arg)) -{ - /* return false to stop the iterator if we've found a layout that can be activated */ - return workspace_layout_set_poll(layout) ? false : true; -} - static WorkSpaceLayout *workspace_change_get_new_layout(Main *bmain, WorkSpace *workspace_new, wmWindow *win) { - /* ED_workspace_duplicate may have stored a layout to activate - * once the workspace gets activated. */ WorkSpaceLayout *layout_old = WM_window_get_active_layout(win); WorkSpaceLayout *layout_new; - bScreen *screen_new; + /* ED_workspace_duplicate may have stored a layout to activate + * once the workspace gets activated. */ if (win->workspace_hook->temp_workspace_store) { layout_new = win->workspace_hook->temp_layout_store; } @@ -113,20 +106,9 @@ static WorkSpaceLayout *workspace_change_get_new_layout(Main *bmain, layout_new = workspace_new->layouts.first; } } - screen_new = BKE_workspace_layout_screen_get(layout_new); - - if (screen_new->winid) { - /* screen is already used, try to find a free one */ - WorkSpaceLayout *layout_temp = BKE_workspace_layout_iter_circular( - workspace_new, layout_new, workspace_change_find_new_layout_cb, NULL, false); - if (!layout_temp) { - /* fallback solution: duplicate layout from old workspace */ - layout_temp = ED_workspace_layout_duplicate(bmain, workspace_new, layout_old, win); - } - layout_new = layout_temp; - } - return layout_new; + return ED_workspace_screen_change_ensure_unused_layout( + bmain, workspace_new, layout_new, layout_old, win); } /** @@ -153,10 +135,7 @@ bool ED_workspace_change(WorkSpace *workspace_new, bContext *C, wmWindowManager return false; } - screen_new = screen_change_prepare(screen_old, screen_new, bmain, C, win); - if (BKE_workspace_layout_screen_get(layout_new) != screen_new) { - layout_new = BKE_workspace_layout_find(workspace_new, screen_new); - } + screen_change_prepare(screen_old, screen_new, bmain, C, win); if (screen_new == NULL) { return false; diff --git a/source/blender/editors/screen/workspace_layout_edit.c b/source/blender/editors/screen/workspace_layout_edit.c index 0af81e0db21..8a36cffa1f1 100644 --- a/source/blender/editors/screen/workspace_layout_edit.c +++ b/source/blender/editors/screen/workspace_layout_edit.c @@ -160,6 +160,66 @@ bool ED_workspace_layout_delete(WorkSpace *workspace, WorkSpaceLayout *layout_ol return false; } +static bool workspace_change_find_new_layout_cb(const WorkSpaceLayout *layout, void *UNUSED(arg)) +{ + /* return false to stop the iterator if we've found a layout that can be activated */ + return workspace_layout_set_poll(layout) ? false : true; +} + +static bScreen *screen_fullscreen_find_associated_normal_screen(const Main *bmain, bScreen *screen) +{ + for (bScreen *screen_iter = bmain->screens.first; screen_iter; + screen_iter = screen_iter->id.next) { + if ((screen_iter != screen) && ELEM(screen_iter->state, SCREENMAXIMIZED, SCREENFULL)) { + ScrArea *area = screen_iter->areabase.first; + if (area && area->full == screen) { + return screen_iter; + } + } + } + + return screen; +} + +static bool screen_is_used_by_other_window(const wmWindow *win, const bScreen *screen) +{ + return BKE_screen_is_used(screen) && (screen->winid != win->winid); +} + +/** + * Make sure there is a non-fullscreen layout to switch to that is not used yet by an other window. + * Needed for workspace or screen switching to ensure valid screens. + * + * \param layout_fallback_base: As last resort, this layout is duplicated and returned. + */ +WorkSpaceLayout *ED_workspace_screen_change_ensure_unused_layout( + Main *bmain, + WorkSpace *workspace, + WorkSpaceLayout *layout_new, + const WorkSpaceLayout *layout_fallback_base, + wmWindow *win) +{ + WorkSpaceLayout *layout_temp = layout_new; + bScreen *screen_temp = BKE_workspace_layout_screen_get(layout_new); + + screen_temp = screen_fullscreen_find_associated_normal_screen(bmain, screen_temp); + layout_temp = BKE_workspace_layout_find(workspace, screen_temp); + + if (screen_is_used_by_other_window(win, screen_temp)) { + /* Screen is already used, try to find a free one. */ + layout_temp = BKE_workspace_layout_iter_circular( + workspace, layout_new, workspace_change_find_new_layout_cb, NULL, false); + screen_temp = layout_temp ? BKE_workspace_layout_screen_get(layout_temp) : NULL; + + if (!layout_temp || screen_is_used_by_other_window(win, screen_temp)) { + /* Fallback solution: duplicate layout. */ + layout_temp = ED_workspace_layout_duplicate(bmain, workspace, layout_fallback_base, win); + } + } + + return layout_temp; +} + static bool workspace_layout_cycle_iter_cb(const WorkSpaceLayout *layout, void *UNUSED(arg)) { /* return false to stop iterator when we have found a layout to activate */ |