Draw: Use unique handles where possible
Use `unique_handle` where possible. Add `unique_handle_for_sculpt`. This also updates `ObjectRef` to make all its properties either immutable or private. Pull Request: https://projects.blender.org/blender/blender/pulls/139852
This commit is contained in:
@@ -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<float3> 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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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_ ?
|
||||
|
||||
@@ -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) |
|
||||
|
||||
@@ -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<Mesh>(*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();
|
||||
|
||||
@@ -182,16 +182,12 @@ class Instance : public DrawEngine {
|
||||
|
||||
if (is_object_data_visible) {
|
||||
if (object_state.sculpt_pbvh) {
|
||||
const Bounds<float3> 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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -55,7 +55,7 @@ struct GSet;
|
||||
struct GPUViewport;
|
||||
namespace blender::draw {
|
||||
class TextureFromPool;
|
||||
struct ObjectRef;
|
||||
class ObjectRef;
|
||||
class Manager;
|
||||
} // namespace blender::draw
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ enum eMeshBatchDirtyMode : int8_t;
|
||||
|
||||
namespace blender::draw {
|
||||
|
||||
struct ObjectRef;
|
||||
class ObjectRef;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Expose via BKE callbacks
|
||||
|
||||
@@ -28,7 +28,7 @@ class Manager;
|
||||
struct CurvesModule;
|
||||
struct PointCloudModule;
|
||||
struct VolumeModule;
|
||||
struct ObjectRef;
|
||||
class ObjectRef;
|
||||
} // namespace blender::draw
|
||||
|
||||
/* draw_hair.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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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<float3> 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<ObjectRef &>(ref).sculpt_handle_ = resource_handle(
|
||||
ref, nullptr, ¢er, &half_extent);
|
||||
return ref.sculpt_handle_;
|
||||
}
|
||||
|
||||
void Manager::compute_visibility(View &view)
|
||||
|
||||
@@ -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<ObjectRef &>(ref).handle = resource_handle(ref);
|
||||
const_cast<ObjectRef &>(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)
|
||||
|
||||
@@ -38,7 +38,7 @@ struct GPULayerAttr;
|
||||
|
||||
namespace blender::draw {
|
||||
|
||||
struct ObjectRef;
|
||||
class ObjectRef;
|
||||
|
||||
} // namespace blender::draw
|
||||
|
||||
|
||||
Reference in New Issue
Block a user