Changeset View
Changeset View
Standalone View
Standalone View
source/blender/draw/intern/draw_cache_impl_curves.cc
| Show First 20 Lines • Show All 506 Lines • ▼ Show 20 Lines | |||||
| static bool curves_ensure_attributes(const Curves &curves, | static bool curves_ensure_attributes(const Curves &curves, | ||||
| CurvesBatchCache &cache, | CurvesBatchCache &cache, | ||||
| GPUMaterial *gpu_material, | GPUMaterial *gpu_material, | ||||
| int subdiv) | int subdiv) | ||||
| { | { | ||||
| ThreadMutex *render_mutex = &cache.render_mutex; | ThreadMutex *render_mutex = &cache.render_mutex; | ||||
| const CustomData *cd_curve = &curves.geometry.curve_data; | const CustomData *cd_curve = &curves.geometry.curve_data; | ||||
| const CustomData *cd_point = &curves.geometry.point_data; | const CustomData *cd_point = &curves.geometry.point_data; | ||||
| CurvesEvalFinalCache &final_cache = cache.curves_cache.final[subdiv]; | |||||
| if (gpu_material) { | |||||
| DRW_Attributes attrs_needed; | DRW_Attributes attrs_needed; | ||||
| drw_attributes_clear(&attrs_needed); | drw_attributes_clear(&attrs_needed); | ||||
| ListBase gpu_attrs = GPU_material_attributes(gpu_material); | ListBase gpu_attrs = GPU_material_attributes(gpu_material); | ||||
| LISTBASE_FOREACH (GPUMaterialAttribute *, gpu_attr, &gpu_attrs) { | LISTBASE_FOREACH (GPUMaterialAttribute *, gpu_attr, &gpu_attrs) { | ||||
| const char *name = gpu_attr->name; | const char *name = gpu_attr->name; | ||||
| int layer_index; | int layer_index; | ||||
| eCustomDataType type; | eCustomDataType type; | ||||
| eAttrDomain domain; | eAttrDomain domain; | ||||
| if (drw_custom_data_match_attribute(cd_curve, name, &layer_index, &type)) { | if (drw_custom_data_match_attribute(cd_curve, name, &layer_index, &type)) { | ||||
| domain = ATTR_DOMAIN_CURVE; | domain = ATTR_DOMAIN_CURVE; | ||||
| } | } | ||||
| else if (drw_custom_data_match_attribute(cd_point, name, &layer_index, &type)) { | else if (drw_custom_data_match_attribute(cd_point, name, &layer_index, &type)) { | ||||
| domain = ATTR_DOMAIN_POINT; | domain = ATTR_DOMAIN_POINT; | ||||
| } | } | ||||
| else { | else { | ||||
| continue; | continue; | ||||
| } | } | ||||
| drw_attributes_add_request(&attrs_needed, name, type, layer_index, domain); | drw_attributes_add_request(&attrs_needed, name, type, layer_index, domain); | ||||
| } | } | ||||
| CurvesEvalFinalCache &final_cache = cache.curves_cache.final[subdiv]; | |||||
| if (!drw_attributes_overlap(&final_cache.attr_used, &attrs_needed)) { | if (!drw_attributes_overlap(&final_cache.attr_used, &attrs_needed)) { | ||||
| /* Some new attributes have been added, free all and start over. */ | /* Some new attributes have been added, free all and start over. */ | ||||
| for (const int i : IndexRange(GPU_MAX_ATTR)) { | for (const int i : IndexRange(GPU_MAX_ATTR)) { | ||||
| GPU_VERTBUF_DISCARD_SAFE(cache.curves_cache.proc_attributes_buf[i]); | GPU_VERTBUF_DISCARD_SAFE(cache.curves_cache.proc_attributes_buf[i]); | ||||
| DRW_TEXTURE_FREE_SAFE(cache.curves_cache.proc_attributes_tex[i]); | DRW_TEXTURE_FREE_SAFE(cache.curves_cache.proc_attributes_tex[i]); | ||||
| } | } | ||||
| drw_attributes_merge(&final_cache.attr_used, &attrs_needed, render_mutex); | drw_attributes_merge(&final_cache.attr_used, &attrs_needed, render_mutex); | ||||
| } | } | ||||
| drw_attributes_merge(&final_cache.attr_used_over_time, &attrs_needed, render_mutex); | drw_attributes_merge(&final_cache.attr_used_over_time, &attrs_needed, render_mutex); | ||||
| } | |||||
| bool need_tf_update = false; | bool need_tf_update = false; | ||||
| for (const int i : IndexRange(final_cache.attr_used.num_requests)) { | for (const int i : IndexRange(final_cache.attr_used.num_requests)) { | ||||
| const DRW_AttributeRequest &request = final_cache.attr_used.requests[i]; | const DRW_AttributeRequest &request = final_cache.attr_used.requests[i]; | ||||
| if (cache.curves_cache.proc_attributes_buf[i] != nullptr) { | if (cache.curves_cache.proc_attributes_buf[i] != nullptr) { | ||||
| continue; | continue; | ||||
| Show All 40 Lines | if ((*r_hair_cache)->final[subdiv].proc_buf == nullptr) { | ||||
| curves_batch_cache_ensure_procedural_final_points(cache.curves_cache, subdiv); | curves_batch_cache_ensure_procedural_final_points(cache.curves_cache, subdiv); | ||||
| need_ft_update = true; | need_ft_update = true; | ||||
| } | } | ||||
| if ((*r_hair_cache)->final[subdiv].proc_hairs[thickness_res - 1] == nullptr) { | if ((*r_hair_cache)->final[subdiv].proc_hairs[thickness_res - 1] == nullptr) { | ||||
| curves_batch_cache_ensure_procedural_indices( | curves_batch_cache_ensure_procedural_indices( | ||||
| *curves, cache.curves_cache, thickness_res, subdiv); | *curves, cache.curves_cache, thickness_res, subdiv); | ||||
| } | } | ||||
| if (gpu_material) { | |||||
| need_ft_update |= curves_ensure_attributes(*curves, cache, gpu_material, subdiv); | need_ft_update |= curves_ensure_attributes(*curves, cache, gpu_material, subdiv); | ||||
| } | |||||
| return need_ft_update; | return need_ft_update; | ||||
| } | } | ||||
| int DRW_curves_material_count_get(Curves *curves) | int DRW_curves_material_count_get(Curves *curves) | ||||
| { | { | ||||
| return max_ii(1, curves->totcol); | return max_ii(1, curves->totcol); | ||||
| } | } | ||||
| GPUBatch *DRW_curves_batch_cache_get_edit_points(Curves *curves) | GPUBatch *DRW_curves_batch_cache_get_edit_points(Curves *curves) | ||||
| { | { | ||||
| CurvesBatchCache &cache = curves_batch_cache_get(*curves); | CurvesBatchCache &cache = curves_batch_cache_get(*curves); | ||||
| return DRW_batch_request(&cache.edit_points); | return DRW_batch_request(&cache.edit_points); | ||||
| } | } | ||||
| static void request_attribute(Curves &curves, const char *name) | |||||
| { | |||||
| CurvesBatchCache &cache = curves_batch_cache_get(curves); | |||||
| const DRWContextState *draw_ctx = DRW_context_state_get(); | |||||
| const Scene *scene = draw_ctx->scene; | |||||
| const int subdiv = scene->r.hair_subdiv; | |||||
| CurvesEvalFinalCache &final_cache = cache.curves_cache.final[subdiv]; | |||||
| DRW_Attributes attributes{}; | |||||
| CurveComponent component; | |||||
| component.replace(&curves, GeometryOwnershipType::ReadOnly); | |||||
| std::optional<AttributeMetaData> meta_data = component.attribute_get_meta_data(name); | |||||
| if (!meta_data) { | |||||
| return; | |||||
| } | |||||
| const eAttrDomain domain = meta_data->domain; | |||||
| const eCustomDataType type = meta_data->data_type; | |||||
| const CustomData &custom_data = domain == ATTR_DOMAIN_POINT ? curves.geometry.point_data : | |||||
| curves.geometry.curve_data; | |||||
| drw_attributes_add_request( | |||||
| &attributes, name, type, CustomData_get_named_layer(&custom_data, type, name), domain); | |||||
| drw_attributes_merge(&final_cache.attr_used, &attributes, &cache.render_mutex); | |||||
| } | |||||
| GPUTexture **DRW_curves_texture_for_evaluated_attribute(Curves *curves, | |||||
| const char *name, | |||||
| bool *r_is_point_domain) | |||||
| { | |||||
| CurvesBatchCache &cache = curves_batch_cache_get(*curves); | |||||
| const DRWContextState *draw_ctx = DRW_context_state_get(); | |||||
| const Scene *scene = draw_ctx->scene; | |||||
| const int subdiv = scene->r.hair_subdiv; | |||||
| CurvesEvalFinalCache &final_cache = cache.curves_cache.final[subdiv]; | |||||
| request_attribute(*curves, name); | |||||
| int request_i = -1; | |||||
| for (const int i : IndexRange(final_cache.attr_used.num_requests)) { | |||||
| if (STREQ(final_cache.attr_used.requests[i].attribute_name, name)) { | |||||
| request_i = i; | |||||
| break; | |||||
| } | |||||
| } | |||||
| if (request_i == -1) { | |||||
| *r_is_point_domain = false; | |||||
| return nullptr; | |||||
| } | |||||
| switch (final_cache.attr_used.requests[request_i].domain) { | |||||
| case ATTR_DOMAIN_POINT: | |||||
| *r_is_point_domain = true; | |||||
| return &final_cache.attributes_tex[request_i]; | |||||
| case ATTR_DOMAIN_CURVE: | |||||
| *r_is_point_domain = false; | |||||
| return &cache.curves_cache.proc_attributes_tex[request_i]; | |||||
| default: | |||||
| BLI_assert_unreachable(); | |||||
| return nullptr; | |||||
| } | |||||
| } | |||||
| void DRW_curves_batch_cache_create_requested(Object *ob) | void DRW_curves_batch_cache_create_requested(Object *ob) | ||||
| { | { | ||||
| Curves *curves = static_cast<Curves *>(ob->data); | Curves *curves = static_cast<Curves *>(ob->data); | ||||
| CurvesBatchCache &cache = curves_batch_cache_get(*curves); | CurvesBatchCache &cache = curves_batch_cache_get(*curves); | ||||
| if (DRW_batch_requested(cache.edit_points, GPU_PRIM_POINTS)) { | if (DRW_batch_requested(cache.edit_points, GPU_PRIM_POINTS)) { | ||||
| DRW_vbo_request(cache.edit_points, &cache.curves_cache.proc_point_buf); | DRW_vbo_request(cache.edit_points, &cache.curves_cache.proc_point_buf); | ||||
| } | } | ||||
| if (DRW_vbo_requested(cache.curves_cache.proc_point_buf)) { | if (DRW_vbo_requested(cache.curves_cache.proc_point_buf)) { | ||||
| curves_batch_cache_ensure_procedural_pos(*curves, cache.curves_cache, nullptr); | curves_batch_cache_ensure_procedural_pos(*curves, cache.curves_cache, nullptr); | ||||
| } | } | ||||
| } | } | ||||