diff --git a/source/blender/draw/engines/eevee/eevee_sync.cc b/source/blender/draw/engines/eevee/eevee_sync.cc index a25536705a6..a06f7fb4328 100644 --- a/source/blender/draw/engines/eevee/eevee_sync.cc +++ b/source/blender/draw/engines/eevee/eevee_sync.cc @@ -178,7 +178,7 @@ bool SyncModule::sync_sculpt(Object *ob, ObjectHandle &ob_handle, const ObjectRe return false; } - ResourceHandle res_handle = inst_.manager->unique_handle(ob_ref); + ResourceHandle res_handle = inst_.manager->unique_handle_for_sculpt(ob_ref); bool has_motion = false; MaterialArray &material_array = inst_.materials.material_array_get(ob, has_motion); @@ -235,13 +235,6 @@ bool SyncModule::sync_sculpt(Object *ob, ObjectHandle &ob_handle, const ObjectRe inst_.volume.object_sync(ob_handle); } - /* Use a valid bounding box. The pbvh::Tree module already does its own culling, but a valid */ - /* bounding box is still needed for directional shadow tile-map bounds computation. */ - const Bounds bounds = bke::pbvh::bounds_get(*bke::object::pbvh_get(*ob_ref.object)); - const float3 center = math::midpoint(bounds.min, bounds.max); - const float3 half_extent = bounds.max - center + inflate_bounds; - inst_.manager->update_handle_bounds(res_handle, center, half_extent); - inst_.manager->extract_object_attributes(res_handle, ob_ref, material_array.gpu_materials); inst_.shadows.sync_object(ob, ob_handle, res_handle, is_alpha_blend, has_transparent_shadows); diff --git a/source/blender/draw/engines/external/external_engine.cc b/source/blender/draw/engines/external/external_engine.cc index a3f60b67446..e64f83bbf48 100644 --- a/source/blender/draw/engines/external/external_engine.cc +++ b/source/blender/draw/engines/external/external_engine.cc @@ -123,7 +123,7 @@ class Prepass { void sculpt_sync(Manager &manager, const ObjectRef &ob_ref) { - ResourceHandle handle = manager.resource_handle_for_sculpt(ob_ref); + ResourceHandle handle = manager.unique_handle_for_sculpt(ob_ref); for (SculptBatch &batch : sculpt_batches_get(ob_ref.object, SCULPT_BATCH_DEFAULT)) { mesh_ps_->draw(batch.batch, handle); diff --git a/source/blender/draw/engines/overlay/overlay_attribute_viewer.hh b/source/blender/draw/engines/overlay/overlay_attribute_viewer.hh index c33ca014ef6..7e11b3feaf4 100644 --- a/source/blender/draw/engines/overlay/overlay_attribute_viewer.hh +++ b/source/blender/draw/engines/overlay/overlay_attribute_viewer.hh @@ -147,7 +147,7 @@ class AttributeViewer : Overlay { gpu::Batch *batch = DRW_cache_curve_edge_wire_get(&object); auto &sub = *instance_sub_; sub.push_constant("ucolor", float4(color)); - ResourceHandle res_handle = manager.resource_handle(object.object_to_world()); + ResourceHandle res_handle = manager.unique_handle(ob_ref); sub.draw(batch, res_handle); break; } @@ -214,7 +214,7 @@ class AttributeViewer : Overlay { gpu::Batch *batch = DRW_cache_curve_edge_wire_viewer_attribute_get(&object); auto &sub = *curve_sub_; sub.push_constant("opacity", opacity); - ResourceHandle res_handle = manager.resource_handle(object.object_to_world()); + ResourceHandle res_handle = manager.unique_handle(ob_ref); sub.draw(batch, res_handle); } } diff --git a/source/blender/draw/engines/overlay/overlay_facing.hh b/source/blender/draw/engines/overlay/overlay_facing.hh index 61f5e75dae7..46dcf892c5d 100644 --- a/source/blender/draw/engines/overlay/overlay_facing.hh +++ b/source/blender/draw/engines/overlay/overlay_facing.hh @@ -75,7 +75,7 @@ class Facing : Overlay { !state.is_image_render; if (use_sculpt_pbvh) { - ResourceHandle handle = manager.resource_handle_for_sculpt(ob_ref); + ResourceHandle handle = manager.unique_handle_for_sculpt(ob_ref); for (SculptBatch &batch : sculpt_batches_get(ob_ref.object, SCULPT_BATCH_DEFAULT)) { ps_.draw(batch.batch, handle); diff --git a/source/blender/draw/engines/overlay/overlay_fade.hh b/source/blender/draw/engines/overlay/overlay_fade.hh index f5b901fecba..d7a901d4cf4 100644 --- a/source/blender/draw/engines/overlay/overlay_fade.hh +++ b/source/blender/draw/engines/overlay/overlay_fade.hh @@ -97,7 +97,7 @@ class Fade : Overlay { !state.is_image_render; if (use_sculpt_pbvh) { - ResourceHandle handle = manager.resource_handle_for_sculpt(ob_ref); + ResourceHandle handle = manager.unique_handle_for_sculpt(ob_ref); for (SculptBatch &batch : sculpt_batches_get(ob_ref.object, SCULPT_BATCH_DEFAULT)) { sub.draw(batch.batch, handle); diff --git a/source/blender/draw/engines/overlay/overlay_mode_transfer.hh b/source/blender/draw/engines/overlay/overlay_mode_transfer.hh index 30e75bc344f..9a700784498 100644 --- a/source/blender/draw/engines/overlay/overlay_mode_transfer.hh +++ b/source/blender/draw/engines/overlay/overlay_mode_transfer.hh @@ -87,7 +87,7 @@ class ModeTransfer : Overlay { const bool use_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob_ref.object, state.rv3d) && !state.is_image_render; if (use_sculpt_pbvh) { - ResourceHandle handle = manager.resource_handle_for_sculpt(ob_ref); + ResourceHandle handle = manager.unique_handle_for_sculpt(ob_ref); for (SculptBatch &batch : sculpt_batches_get(ob_ref.object, SCULPT_BATCH_DEFAULT)) { ps_.draw(batch.batch, handle); diff --git a/source/blender/draw/engines/overlay/overlay_prepass.hh b/source/blender/draw/engines/overlay/overlay_prepass.hh index 9af36ffdc68..79cb3898a23 100644 --- a/source/blender/draw/engines/overlay/overlay_prepass.hh +++ b/source/blender/draw/engines/overlay/overlay_prepass.hh @@ -168,7 +168,7 @@ class Prepass : Overlay { void sculpt_sync(Manager &manager, const ObjectRef &ob_ref, Resources &res) { - ResourceHandle handle = manager.resource_handle_for_sculpt(ob_ref); + ResourceHandle handle = manager.unique_handle_for_sculpt(ob_ref); for (SculptBatch &batch : sculpt_batches_get(ob_ref.object, SCULPT_BATCH_DEFAULT)) { select::ID select_id = use_material_slot_selection_ ? diff --git a/source/blender/draw/engines/overlay/overlay_sculpt.hh b/source/blender/draw/engines/overlay/overlay_sculpt.hh index a08ff9b93f4..1c7f00cdf68 100644 --- a/source/blender/draw/engines/overlay/overlay_sculpt.hh +++ b/source/blender/draw/engines/overlay/overlay_sculpt.hh @@ -210,7 +210,7 @@ class Sculpts : Overlay { const bool use_pbvh = BKE_sculptsession_use_pbvh_draw(ob_ref.object, state.rv3d); if (use_pbvh) { - ResourceHandle handle = manager.resource_handle_for_sculpt(ob_ref); + ResourceHandle handle = manager.unique_handle_for_sculpt(ob_ref); SculptBatchFeature sculpt_batch_features_ = (show_face_set_ ? SCULPT_BATCH_FACE_SET : SCULPT_BATCH_DEFAULT) | diff --git a/source/blender/draw/engines/select/select_engine.cc b/source/blender/draw/engines/select/select_engine.cc index d5fc9ba46c5..093e642bc72 100644 --- a/source/blender/draw/engines/select/select_engine.cc +++ b/source/blender/draw/engines/select/select_engine.cc @@ -340,14 +340,14 @@ struct Instance : public DrawEngine { blender::gpu::Batch *geom_faces = DRW_mesh_batch_cache_get_surface( DRW_object_get_data_for_drawing(*ob)); - depth_occlude->draw(geom_faces, manager.resource_handle(ob_ref)); + depth_occlude->draw(geom_faces, manager.unique_handle(ob_ref)); return; } /* Only sync selectable object once. * This can happen in retopology mode where there is two sync loop. */ sel_ctx.elem_ranges.lookup_or_add_cb(ob, [&]() { - ResourceHandle res_handle = manager.resource_handle(ob_ref); + ResourceHandle res_handle = manager.unique_handle(ob_ref); ElemIndexRanges elem_ranges = object_sync( draw_ctx->v3d, ob, res_handle, sel_ctx.select_mode, sel_ctx.max_index_drawn_len); sel_ctx.max_index_drawn_len = elem_ranges.total.one_after_last(); diff --git a/source/blender/draw/engines/workbench/workbench_engine.cc b/source/blender/draw/engines/workbench/workbench_engine.cc index 91bb3b4fde8..3dae245dd6b 100644 --- a/source/blender/draw/engines/workbench/workbench_engine.cc +++ b/source/blender/draw/engines/workbench/workbench_engine.cc @@ -182,16 +182,12 @@ class Instance : public DrawEngine { if (is_object_data_visible) { if (object_state.sculpt_pbvh) { - const Bounds bounds = bke::pbvh::bounds_get( - *bke::object::pbvh_get(*ob_ref.object)); - const float3 center = math::midpoint(bounds.min, bounds.max); - const float3 half_extent = bounds.max - center; - ResourceHandle handle = manager.resource_handle(ob_ref, nullptr, ¢er, &half_extent); + ResourceHandle handle = manager.unique_handle_for_sculpt(ob_ref); this->sculpt_sync(ob_ref, handle, object_state); emitter_handle = handle; } else if (ob->type == OB_MESH) { - ResourceHandle handle = manager.resource_handle(ob_ref); + ResourceHandle handle = manager.unique_handle(ob_ref); this->mesh_sync(ob_ref, handle, object_state); emitter_handle = handle; } @@ -381,7 +377,7 @@ class Instance : public DrawEngine { void pointcloud_sync(Manager &manager, ObjectRef &ob_ref, const ObjectState &object_state) { - ResourceHandle handle = manager.resource_handle(ob_ref); + ResourceHandle handle = manager.unique_handle(ob_ref); Material mat = this->get_material(ob_ref, object_state.color_type); resources_.material_buf.append(mat); @@ -402,8 +398,8 @@ class Instance : public DrawEngine { ParticleSystem *psys, ModifierData *md) { - /* Skip frustum culling. */ - ResourceHandle handle = manager.resource_handle(ob_ref.object->object_to_world()); + ResourceHandle handle = manager.resource_handle_for_psys(ob_ref, + ob_ref.object->object_to_world()); Material mat = this->get_material(ob_ref, object_state.color_type, psys->part->omat - 1); MaterialTexture texture; @@ -424,8 +420,7 @@ class Instance : public DrawEngine { void curves_sync(Manager &manager, ObjectRef &ob_ref, const ObjectState &object_state) { - /* Skip frustum culling. */ - ResourceHandle handle = manager.resource_handle(ob_ref.object->object_to_world()); + ResourceHandle handle = manager.unique_handle(ob_ref); Material mat = this->get_material(ob_ref, object_state.color_type); resources_.material_buf.append(mat); diff --git a/source/blender/draw/engines/workbench/workbench_volume.cc b/source/blender/draw/engines/workbench/workbench_volume.cc index aa73549f186..4d9f4ad6bbc 100644 --- a/source/blender/draw/engines/workbench/workbench_volume.cc +++ b/source/blender/draw/engines/workbench/workbench_volume.cc @@ -220,7 +220,7 @@ void VolumePass::draw_slice_ps(Manager &manager, ps.push_constant("slice_axis", axis); ps.push_constant("step_length", step_length); - ps.draw(resources.volume_cube_batch, manager.resource_handle(ob_ref)); + ps.draw(resources.volume_cube_batch, manager.unique_handle(ob_ref)); } void VolumePass::draw_volume_ps(Manager &manager, @@ -242,7 +242,7 @@ void VolumePass::draw_volume_ps(Manager &manager, ps.push_constant("step_length", step_length); ps.push_constant("noise_ofs", float(noise_offset)); - ps.draw(resources.volume_cube_batch, manager.resource_handle(ob_ref)); + ps.draw(resources.volume_cube_batch, manager.unique_handle(ob_ref)); } } // namespace blender::workbench diff --git a/source/blender/draw/intern/DRW_render.hh b/source/blender/draw/intern/DRW_render.hh index 0e2d0a1683c..7fe0327f621 100644 --- a/source/blender/draw/intern/DRW_render.hh +++ b/source/blender/draw/intern/DRW_render.hh @@ -55,7 +55,7 @@ struct GSet; struct GPUViewport; namespace blender::draw { class TextureFromPool; -struct ObjectRef; +class ObjectRef; class Manager; } // namespace blender::draw diff --git a/source/blender/draw/intern/draw_cache_impl.hh b/source/blender/draw/intern/draw_cache_impl.hh index 4423aadfba6..0ae72fb1a5b 100644 --- a/source/blender/draw/intern/draw_cache_impl.hh +++ b/source/blender/draw/intern/draw_cache_impl.hh @@ -39,7 +39,7 @@ enum eMeshBatchDirtyMode : int8_t; namespace blender::draw { -struct ObjectRef; +class ObjectRef; /* -------------------------------------------------------------------- */ /** \name Expose via BKE callbacks diff --git a/source/blender/draw/intern/draw_common_c.hh b/source/blender/draw/intern/draw_common_c.hh index f0512b310e0..cb204dbe73e 100644 --- a/source/blender/draw/intern/draw_common_c.hh +++ b/source/blender/draw/intern/draw_common_c.hh @@ -28,7 +28,7 @@ class Manager; struct CurvesModule; struct PointCloudModule; struct VolumeModule; -struct ObjectRef; +class ObjectRef; } // namespace blender::draw /* draw_hair.cc */ diff --git a/source/blender/draw/intern/draw_context.cc b/source/blender/draw/intern/draw_context.cc index 688f4637198..2f7ba26c523 100644 --- a/source/blender/draw/intern/draw_context.cc +++ b/source/blender/draw/intern/draw_context.cc @@ -674,22 +674,13 @@ void DupliCacheManager::extract_all(ExtractionGraph &extraction) namespace blender::draw { ObjectRef::ObjectRef(DEGObjectIterData &iter_data, Object *ob) + : dupli_object_(iter_data.dupli_object_current), + dupli_parent_(iter_data.dupli_parent), + object(ob) { - this->dupli_parent_ = iter_data.dupli_parent; - this->dupli_object_ = iter_data.dupli_object_current; - this->object = ob; - /* Set by the first draw-call. */ - this->handle = ResourceHandle(0); } -ObjectRef::ObjectRef(Object *ob) -{ - this->dupli_parent_ = nullptr; - this->dupli_object_ = nullptr; - this->object = ob; - /* Set by the first draw-call. */ - this->handle = ResourceHandle(0); -} +ObjectRef::ObjectRef(Object *ob) : object(ob) {} } // namespace blender::draw diff --git a/source/blender/draw/intern/draw_handle.hh b/source/blender/draw/intern/draw_handle.hh index 4926b003d54..0c28e536ec3 100644 --- a/source/blender/draw/intern/draw_handle.hh +++ b/source/blender/draw/intern/draw_handle.hh @@ -96,22 +96,24 @@ struct ResourceHandleRange { }; /* TODO(fclem): Move to somewhere more appropriated after cleaning up the header dependencies. */ -struct ObjectRef { +class ObjectRef { + friend class Manager; friend class ObjectKey; friend DupliCacheManager; private: /** Duplicated object that corresponds to the current object. */ - DupliObject *dupli_object_; + DupliObject *const dupli_object_ = nullptr; /** Object that created the dupli-list the current object is part of. */ - Object *dupli_parent_; + Object *const dupli_parent_ = nullptr; + + /** Unique handle per object ref. */ + ResourceHandleRange handle_ = {0, 0}; + ResourceHandleRange sculpt_handle_ = {0, 0}; public: - Object *object; - /** Unique handle per object ref. */ - ResourceHandleRange handle; + Object *const object; - ObjectRef() = default; ObjectRef(DEGObjectIterData &iter_data, Object *ob); ObjectRef(Object *ob); diff --git a/source/blender/draw/intern/draw_manager.cc b/source/blender/draw/intern/draw_manager.cc index ccbffe91586..4fc6d60c8a3 100644 --- a/source/blender/draw/intern/draw_manager.cc +++ b/source/blender/draw/intern/draw_manager.cc @@ -172,14 +172,19 @@ uint64_t Manager::fingerprint_get() return sync_counter_ | (uint64_t(resource_len_) << 32); } -ResourceHandleRange Manager::resource_handle_for_sculpt(const ObjectRef &ref) +ResourceHandleRange Manager::unique_handle_for_sculpt(const ObjectRef &ref) { - /* TODO(fclem): Deduplicate with other engine. */ + if (ref.sculpt_handle_.handle_first.raw != 0) { + return ref.sculpt_handle_; + } const bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(*ref.object); const blender::Bounds bounds = bke::pbvh::bounds_get(pbvh); const float3 center = math::midpoint(bounds.min, bounds.max); const float3 half_extent = bounds.max - center; - return resource_handle(ref, nullptr, ¢er, &half_extent); + /* WORKAROUND: Instead of breaking const correctness everywhere, we only break it for this. */ + const_cast(ref).sculpt_handle_ = resource_handle( + ref, nullptr, ¢er, &half_extent); + return ref.sculpt_handle_; } void Manager::compute_visibility(View &view) diff --git a/source/blender/draw/intern/draw_manager.hh b/source/blender/draw/intern/draw_manager.hh index e1c9405a84b..67720931472 100644 --- a/source/blender/draw/intern/draw_manager.hh +++ b/source/blender/draw/intern/draw_manager.hh @@ -123,11 +123,14 @@ class Manager { * Create a unique resource handle for the given object. * Returns the existing handle if it exists. */ + /* WORKAROUND: Instead of breaking const correctness everywhere, we only break it for this. */ ResourceHandleRange unique_handle(const ObjectRef &ref); + + ResourceHandleRange unique_handle_for_sculpt(const ObjectRef &ref); + /** * Create a new resource handle for the given object. */ - /* WORKAROUND: Instead of breaking const correctness everywhere, we only break it for this. */ ResourceHandleRange resource_handle(const ObjectRef &ref, float inflate_bounds = 0.0f); /** * Create a new resource handle for the given object, but optionally override model matrix and @@ -156,16 +159,10 @@ class Manager { */ ResourceHandle resource_handle_for_psys(const ObjectRef &ref, const float4x4 &model_matrix); - ResourceHandleRange resource_handle_for_sculpt(const ObjectRef &ref); - /** Update the bounds of an already created handle. */ void update_handle_bounds(ResourceHandle handle, const ObjectRef &ref, float inflate_bounds = 0.0f); - /** Update the bounds of an already created handle. */ - void update_handle_bounds(ResourceHandle handle, - const float3 &bounds_center, - const float3 &bounds_half_extent); /** * Populate additional per resource data on demand. @@ -317,11 +314,11 @@ class Manager { inline ResourceHandleRange Manager::unique_handle(const ObjectRef &ref) { - if (ref.handle.handle_first.raw == 0) { + if (ref.handle_.handle_first.raw == 0) { /* WORKAROUND: Instead of breaking const correctness everywhere, we only break it for this. */ - const_cast(ref).handle = resource_handle(ref); + const_cast(ref).handle_ = resource_handle(ref); } - return ref.handle; + return ref.handle_; } inline ResourceHandleRange Manager::resource_handle(const ObjectRef &ref, float inflate_bounds) @@ -388,13 +385,6 @@ inline void Manager::update_handle_bounds(ResourceHandle handle, bounds_buf.current()[handle.resource_index()].sync(*ref.object, inflate_bounds); } -inline void Manager::update_handle_bounds(ResourceHandle handle, - const float3 &bounds_center, - const float3 &bounds_half_extent) -{ - bounds_buf.current()[handle.resource_index()].sync(bounds_center, bounds_half_extent); -} - inline void Manager::extract_object_attributes(ResourceHandle handle, const ObjectRef &ref, const GPUMaterial *material) diff --git a/source/blender/draw/intern/draw_shader_shared.hh b/source/blender/draw/intern/draw_shader_shared.hh index 42cb4ae6133..086cc6880c8 100644 --- a/source/blender/draw/intern/draw_shader_shared.hh +++ b/source/blender/draw/intern/draw_shader_shared.hh @@ -38,7 +38,7 @@ struct GPULayerAttr; namespace blender::draw { -struct ObjectRef; +class ObjectRef; } // namespace blender::draw