From 4f909ba6fd2d5ccb200e240f2956b4c8a7220e56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Thu, 6 Mar 2025 15:18:02 +0100 Subject: [PATCH] DRW: Make DRWContext thread local The owner of the context is now always the local context. The `DRWContext` is now a temporary object that owns no data. The draw debug API is being put in a non-working state by this PR as it conflicts with the new lifetime / ownership of the `DRWContext` class. A new design with a global (threadsafe) debug module is needed to add back support for these debug features. Note that these are not user facing features. Some parts of EEVEE are still calling the global context and that caused crashes in the volume probe baking pipeline where the context is not yet known. Sort circuiting these function calls in this case fixes the issue, but a more longer term solution would be to alway have a `DRWContext` available inside `eevee::Instance`. I did some testing and didn't find much of a difference in frame time. However, we should still strive to remove all global access in the future to avoid potential overhead of `thread_local`. Pull Request: https://projects.blender.org/blender/blender/pulls/135521 --- source/blender/draw/CMakeLists.txt | 1 - source/blender/draw/DRW_engine.hh | 12 +- .../draw/engines/eevee_next/eevee_instance.cc | 7 +- .../draw/engines/eevee_next/eevee_instance.hh | 21 ++- .../eevee_next/eevee_lightprobe_planar.cc | 2 +- .../eevee_next/eevee_lightprobe_sphere.cc | 2 +- .../eevee_next/eevee_lightprobe_volume.cc | 2 +- source/blender/draw/intern/DRW_render.hh | 15 +- source/blender/draw/intern/draw_debug.cc | 69 +-------- source/blender/draw/intern/draw_debug.hh | 24 ++- source/blender/draw/intern/draw_debug_c.hh | 31 ---- source/blender/draw/intern/draw_manager_c.cc | 142 ++++++++---------- source/blender/draw/intern/draw_manager_c.hh | 3 - 13 files changed, 131 insertions(+), 200 deletions(-) delete mode 100644 source/blender/draw/intern/draw_debug_c.hh diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index f5371e2e506..ef1a198d6eb 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -167,7 +167,6 @@ set(SRC intern/draw_common_shader_shared.hh intern/draw_curves_private.hh intern/draw_debug.hh - intern/draw_debug_c.hh intern/draw_hair_private.hh intern/draw_handle.hh intern/draw_manager.hh diff --git a/source/blender/draw/DRW_engine.hh b/source/blender/draw/DRW_engine.hh index 08e4b0b337f..ede36c4be9c 100644 --- a/source/blender/draw/DRW_engine.hh +++ b/source/blender/draw/DRW_engine.hh @@ -96,7 +96,7 @@ void DRW_draw_select_loop(Depsgraph *depsgraph, DRW_ObjectFilterFn object_filter_fn, void *object_filter_user_data); /** - * Object mode select-loop. + * Used by auto-depth and other depth queries feature. */ void DRW_draw_depth_loop(Depsgraph *depsgraph, ARegion *region, @@ -109,6 +109,10 @@ void DRW_draw_depth_loop(Depsgraph *depsgraph, */ void DRW_draw_depth_object( Scene *scene, ARegion *region, View3D *v3d, GPUViewport *viewport, Object *object); + +/** + * Edit mesh mode selection. + */ void DRW_draw_select_id(Depsgraph *depsgraph, ARegion *region, View3D *v3d); /** @@ -122,6 +126,12 @@ bool DRW_draw_in_progress(); * Helper to check if exit object type to render. */ bool DRW_render_check_grease_pencil(Depsgraph *depsgraph); +/** + * Render grease pencil on top of other render engine output (but only for non-draw-engine). + * This function creates a DRWContext. + * `DRW_render_to_image()` applies grease pencil using `DRW_render_gpencil_to_image` as it + * already has a DRWContext setup. + */ void DRW_render_gpencil(RenderEngine *engine, Depsgraph *depsgraph); void DRW_render_context_enable(Render *render); diff --git a/source/blender/draw/engines/eevee_next/eevee_instance.cc b/source/blender/draw/engines/eevee_next/eevee_instance.cc index dcf75b6d580..251a9aa4032 100644 --- a/source/blender/draw/engines/eevee_next/eevee_instance.cc +++ b/source/blender/draw/engines/eevee_next/eevee_instance.cc @@ -33,6 +33,7 @@ #include "DNA_particle_types.h" #include "draw_common.hh" +#include "draw_manager_c.hh" #include "draw_view_data.hh" namespace blender::eevee { @@ -710,11 +711,13 @@ void Instance::light_bake_irradiance( { BLI_assert(is_baking()); + DRWContext draw_ctx; + auto custom_pipeline_wrapper = [&](FunctionRef callback) { context_enable(); - DRW_custom_pipeline_begin(&draw_engine_eevee_next_type, depsgraph); + DRW_custom_pipeline_begin(draw_ctx, &draw_engine_eevee_next_type, depsgraph); callback(); - DRW_custom_pipeline_end(); + DRW_custom_pipeline_end(draw_ctx); context_disable(); }; diff --git a/source/blender/draw/engines/eevee_next/eevee_instance.hh b/source/blender/draw/engines/eevee_next/eevee_instance.hh index 3758377c434..30864c5c9a9 100644 --- a/source/blender/draw/engines/eevee_next/eevee_instance.hh +++ b/source/blender/draw/engines/eevee_next/eevee_instance.hh @@ -265,12 +265,14 @@ class Instance { bool is_image_render() const { - return DRW_state_is_image_render(); + /* WORKAROUND: During light baking, this may be called before a DRWContext is bound. */ + return !is_light_bake && DRW_state_is_image_render(); } bool is_viewport_image_render() const { - return DRW_state_is_viewport_image_render(); + /* WORKAROUND: During light baking, this may be called before a DRWContext is bound. */ + return !is_light_bake && DRW_state_is_viewport_image_render(); } bool is_baking() const @@ -291,7 +293,8 @@ class Instance { bool is_playback() const { - return DRW_state_is_playback(); + /* WORKAROUND: During light baking, this may be called before a DRWContext is bound. */ + return !is_light_bake && DRW_state_is_playback(); } bool is_transforming() const @@ -302,12 +305,20 @@ class Instance { bool is_navigating() const { - return DRW_state_is_navigating(); + /* WORKAROUND: During light baking, this may be called before a DRWContext is bound. */ + return !is_light_bake && DRW_state_is_navigating(); } bool is_painting() const { - return DRW_state_is_painting(); + /* WORKAROUND: During light baking, this may be called before a DRWContext is bound. */ + return !is_light_bake && DRW_state_is_painting(); + } + + bool do_display_support() const + { + /* WORKAROUND: During light baking, this may be called before a DRWContext is bound. */ + return !is_light_bake && DRW_state_draw_support(); } bool use_scene_lights() const diff --git a/source/blender/draw/engines/eevee_next/eevee_lightprobe_planar.cc b/source/blender/draw/engines/eevee_next/eevee_lightprobe_planar.cc index 5ee32149319..15801ee449c 100644 --- a/source/blender/draw/engines/eevee_next/eevee_lightprobe_planar.cc +++ b/source/blender/draw/engines/eevee_next/eevee_lightprobe_planar.cc @@ -79,7 +79,7 @@ void PlanarProbeModule::set_view(const draw::View &main_view, int2 main_view_ext depth_tx_.ensure_2d_array(GPU_DEPTH_COMPONENT32F, extent, layer_count, usage); depth_tx_.ensure_layer_views(); - do_display_draw_ = DRW_state_draw_support() && num_probes > 0; + do_display_draw_ = inst_.do_display_support() && num_probes > 0; int resource_index = 0; int display_index = 0; diff --git a/source/blender/draw/engines/eevee_next/eevee_lightprobe_sphere.cc b/source/blender/draw/engines/eevee_next/eevee_lightprobe_sphere.cc index 9042b840379..ee2f75eafa1 100644 --- a/source/blender/draw/engines/eevee_next/eevee_lightprobe_sphere.cc +++ b/source/blender/draw/engines/eevee_next/eevee_lightprobe_sphere.cc @@ -315,7 +315,7 @@ void SphereProbeModule::set_view(View & /*view*/) void SphereProbeModule::sync_display(Vector &probe_active) { do_display_draw_ = false; - if (!DRW_state_draw_support()) { + if (!instance_.do_display_support()) { return; } diff --git a/source/blender/draw/engines/eevee_next/eevee_lightprobe_volume.cc b/source/blender/draw/engines/eevee_next/eevee_lightprobe_volume.cc index 7d2591a30a3..b8320cc3a98 100644 --- a/source/blender/draw/engines/eevee_next/eevee_lightprobe_volume.cc +++ b/source/blender/draw/engines/eevee_next/eevee_lightprobe_volume.cc @@ -25,7 +25,7 @@ namespace blender::eevee { void VolumeProbeModule::init() { - display_grids_enabled_ = DRW_state_draw_support(); + display_grids_enabled_ = inst_.do_display_support(); /* This might become an option in the future. */ bool use_l2_band = false; diff --git a/source/blender/draw/intern/DRW_render.hh b/source/blender/draw/intern/DRW_render.hh index 9b06d54a193..9825a6de514 100644 --- a/source/blender/draw/intern/DRW_render.hh +++ b/source/blender/draw/intern/DRW_render.hh @@ -40,6 +40,7 @@ struct SpaceLink; struct TaskGraph; struct View3D; struct ViewLayer; +struct DRWContext; struct World; namespace blender::draw { class TextureFromPool; @@ -138,18 +139,14 @@ void DRW_render_set_time(RenderEngine *engine, Depsgraph *depsgraph, int frame, * This function only setup DST and execute the given function. * \warning similar to DRW_render_to_image you cannot use default lists (`dfbl` & `dtxl`). */ -void DRW_custom_pipeline(DrawEngineType *draw_engine_type, - Depsgraph *depsgraph, - void (*callback)(void *vedata, void *user_data), - void *user_data); -/** - * Same as `DRW_custom_pipeline` but allow better code-flow than a callback. - */ -void DRW_custom_pipeline_begin(DrawEngineType *draw_engine_type, Depsgraph *depsgraph); -void DRW_custom_pipeline_end(); +void DRW_custom_pipeline_begin(DRWContext &draw_ctx, + DrawEngineType *draw_engine_type, + Depsgraph *depsgraph); +void DRW_custom_pipeline_end(DRWContext &draw_ctx); /** * Used when the render engine want to redo another cache populate inside the same render frame. + * Assumes it is called between `DRW_custom_pipeline_begin/end()`. */ void DRW_cache_restart(); diff --git a/source/blender/draw/intern/draw_debug.cc b/source/blender/draw/intern/draw_debug.cc index e19293358a9..16bc73ee363 100644 --- a/source/blender/draw/intern/draw_debug.cc +++ b/source/blender/draw/intern/draw_debug.cc @@ -15,7 +15,6 @@ #include "GPU_debug.hh" #include "draw_debug.hh" -#include "draw_debug_c.hh" #include "draw_manager_c.hh" #include "draw_shader.hh" #include "draw_shader_shared.hh" @@ -283,7 +282,12 @@ void DebugDraw::display_to_view() blender::draw::DebugDraw *DRW_debug_get() { + /* This module is currently not in working state. Some refactor is needed (see #135521). */ + BLI_assert_unreachable(); +#ifdef WITH_DRAW_DEBUG return reinterpret_cast(drw_get().debug); +#endif + return nullptr; } /** \} */ @@ -327,67 +331,10 @@ void drw_debug_module_free(DRWDebugModule *module) GPUStorageBuf *drw_debug_gpu_draw_buf_get() { +#ifdef WITH_DRAW_DEBUG return reinterpret_cast(drw_get().debug)->gpu_draw_buf_get(); -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name C-API public - * \{ */ - -void DRW_debug_modelmat_reset() -{ - reinterpret_cast(drw_get().debug)->modelmat_reset(); -} - -void DRW_debug_modelmat(const float modelmat[4][4]) -{ -#ifdef WITH_DRAW_DEBUG - reinterpret_cast(drw_get().debug)->modelmat_set(modelmat); -#else - UNUSED_VARS(modelmat); -#endif -} - -void DRW_debug_line_v3v3(const float v1[3], const float v2[3], const float color[4]) -{ - reinterpret_cast(drw_get().debug)->draw_line(v1, v2, color); -} - -void DRW_debug_polygon_v3(const float (*v)[3], int vert_len, const float color[4]) -{ - reinterpret_cast(drw_get().debug) - ->draw_polygon(blender::Span((float3 *)v, vert_len), color); -} - -void DRW_debug_m4(const float m[4][4]) -{ - reinterpret_cast(drw_get().debug)->draw_matrix(float4x4(m)); -} - -void DRW_debug_m4_as_bbox(const float m[4][4], bool invert, const float color[4]) -{ - blender::float4x4 m4(m); - if (invert) { - m4 = blender::math::invert(m4); - } - reinterpret_cast(drw_get().debug)->draw_matrix_as_bbox(m4, color); -} - -void DRW_debug_bbox(const BoundBox *bbox, const float color[4]) -{ -#ifdef WITH_DRAW_DEBUG - reinterpret_cast(drw_get().debug)->draw_bbox(*bbox, color); -#else - UNUSED_VARS(bbox, color); -#endif -} - -void DRW_debug_sphere(const float center[3], float radius, const float color[4]) -{ - reinterpret_cast(drw_get().debug) - ->draw_sphere(center, radius, color); +#endif + return nullptr; } /** \} */ diff --git a/source/blender/draw/intern/draw_debug.hh b/source/blender/draw/intern/draw_debug.hh index ad1a1d7c2eb..bfd4c0aafb1 100644 --- a/source/blender/draw/intern/draw_debug.hh +++ b/source/blender/draw/intern/draw_debug.hh @@ -26,14 +26,24 @@ namespace blender::draw { +#if 0 /* The debug module is currently broken. Needs an overhaul (see #135521). */ /* Shortcuts to avoid boilerplate code and match shader API. */ -#define drw_debug_line(...) DRW_debug_get()->draw_line(__VA_ARGS__) -#define drw_debug_polygon(...) DRW_debug_get()->draw_polygon(__VA_ARGS__) -#define drw_debug_bbox(...) DRW_debug_get()->draw_bbox(__VA_ARGS__) -#define drw_debug_sphere(...) DRW_debug_get()->draw_sphere(__VA_ARGS__) -#define drw_debug_point(...) DRW_debug_get()->draw_point(__VA_ARGS__) -#define drw_debug_matrix(...) DRW_debug_get()->draw_matrix(__VA_ARGS__) -#define drw_debug_matrix_as_bbox(...) DRW_debug_get()->draw_matrix_as_bbox(__VA_ARGS__) +# define drw_debug_line(...) DRW_debug_get()->draw_line(__VA_ARGS__) +# define drw_debug_polygon(...) DRW_debug_get()->draw_polygon(__VA_ARGS__) +# define drw_debug_bbox(...) DRW_debug_get()->draw_bbox(__VA_ARGS__) +# define drw_debug_sphere(...) DRW_debug_get()->draw_sphere(__VA_ARGS__) +# define drw_debug_point(...) DRW_debug_get()->draw_point(__VA_ARGS__) +# define drw_debug_matrix(...) DRW_debug_get()->draw_matrix(__VA_ARGS__) +# define drw_debug_matrix_as_bbox(...) DRW_debug_get()->draw_matrix_as_bbox(__VA_ARGS__) +#else +# define drw_debug_line(...) +# define drw_debug_polygon(...) +# define drw_debug_bbox(...) +# define drw_debug_sphere(...) +# define drw_debug_point(...) +# define drw_debug_matrix(...) +# define drw_debug_matrix_as_bbox(...) +#endif class DebugDraw { private: diff --git a/source/blender/draw/intern/draw_debug_c.hh b/source/blender/draw/intern/draw_debug_c.hh deleted file mode 100644 index f6fe41ce844..00000000000 --- a/source/blender/draw/intern/draw_debug_c.hh +++ /dev/null @@ -1,31 +0,0 @@ -/* SPDX-FileCopyrightText: 2018 Blender Authors - * - * SPDX-License-Identifier: GPL-2.0-or-later */ - -/** \file - * \ingroup draw - * - * \brief Simple API to draw debug shapes in the viewport. - * IMPORTANT: This is the legacy API for C. Use draw_debug.hh instead in new C++ code. - */ - -#pragma once - -struct BoundBox; - -void DRW_debug_modelmat_reset(); -void DRW_debug_modelmat(const float modelmat[4][4]); - -/** - * IMPORTANT: For now there is a limit of DRW_DEBUG_DRAW_VERT_MAX that can be drawn - * using all the draw functions. - */ -void DRW_debug_line_v3v3(const float v1[3], const float v2[3], const float color[4]); -void DRW_debug_polygon_v3(const float (*v)[3], int vert_len, const float color[4]); -/** - * \note g_modelmat is still applied on top. - */ -void DRW_debug_m4(const float m[4][4]); -void DRW_debug_m4_as_bbox(const float m[4][4], bool invert, const float color[4]); -void DRW_debug_bbox(const BoundBox *bbox, const float color[4]); -void DRW_debug_sphere(const float center[3], float radius, const float color[4]); diff --git a/source/blender/draw/intern/draw_manager_c.cc b/source/blender/draw/intern/draw_manager_c.cc index 2178a916f38..d0815ee1775 100644 --- a/source/blender/draw/intern/draw_manager_c.cc +++ b/source/blender/draw/intern/draw_manager_c.cc @@ -132,11 +132,18 @@ static TicketMutex *system_gpu_context_mutex = nullptr; /** \} */ /** Render State: No persistent data between draw calls. */ -DRWContext DST = {}; +thread_local DRWContext *g_context = nullptr; + +static void drw_set(DRWContext &context) +{ + BLI_assert(g_context == nullptr); + g_context = &context; + g_context->prepare_clean_for_draw(); +} DRWContext &drw_get() { - return DST; + return *g_context; } GPUFrameBuffer *DRWContext::default_framebuffer() @@ -147,12 +154,8 @@ GPUFrameBuffer *DRWContext::default_framebuffer() void DRWContext::prepare_clean_for_draw() { - /* Only debug module is persistent. */ - DRWDebugModule *debug = this->debug; /* Reset all members to default values. */ *this = {}; - /* Restore the debug module. */ - this->debug = debug; } /* This function is used to reset draw manager to a state @@ -160,14 +163,12 @@ void DRWContext::prepare_clean_for_draw() * draw calls. */ void DRWContext::state_ensure_not_reused() { - /* Only debug module is persistent. */ - DRWDebugModule *debug = this->debug; #if 0 /* Creates compilation warning. */ /* Poison the whole module. */ - memset(&DST, 0xff, sizeof(DRWContext)); + memset(g_context, 0xff, sizeof(DRWContext)); #endif - /* Restore the debug module. */ - this->debug = debug; + BLI_assert(g_context == this); + g_context = nullptr; } static struct { @@ -1221,8 +1222,8 @@ void DRW_notify_view_update(const DRWUpdateContext *update_ctx) return; } - /* Reset before using it. */ - DST.prepare_clean_for_draw(); + DRWContext draw_ctx; + drw_set(draw_ctx); BKE_view_layer_synced_ensure(scene, view_layer); drw_get().draw_ctx = {}; @@ -1253,7 +1254,7 @@ void DRW_notify_view_update(const DRWUpdateContext *update_ctx) drw_engines_disable(); } - drw_manager_exit(&DST); + drw_manager_exit(&draw_ctx); BLI_ticket_mutex_unlock(system_gpu_context_mutex); } @@ -1274,8 +1275,8 @@ static void drw_notify_view_update_offscreen(Depsgraph *depsgraph, const bool gpencil_engine_needed = drw_gpencil_engine_needed(depsgraph, v3d); - /* Reset before using it. */ - DST.prepare_clean_for_draw(); + DRWContext draw_ctx; + drw_set(draw_ctx); BKE_view_layer_synced_ensure(scene, view_layer); drw_get().draw_ctx = {}; @@ -1305,7 +1306,7 @@ static void drw_notify_view_update_offscreen(Depsgraph *depsgraph, drw_engines_disable(); } - drw_manager_exit(&DST); + drw_manager_exit(&draw_ctx); } } @@ -1520,7 +1521,7 @@ static void DRW_draw_render_loop_3d(Depsgraph *depsgraph, drw_task_graph_init(); drw_context_state_init(); - drw_manager_init(&DST, viewport, nullptr); + drw_manager_init(g_context, viewport, nullptr); DRW_viewport_colormanagement_set(viewport); const int object_type_exclude_viewport = v3d->object_type_exclude_viewport; @@ -1613,8 +1614,6 @@ static void DRW_draw_render_loop_3d(Depsgraph *depsgraph, blender::draw::command::StateSet::set(); drw_engines_disable(); - - drw_manager_exit(&DST); } void DRW_draw_render_loop_offscreen(Depsgraph *depsgraph, @@ -1643,12 +1642,15 @@ void DRW_draw_render_loop_offscreen(Depsgraph *depsgraph, /* Just here to avoid an assert but shouldn't be required in practice. */ GPU_framebuffer_restore(); - /* Reset before using it. */ - DST.prepare_clean_for_draw(); + DRWContext draw_ctx; + drw_set(draw_ctx); drw_get().options.is_image_render = is_image_render; drw_get().options.draw_background = draw_background; + DRW_draw_render_loop_3d(depsgraph, engine_type, region, v3d, render_viewport, nullptr); + drw_manager_exit(&draw_ctx); + if (draw_background) { /* HACK(@fclem): In this case we need to make sure the final alpha is 1. * We use the blend mode to ensure that. A better way to fix that would @@ -1691,7 +1693,7 @@ bool DRW_render_check_grease_pencil(Depsgraph *depsgraph) deg_iter_settings.flags = DEG_OBJECT_ITER_FOR_RENDER_ENGINE_FLAGS; DEG_OBJECT_ITER_BEGIN (°_iter_settings, ob) { if (ob->type == OB_GREASE_PENCIL) { - if (DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF) { + if (BKE_object_visibility(ob, DAG_EVAL_RENDER) & OB_VISIBLE_SELF) { return true; } } @@ -1732,8 +1734,9 @@ void DRW_render_gpencil(RenderEngine *engine, Depsgraph *depsgraph) DRW_render_context_enable(render); - /* Reset before using it. */ - DST.prepare_clean_for_draw(); + DRWContext draw_ctx; + drw_set(draw_ctx); + drw_get().options.is_image_render = true; drw_get().options.is_scene_render = true; drw_get().options.draw_background = scene->r.alphamode == R_ADDSKY; @@ -1749,7 +1752,7 @@ void DRW_render_gpencil(RenderEngine *engine, Depsgraph *depsgraph) const int size[2] = {engine->resolution_x, engine->resolution_y}; - drw_manager_init(&DST, nullptr, size); + drw_manager_init(g_context, nullptr, size); /* Main rendering. */ rctf view_rect; @@ -1772,7 +1775,7 @@ void DRW_render_gpencil(RenderEngine *engine, Depsgraph *depsgraph) GPU_depth_test(GPU_DEPTH_NONE); blender::gpu::TexturePool::get().reset(true); - drw_manager_exit(&DST); + drw_manager_exit(&draw_ctx); /* Restore Drawing area. */ GPU_framebuffer_restore(); @@ -1793,8 +1796,9 @@ void DRW_render_to_image(RenderEngine *engine, Depsgraph *depsgraph) * This shall remain in effect until immediate mode supports * multiple threads. */ - /* Reset before using it. */ - DST.prepare_clean_for_draw(); + DRWContext draw_ctx; + + drw_set(draw_ctx); drw_get().options.is_image_render = true; drw_get().options.is_scene_render = true; drw_get().options.draw_background = scene->r.alphamode == R_ADDSKY; @@ -1812,7 +1816,7 @@ void DRW_render_to_image(RenderEngine *engine, Depsgraph *depsgraph) const int size[2] = {engine->resolution_x, engine->resolution_y}; - drw_manager_init(&DST, nullptr, size); + drw_manager_init(g_context, nullptr, size); ViewportEngineData *data = DRW_view_data_engine_data_get_ensure(drw_get().view_data_active, draw_engine_type); @@ -1861,12 +1865,12 @@ void DRW_render_to_image(RenderEngine *engine, Depsgraph *depsgraph) blender::gpu::TexturePool::get().reset(true); - drw_manager_exit(&DST); - DRW_cache_free_old_subdiv(); - /* Reset state after drawing */ blender::draw::command::StateSet::set(); + drw_manager_exit(&draw_ctx); + DRW_cache_free_old_subdiv(); + /* End GPU workload Boundary */ GPU_render_end(); } @@ -1912,14 +1916,15 @@ void DRW_render_object_iter(void *vedata, drw_task_graph_deinit(); } -void DRW_custom_pipeline_begin(DrawEngineType *draw_engine_type, Depsgraph *depsgraph) +void DRW_custom_pipeline_begin(DRWContext &draw_ctx, + DrawEngineType *draw_engine_type, + Depsgraph *depsgraph) { using namespace blender::draw; Scene *scene = DEG_get_evaluated_scene(depsgraph); ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); - /* Reset before using it. */ - DST.prepare_clean_for_draw(); + drw_set(draw_ctx); drw_get().options.is_image_render = true; drw_get().options.is_scene_render = true; drw_get().options.draw_background = false; @@ -1933,14 +1938,14 @@ void DRW_custom_pipeline_begin(DrawEngineType *draw_engine_type, Depsgraph *deps drw_context_state_init(); - drw_manager_init(&DST, nullptr, nullptr); + drw_manager_init(g_context, nullptr, nullptr); drw_get().data->modules_init(); DRW_view_data_engine_data_get_ensure(drw_get().view_data_active, draw_engine_type); } -void DRW_custom_pipeline_end() +void DRW_custom_pipeline_end(DRWContext &draw_ctx) { drw_get().data->modules_exit(); @@ -1956,22 +1961,7 @@ void DRW_custom_pipeline_end() } blender::gpu::TexturePool::get().reset(true); - drw_manager_exit(&DST); -} - -void DRW_custom_pipeline(DrawEngineType *draw_engine_type, - Depsgraph *depsgraph, - void (*callback)(void *vedata, void *user_data), - void *user_data) -{ - DRW_custom_pipeline_begin(draw_engine_type, depsgraph); - - ViewportEngineData *data = DRW_view_data_engine_data_get_ensure(drw_get().view_data_active, - draw_engine_type); - /* Execute the callback. */ - callback(data, user_data); - - DRW_custom_pipeline_end(); + drw_manager_exit(&draw_ctx); } void DRW_cache_restart() @@ -1979,8 +1969,9 @@ void DRW_cache_restart() using namespace blender::draw; drw_get().data->modules_exit(); - drw_manager_init( - &DST, drw_get().viewport, blender::int2{int(drw_get().size[0]), int(drw_get().size[1])}); + drw_manager_init(g_context, + drw_get().viewport, + blender::int2{int(drw_get().size[0]), int(drw_get().size[1])}); drw_get().data->modules_init(); } @@ -2006,7 +1997,7 @@ static void DRW_draw_render_loop_2d(Depsgraph *depsgraph, drw_get().draw_ctx.evil_C = evil_C; drw_context_state_init(); - drw_manager_init(&DST, viewport, nullptr); + drw_manager_init(g_context, viewport, nullptr); DRW_viewport_colormanagement_set(viewport); /* TODO(jbakker): Only populate when editor needs to draw object. @@ -2117,8 +2108,6 @@ static void DRW_draw_render_loop_2d(Depsgraph *depsgraph, blender::draw::command::StateSet::set(); drw_engines_disable(); - - drw_manager_exit(&DST); } void DRW_draw_view(const bContext *C) @@ -2127,14 +2116,15 @@ void DRW_draw_view(const bContext *C) ARegion *region = CTX_wm_region(C); GPUViewport *viewport = WM_draw_region_get_bound_viewport(region); + DRWContext draw_ctx; + drw_set(draw_ctx); + View3D *v3d = CTX_wm_view3d(C); if (v3d) { Scene *scene = DEG_get_evaluated_scene(depsgraph); RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type); - /* Reset before using it. */ - DST.prepare_clean_for_draw(); drw_get().options.draw_text = ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0 && (v3d->overlay.flag & V3D_OVERLAY_HIDE_TEXT) != 0); drw_get().options.draw_background = (scene->r.alphamode == R_ADDSKY) || @@ -2143,9 +2133,10 @@ void DRW_draw_view(const bContext *C) DRW_draw_render_loop_3d(depsgraph, engine_type, region, v3d, viewport, C); } else { - DST.prepare_clean_for_draw(); DRW_draw_render_loop_2d(depsgraph, region, viewport, C); } + + drw_manager_exit(&draw_ctx); } static struct DRWSelectBuffer { @@ -2209,8 +2200,8 @@ void DRW_draw_select_loop(Depsgraph *depsgraph, Object *obedit = use_obedit_skip ? nullptr : OBEDIT_FROM_OBACT(obact); RegionView3D *rv3d = static_cast(region->regiondata); - /* Reset before using it. */ - DST.prepare_clean_for_draw(); + DRWContext draw_ctx; + drw_set(draw_ctx); bool use_obedit = false; /* obedit_ctx_mode is used for selecting the right draw engines */ @@ -2268,7 +2259,7 @@ void DRW_draw_select_loop(Depsgraph *depsgraph, drw_context_state_init(); const int viewport_size[2] = {BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)}; - drw_manager_init(&DST, nullptr, viewport_size); + drw_manager_init(g_context, nullptr, viewport_size); drw_get().options.is_select = true; drw_get().options.is_material_select = do_material_sub_selection; @@ -2395,7 +2386,7 @@ void DRW_draw_select_loop(Depsgraph *depsgraph, blender::draw::command::StateSet::set(); drw_engines_disable(); - drw_manager_exit(&DST); + drw_manager_exit(&draw_ctx); GPU_framebuffer_restore(); } @@ -2413,8 +2404,8 @@ void DRW_draw_depth_loop(Depsgraph *depsgraph, ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); RegionView3D *rv3d = static_cast(region->regiondata); - /* Reset before using it. */ - DST.prepare_clean_for_draw(); + DRWContext draw_ctx; + drw_set(draw_ctx); drw_get().options.is_depth = true; @@ -2431,7 +2422,7 @@ void DRW_draw_depth_loop(Depsgraph *depsgraph, drw_get().draw_ctx.depsgraph = depsgraph; drw_context_state_init(); - drw_manager_init(&DST, viewport, nullptr); + drw_manager_init(g_context, viewport, nullptr); if (use_gpencil) { use_drw_engine(&draw_engine_gpencil_type); @@ -2512,7 +2503,7 @@ void DRW_draw_depth_loop(Depsgraph *depsgraph, drw_engines_disable(); - drw_manager_exit(&DST); + drw_manager_exit(&draw_ctx); } void DRW_draw_select_id(Depsgraph *depsgraph, ARegion *region, View3D *v3d) @@ -2530,8 +2521,8 @@ void DRW_draw_select_id(Depsgraph *depsgraph, ARegion *region, View3D *v3d) ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); RegionView3D *rv3d = static_cast(region->regiondata); - /* Reset before using it. */ - DST.prepare_clean_for_draw(); + DRWContext draw_ctx; + drw_set(draw_ctx); /* Instead of 'DRW_context_state_init(C, &drw_get().draw_ctx)', assign from args */ BKE_view_layer_synced_ensure(scene, view_layer); @@ -2547,7 +2538,7 @@ void DRW_draw_select_id(Depsgraph *depsgraph, ARegion *region, View3D *v3d) drw_task_graph_init(); drw_context_state_init(); - drw_manager_init(&DST, viewport, nullptr); + drw_manager_init(g_context, viewport, nullptr); /* Make sure select engine gets the correct vertex size. */ UI_SetTheme(SPACE_VIEW3D, RGN_TYPE_WINDOW); @@ -2598,7 +2589,7 @@ void DRW_draw_select_id(Depsgraph *depsgraph, ARegion *region, View3D *v3d) drw_engines_disable(); - drw_manager_exit(&DST); + drw_manager_exit(&draw_ctx); } void DRW_draw_depth_object( @@ -2895,9 +2886,6 @@ void DRW_engines_free() DRW_shaders_free(); - drw_debug_module_free(drw_get().debug); - drw_get().debug = nullptr; - DRW_gpu_context_disable(); } diff --git a/source/blender/draw/intern/draw_manager_c.hh b/source/blender/draw/intern/draw_manager_c.hh index dfb7eaf5e2b..6619de80640 100644 --- a/source/blender/draw/intern/draw_manager_c.hh +++ b/source/blender/draw/intern/draw_manager_c.hh @@ -126,9 +126,6 @@ struct DRWContext { /* Contains list of objects that needs to be extracted from other objects. */ GSet *delayed_extraction = nullptr; - /* Contains debug drawcall infos. Persistent across usage. */ - DRWDebugModule *debug = nullptr; - /* Reset all members before drawing in order to avoid undefined state. */ void prepare_clean_for_draw(); /* Poison all members to detect missing `prepare_clean_for_draw()`. */