Changeset View
Changeset View
Standalone View
Standalone View
source/blender/draw/intern/draw_manager.c
| Show First 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | |||||
| #include "DNA_meshdata_types.h" | #include "DNA_meshdata_types.h" | ||||
| #include "DNA_world_types.h" | #include "DNA_world_types.h" | ||||
| #include "ED_space_api.h" | #include "ED_space_api.h" | ||||
| #include "ED_screen.h" | #include "ED_screen.h" | ||||
| #include "ED_gpencil.h" | #include "ED_gpencil.h" | ||||
| #include "ED_view3d.h" | #include "ED_view3d.h" | ||||
| #include "UI_view2d.h" | |||||
| #include "GPU_draw.h" | #include "GPU_draw.h" | ||||
| #include "GPU_extensions.h" | #include "GPU_extensions.h" | ||||
| #include "GPU_framebuffer.h" | #include "GPU_framebuffer.h" | ||||
| #include "GPU_immediate.h" | #include "GPU_immediate.h" | ||||
| #include "GPU_uniformbuffer.h" | #include "GPU_uniformbuffer.h" | ||||
| #include "GPU_viewport.h" | #include "GPU_viewport.h" | ||||
| #include "GPU_matrix.h" | #include "GPU_matrix.h" | ||||
| Show All 15 Lines | |||||
| #include "draw_mode_engines.h" | #include "draw_mode_engines.h" | ||||
| #include "engines/eevee/eevee_engine.h" | #include "engines/eevee/eevee_engine.h" | ||||
| #include "engines/basic/basic_engine.h" | #include "engines/basic/basic_engine.h" | ||||
| #include "engines/workbench/workbench_engine.h" | #include "engines/workbench/workbench_engine.h" | ||||
| #include "engines/external/external_engine.h" | #include "engines/external/external_engine.h" | ||||
| #include "engines/gpencil/gpencil_engine.h" | #include "engines/gpencil/gpencil_engine.h" | ||||
| #include "engines/select/select_engine.h" | #include "engines/select/select_engine.h" | ||||
| #include "editors/image_uv_editor.h" | |||||
| #include "GPU_context.h" | #include "GPU_context.h" | ||||
| #include "DEG_depsgraph.h" | #include "DEG_depsgraph.h" | ||||
| #include "DEG_depsgraph_query.h" | #include "DEG_depsgraph_query.h" | ||||
| #include "DRW_select_buffer.h" | #include "DRW_select_buffer.h" | ||||
| ▲ Show 20 Lines • Show All 513 Lines • ▼ Show 20 Lines | |||||
| /* It also stores viewport variable to an immutable place: DST | /* It also stores viewport variable to an immutable place: DST | ||||
| * This is because a cache uniform only store reference | * This is because a cache uniform only store reference | ||||
| * to its value. And we don't want to invalidate the cache | * to its value. And we don't want to invalidate the cache | ||||
| * if this value change per viewport */ | * if this value change per viewport */ | ||||
| static void drw_viewport_var_init(void) | static void drw_viewport_var_init(void) | ||||
| { | { | ||||
| RegionView3D *rv3d = DST.draw_ctx.rv3d; | RegionView3D *rv3d = DST.draw_ctx.rv3d; | ||||
| ARegion *ar = DST.draw_ctx.ar; | |||||
| /* Refresh DST.size */ | /* Refresh DST.size */ | ||||
| if (DST.viewport) { | if (DST.viewport) { | ||||
| int size[2]; | int size[2]; | ||||
| GPU_viewport_size_get(DST.viewport, size); | GPU_viewport_size_get(DST.viewport, size); | ||||
| DST.size[0] = size[0]; | DST.size[0] = size[0]; | ||||
| DST.size[1] = size[1]; | DST.size[1] = size[1]; | ||||
| DST.inv_size[0] = 1.0f / size[0]; | DST.inv_size[0] = 1.0f / size[0]; | ||||
| DST.inv_size[1] = 1.0f / size[1]; | DST.inv_size[1] = 1.0f / size[1]; | ||||
| ▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | if (rv3d != NULL) { | ||||
| if (DST.draw_ctx.sh_cfg == GPU_SHADER_CFG_CLIPPED) { | if (DST.draw_ctx.sh_cfg == GPU_SHADER_CFG_CLIPPED) { | ||||
| int plane_len = (rv3d->viewlock & RV3D_BOXCLIP) ? 4 : 6; | int plane_len = (rv3d->viewlock & RV3D_BOXCLIP) ? 4 : 6; | ||||
| DRW_view_clip_planes_set(DST.view_default, rv3d->clip, plane_len); | DRW_view_clip_planes_set(DST.view_default, rv3d->clip, plane_len); | ||||
| } | } | ||||
| DST.view_active = DST.view_default; | DST.view_active = DST.view_default; | ||||
| DST.view_previous = NULL; | DST.view_previous = NULL; | ||||
| /* fclem: Is this still needed ? */ | |||||
| if (DST.draw_ctx.object_edit) { | |||||
| ED_view3d_init_mats_rv3d(DST.draw_ctx.object_edit, rv3d); | |||||
| } | |||||
| } | |||||
| else if (ar != NULL) { | |||||
| View2D *v2d = &ar->v2d; | |||||
| float viewmat[4][4]; | |||||
| float winmat[4][4]; | |||||
| rctf region_space = {0.0f, 1.0f, 0.0f, 1.0f}; | |||||
| BLI_rctf_transform_calc_m4_pivot_min(&v2d->cur, ®ion_space, viewmat); | |||||
| unit_m4(winmat); | |||||
| winmat[0][0] = 2.0f; | |||||
| winmat[1][1] = 2.0f; | |||||
| winmat[3][0] = -1.0f; | |||||
| winmat[3][1] = -1.0f; | |||||
| DST.view_default = DRW_view_create(viewmat, winmat, NULL, NULL, NULL); | |||||
| DST.view_active = DST.view_default; | |||||
| DST.view_previous = NULL; | |||||
| } | } | ||||
| else { | else { | ||||
| zero_v3(DST.screenvecs[0]); | zero_v3(DST.screenvecs[0]); | ||||
| zero_v3(DST.screenvecs[1]); | zero_v3(DST.screenvecs[1]); | ||||
| DST.pixsize = 1.0f; | DST.pixsize = 1.0f; | ||||
| DST.view_default = NULL; | DST.view_default = NULL; | ||||
| DST.view_active = NULL; | DST.view_active = NULL; | ||||
| DST.view_previous = NULL; | DST.view_previous = NULL; | ||||
| } | } | ||||
| /* fclem: Is this still needed ? */ | |||||
| if (DST.draw_ctx.object_edit) { | |||||
| ED_view3d_init_mats_rv3d(DST.draw_ctx.object_edit, rv3d); | |||||
| } | |||||
| /* Alloc array of texture reference. */ | /* Alloc array of texture reference. */ | ||||
| memset(&DST.RST, 0x0, sizeof(DST.RST)); | memset(&DST.RST, 0x0, sizeof(DST.RST)); | ||||
| if (G_draw.view_ubo == NULL) { | if (G_draw.view_ubo == NULL) { | ||||
| G_draw.view_ubo = DRW_uniformbuffer_create(sizeof(DRWViewUboStorage), NULL); | G_draw.view_ubo = DRW_uniformbuffer_create(sizeof(DRWViewUboStorage), NULL); | ||||
| } | } | ||||
| if (DST.draw_list == NULL) { | if (DST.draw_list == NULL) { | ||||
| ▲ Show 20 Lines • Show All 680 Lines • ▼ Show 20 Lines | |||||
| /** | /** | ||||
| * Use for select and depth-drawing. | * Use for select and depth-drawing. | ||||
| */ | */ | ||||
| static void drw_engines_enable_basic(void) | static void drw_engines_enable_basic(void) | ||||
| { | { | ||||
| use_drw_engine(DRW_engine_viewport_basic_type.draw_engine); | use_drw_engine(DRW_engine_viewport_basic_type.draw_engine); | ||||
| } | } | ||||
| static void drw_engines_enable_2d(void) | |||||
| { | |||||
| SpaceLink *space_data = DST.draw_ctx.space_data; | |||||
| if (!space_data) { | |||||
| return; | |||||
| } | |||||
| if (space_data->spacetype == SPACE_IMAGE) { | |||||
| use_drw_engine(&draw_engine_image_uv_editor_type); | |||||
| } | |||||
| } | |||||
| static void drw_engines_enable(ViewLayer *view_layer, | static void drw_engines_enable(ViewLayer *view_layer, | ||||
| RenderEngineType *engine_type, | RenderEngineType *engine_type, | ||||
| bool gpencil_engine_needed) | bool gpencil_engine_needed) | ||||
| { | { | ||||
| Object *obact = OBACT(view_layer); | Object *obact = OBACT(view_layer); | ||||
| const enum eContextObjectMode mode = CTX_data_mode_enum_ex( | const enum eContextObjectMode mode = CTX_data_mode_enum_ex( | ||||
| DST.draw_ctx.object_edit, obact, DST.draw_ctx.object_mode); | DST.draw_ctx.object_edit, obact, DST.draw_ctx.object_mode); | ||||
| View3D *v3d = DST.draw_ctx.v3d; | View3D *v3d = DST.draw_ctx.v3d; | ||||
| ▲ Show 20 Lines • Show All 121 Lines • ▼ Show 20 Lines | |||||
| /** \name Main Draw Loops (DRW_draw) | /** \name Main Draw Loops (DRW_draw) | ||||
| * \{ */ | * \{ */ | ||||
| /* Everything starts here. | /* Everything starts here. | ||||
| * This function takes care of calling all cache and rendering functions | * This function takes care of calling all cache and rendering functions | ||||
| * for each relevant engine / mode engine. */ | * for each relevant engine / mode engine. */ | ||||
| void DRW_draw_view(const bContext *C) | void DRW_draw_view(const bContext *C) | ||||
| { | { | ||||
| View3D *v3d = CTX_wm_view3d(C); | |||||
| if (v3d) { | |||||
| Depsgraph *depsgraph = CTX_data_expect_evaluated_depsgraph(C); | Depsgraph *depsgraph = CTX_data_expect_evaluated_depsgraph(C); | ||||
| ARegion *ar = CTX_wm_region(C); | ARegion *ar = CTX_wm_region(C); | ||||
| View3D *v3d = CTX_wm_view3d(C); | |||||
| Scene *scene = DEG_get_evaluated_scene(depsgraph); | Scene *scene = DEG_get_evaluated_scene(depsgraph); | ||||
| RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type); | RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type); | ||||
| GPUViewport *viewport = WM_draw_region_get_bound_viewport(ar); | GPUViewport *viewport = WM_draw_region_get_bound_viewport(ar); | ||||
| /* Reset before using it. */ | /* Reset before using it. */ | ||||
| drw_state_prepare_clean_for_draw(&DST); | drw_state_prepare_clean_for_draw(&DST); | ||||
| DST.options.draw_text = ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0 && | DST.options.draw_text = ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0 && | ||||
| (v3d->overlay.flag & V3D_OVERLAY_HIDE_TEXT) != 0); | (v3d->overlay.flag & V3D_OVERLAY_HIDE_TEXT) != 0); | ||||
| DST.options.draw_background = (scene->r.alphamode == R_ADDSKY) || | DST.options.draw_background = (scene->r.alphamode == R_ADDSKY) || | ||||
| (v3d->shading.type != OB_RENDER); | (v3d->shading.type != OB_RENDER); | ||||
| DST.options.do_color_management = true; | DST.options.do_color_management = true; | ||||
| DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, viewport, C); | DRW_draw_render_loop_ex(depsgraph, engine_type, ar, v3d, viewport, C); | ||||
| } | } | ||||
| else { | |||||
| Depsgraph *depsgraph = CTX_data_expect_evaluated_depsgraph(C); | |||||
| ARegion *ar = CTX_wm_region(C); | |||||
| GPUViewport *viewport = WM_draw_region_get_bound_viewport(ar); | |||||
| drw_state_prepare_clean_for_draw(&DST); | |||||
| DST.options.do_color_management = true; | |||||
| DRW_draw_render_loop_2d_ex(depsgraph, ar, viewport, C); | |||||
| } | |||||
| } | |||||
| /** | /** | ||||
| * Used for both regular and off-screen drawing. | * Used for both regular and off-screen drawing. | ||||
| * Need to reset DST before calling this function | * Need to reset DST before calling this function | ||||
| */ | */ | ||||
| void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph, | void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph, | ||||
| RenderEngineType *engine_type, | RenderEngineType *engine_type, | ||||
| ARegion *ar, | ARegion *ar, | ||||
| View3D *v3d, | View3D *v3d, | ||||
| GPUViewport *viewport, | GPUViewport *viewport, | ||||
| const bContext *evil_C) | const bContext *evil_C) | ||||
| { | { | ||||
| Scene *scene = DEG_get_evaluated_scene(depsgraph); | Scene *scene = DEG_get_evaluated_scene(depsgraph); | ||||
| ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); | ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); | ||||
| RegionView3D *rv3d = ar->regiondata; | RegionView3D *rv3d = ar->regiondata; | ||||
| const bool do_annotations = (((v3d->flag2 & V3D_SHOW_ANNOTATION) != 0) && | const bool do_annotations = (((v3d->flag2 & V3D_SHOW_ANNOTATION) != 0) && | ||||
| ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0)); | ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0)); | ||||
| DST.draw_ctx.evil_C = evil_C; | DST.draw_ctx.evil_C = evil_C; | ||||
| DST.viewport = viewport; | DST.viewport = viewport; | ||||
| ▲ Show 20 Lines • Show All 180 Lines • ▼ Show 20 Lines | #endif | ||||
| drw_viewport_cache_resize(); | drw_viewport_cache_resize(); | ||||
| #ifdef DEBUG | #ifdef DEBUG | ||||
| /* Avoid accidental reuse. */ | /* Avoid accidental reuse. */ | ||||
| drw_state_ensure_not_reused(&DST); | drw_state_ensure_not_reused(&DST); | ||||
| #endif | #endif | ||||
| } | } | ||||
| void DRW_draw_render_loop_2d_ex(struct Depsgraph *depsgraph, | |||||
| ARegion *ar, | |||||
| GPUViewport *viewport, | |||||
| const bContext *evil_C) | |||||
| { | |||||
| Scene *scene = DEG_get_evaluated_scene(depsgraph); | |||||
| ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); | |||||
| DST.draw_ctx.evil_C = evil_C; | |||||
| DST.viewport = viewport; | |||||
| /* Setup viewport */ | |||||
| DST.draw_ctx = (DRWContextState){ | |||||
| .ar = ar, | |||||
| .scene = scene, | |||||
| .view_layer = view_layer, | |||||
| .obact = OBACT(view_layer), | |||||
| .depsgraph = depsgraph, | |||||
| .space_data = CTX_wm_space_data(evil_C), | |||||
| /* reuse if caller sets */ | |||||
| .evil_C = DST.draw_ctx.evil_C, | |||||
| }; | |||||
| drw_context_state_init(); | |||||
| drw_viewport_var_init(); | |||||
| const bool do_populate_loop = true; | |||||
| /* Get list of enabled engines */ | |||||
| drw_engines_enable_2d(); | |||||
| drw_engines_data_validate(); | |||||
| /* Update ubos */ | |||||
| DRW_globals_update(); | |||||
| drw_debug_init(); | |||||
| /* No framebuffer allowed before drawing. */ | |||||
| // TODO: this is failing BLI_assert(GPU_framebuffer_active_get() == NULL); | |||||
| /* Init engines */ | |||||
| drw_engines_init(); | |||||
| /* Cache filling */ | |||||
| { | |||||
| PROFILE_START(stime); | |||||
| drw_engines_cache_init(); | |||||
| /* Only iterate over objects for internal engines or when overlays are enabled */ | |||||
| if (do_populate_loop) { | |||||
| DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (depsgraph, ob) { | |||||
| drw_engines_cache_populate(ob); | |||||
| } | |||||
| DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END; | |||||
| } | |||||
| drw_engines_cache_finish(); | |||||
| DRW_render_instance_buffer_finish(); | |||||
| #ifdef USE_PROFILE | |||||
| double *cache_time = GPU_viewport_cache_time_get(DST.viewport); | |||||
| PROFILE_END_UPDATE(*cache_time, stime); | |||||
| #endif | |||||
| } | |||||
| DRW_stats_begin(); | |||||
| GPU_framebuffer_bind(DST.default_framebuffer); | |||||
| /* Start Drawing */ | |||||
| DRW_state_reset(); | |||||
| const bool background_drawn = drw_engines_draw_background(); | |||||
| GPU_framebuffer_bind(DST.default_framebuffer); | |||||
| if (DST.draw_ctx.evil_C) { | |||||
| ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_PRE_VIEW); | |||||
| } | |||||
| drw_engines_draw_scene(); | |||||
| if (!background_drawn) { | |||||
| drw_draw_background_alpha_under(); | |||||
| } | |||||
| /* Fix 3D view being "laggy" on macos and win+nvidia. (See T56996, T61474) */ | |||||
| GPU_flush(); | |||||
| /* annotations - temporary drawing buffer (3d space) */ | |||||
| /* XXX: Or should we use a proper draw/overlay engine for this case? */ | |||||
| // if (do_annotations) { | |||||
| // GPU_depth_test(false); | |||||
| // /* XXX: as scene->gpd is not copied for COW yet */ | |||||
| // ED_annotation_draw_view3d(DEG_get_input_scene(depsgraph), depsgraph, v3d, ar, true); | |||||
| // GPU_depth_test(true); | |||||
| // } | |||||
| DRW_state_reset(); | |||||
| if (DST.draw_ctx.evil_C) { | |||||
| GPU_depth_test(false); | |||||
| ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_POST_VIEW); | |||||
| GPU_depth_test(true); | |||||
| /* Callback can be nasty and do whatever they want with the state. | |||||
| * Don't trust them! */ | |||||
| DRW_state_reset(); | |||||
| } | |||||
| drw_debug_draw(); | |||||
| GPU_depth_test(false); | |||||
| drw_engines_draw_text(); | |||||
| GPU_depth_test(true); | |||||
| // if (DST.draw_ctx.evil_C) { | |||||
| // /* needed so gizmo isn't obscured */ | |||||
| // if ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) { | |||||
| // glDisable(GL_DEPTH_TEST); | |||||
| // DRW_draw_gizmo_3d(); | |||||
| // } | |||||
| /* annotations - temporary drawing buffer (screenspace) */ | |||||
| /* XXX: Or should we use a proper draw/overlay engine for this case? */ | |||||
| // if (do_annotations) { | |||||
| // GPU_depth_test(false); | |||||
| // /* XXX: as scene->gpd is not copied for COW yet */ | |||||
| // ED_annotation_draw_view3d(DEG_get_input_scene(depsgraph), depsgraph, v3d, ar, false); | |||||
| // GPU_depth_test(true); | |||||
| // } | |||||
| // if ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0) { | |||||
| // /* Draw 2D after region info so we can draw on top of the camera passepartout overlay. | |||||
| // * 'DRW_draw_region_info' sets the projection in pixel-space. */ | |||||
| // GPU_depth_test(false); | |||||
| // DRW_draw_gizmo_2d(); | |||||
| // GPU_depth_test(true); | |||||
| // } | |||||
| // } | |||||
| DRW_stats_reset(); | |||||
| if (G.debug_value > 20 && G.debug_value < 30) { | |||||
| GPU_depth_test(false); | |||||
| /* local coordinate visible rect inside region, to accommodate overlapping ui */ | |||||
| const rcti *rect = ED_region_visible_rect(DST.draw_ctx.ar); | |||||
| DRW_stats_draw(rect); | |||||
| GPU_depth_test(true); | |||||
| } | |||||
| if (WM_draw_region_get_bound_viewport(ar)) { | |||||
| /* Don't unbind the framebuffer yet in this case and let | |||||
| * GPU_viewport_unbind do it, so that we can still do further | |||||
| * drawing of action zones on top. */ | |||||
| } | |||||
| else { | |||||
| GPU_framebuffer_restore(); | |||||
| } | |||||
| DRW_state_reset(); | |||||
| drw_engines_disable(); | |||||
| drw_viewport_cache_resize(); | |||||
| #ifdef DEBUG | |||||
| /* Avoid accidental reuse. */ | |||||
| drw_state_ensure_not_reused(&DST); | |||||
| #endif | |||||
| } | |||||
| void DRW_draw_render_loop(struct Depsgraph *depsgraph, | void DRW_draw_render_loop(struct Depsgraph *depsgraph, | ||||
| ARegion *ar, | ARegion *ar, | ||||
| View3D *v3d, | View3D *v3d, | ||||
| GPUViewport *viewport) | GPUViewport *viewport) | ||||
| { | { | ||||
| /* Reset before using it. */ | /* Reset before using it. */ | ||||
| drw_state_prepare_clean_for_draw(&DST); | drw_state_prepare_clean_for_draw(&DST); | ||||
| ▲ Show 20 Lines • Show All 1,083 Lines • ▼ Show 20 Lines | void DRW_engines_register(void) | ||||
| DRW_engine_register(&draw_engine_paint_texture_type); | DRW_engine_register(&draw_engine_paint_texture_type); | ||||
| DRW_engine_register(&draw_engine_paint_vertex_type); | DRW_engine_register(&draw_engine_paint_vertex_type); | ||||
| DRW_engine_register(&draw_engine_particle_type); | DRW_engine_register(&draw_engine_particle_type); | ||||
| DRW_engine_register(&draw_engine_pose_type); | DRW_engine_register(&draw_engine_pose_type); | ||||
| DRW_engine_register(&draw_engine_sculpt_type); | DRW_engine_register(&draw_engine_sculpt_type); | ||||
| DRW_engine_register(&draw_engine_gpencil_type); | DRW_engine_register(&draw_engine_gpencil_type); | ||||
| DRW_engine_register(&draw_engine_select_type); | DRW_engine_register(&draw_engine_select_type); | ||||
| DRW_engine_register(&draw_engine_image_uv_editor_type); | |||||
| /* setup callbacks */ | /* setup callbacks */ | ||||
| { | { | ||||
| BKE_mball_batch_cache_dirty_tag_cb = DRW_mball_batch_cache_dirty_tag; | BKE_mball_batch_cache_dirty_tag_cb = DRW_mball_batch_cache_dirty_tag; | ||||
| BKE_mball_batch_cache_free_cb = DRW_mball_batch_cache_free; | BKE_mball_batch_cache_free_cb = DRW_mball_batch_cache_free; | ||||
| BKE_curve_batch_cache_dirty_tag_cb = DRW_curve_batch_cache_dirty_tag; | BKE_curve_batch_cache_dirty_tag_cb = DRW_curve_batch_cache_dirty_tag; | ||||
| BKE_curve_batch_cache_free_cb = DRW_curve_batch_cache_free; | BKE_curve_batch_cache_free_cb = DRW_curve_batch_cache_free; | ||||
| ▲ Show 20 Lines • Show All 189 Lines • Show Last 20 Lines | |||||