Reduced connection data block size.

Previously we allocated a block for each connection. However when an output is reused by multiple connections this lead to duplicates. It also obfuscated which block is actually being used.
This commit is contained in:
Martin Felis 2024-04-08 21:52:03 +02:00
parent 9f9ac60f9c
commit 2d5337ed1d
2 changed files with 59 additions and 25 deletions

View File

@ -496,10 +496,12 @@ void AnimGraphResource::CreateBlendTreeInstance(
result.m_name = m_name;
NodeSocketDataOffsetMap node_offset_map;
CreateBlendTreeRuntimeNodeInstances(result);
PrepareBlendTreeIOData(result);
PrepareBlendTreeIOData(result, node_offset_map);
SetRuntimeNodeProperties(result);
CreateBlendTreeConnectionInstances(result);
CreateBlendTreeConnectionInstances(result, node_offset_map);
result.UpdateOrderedNodes();
result.ResetNodeStates();
@ -537,7 +539,8 @@ void AnimGraphResource::CreateBlendTreeRuntimeNodeInstances(
}
void AnimGraphResource::PrepareBlendTreeIOData(
AnimGraphBlendTree& instance) const {
AnimGraphBlendTree& instance,
NodeSocketDataOffsetMap& node_offset_map) const {
instance.m_node_descriptor =
AnimNodeDescriptorFactory("BlendTree", instance.m_nodes[0]);
@ -590,15 +593,23 @@ void AnimGraphResource::PrepareBlendTreeIOData(
output_block_offset += sizeof(void*);
}
// connections: make source and target sockets point to the same address in the connection data storage.
// TODO: instead of every connection, only create data blocks for the source sockets and make sure every source socket gets allocated once.
//
// connecton data storage
//
size_t connection_data_storage_size = 0;
for (const auto& connection : m_blend_tree_resource.m_connections) {
const AnimNodeResource* source_node =
m_blend_tree_resource.m_nodes[connection.source_node_index];
Socket* source_socket = source_node->m_socket_accessor->GetOutputSocket(
connection.source_socket_name.c_str());
connection_data_storage_size += source_socket->m_type_size;
NodeSocketPair source_socket_pair{source_node, source_socket->m_name};
if (node_offset_map.find(source_socket_pair) == node_offset_map.end()) {
node_offset_map.insert(
{source_socket_pair, connection_data_storage_size});
connection_data_storage_size += source_socket->m_type_size;
}
}
if (connection_data_storage_size > 0) {
@ -608,7 +619,8 @@ void AnimGraphResource::PrepareBlendTreeIOData(
}
void AnimGraphResource::CreateBlendTreeConnectionInstances(
AnimGraphBlendTree& instance) const {
AnimGraphBlendTree& instance,
NodeSocketDataOffsetMap& node_offset_map) const {
std::vector<NodeDescriptorBase*> instance_node_descriptors(
m_blend_tree_resource.m_nodes.size(),
nullptr);
@ -630,7 +642,6 @@ void AnimGraphResource::CreateBlendTreeConnectionInstances(
instance_node_descriptors[1]->m_outputs =
instance.m_node_descriptor->m_outputs;
size_t connection_data_offset = 0;
for (const auto& connection : m_blend_tree_resource.m_connections) {
NodeDescriptorBase* source_node_descriptor =
instance_node_descriptors[connection.source_node_index];
@ -729,32 +740,48 @@ void AnimGraphResource::CreateBlendTreeConnectionInstances(
instance_connection.m_target_socket_name = target_socket->m_name;
instance_connection.m_socket = *target_socket;
size_t socket_data_offset = 0;
if (connection.source_node_index == 1) {
instance_connection.m_socket = *target_socket;
} else if (connection.target_node_index == 0) {
instance_connection.m_socket = *source_socket;
} else {
if (connection.target_node_index == 0) {
instance_connection.m_socket = *source_socket;
}
NodeSocketPair node_socket_pair{
m_blend_tree_resource.m_nodes[connection.source_node_index],
source_socket->m_name};
NodeSocketDataOffsetMap::const_iterator socket_data_offset_iter =
node_offset_map.find(node_socket_pair);
if (socket_data_offset_iter != node_offset_map.end()) {
socket_data_offset = socket_data_offset_iter->second;
} else {
std::cerr << "Error: could not find data offset for node '"
<< source_node->m_name << "' and socket '"
<< source_socket->m_name << "'." << std::endl;
assert(false);
abort();
}
*target_socket->m_reference.ptr_ptr =
&instance.m_connection_data_storage[connection_data_offset];
&instance.m_connection_data_storage[socket_data_offset];
*source_socket->m_reference.ptr_ptr =
&instance.m_connection_data_storage[connection_data_offset];
&instance.m_connection_data_storage[socket_data_offset];
if (source_socket->m_type == SocketType::SocketTypeAnimation) {
instance.m_animdata_blocks.push_back(
(AnimData*)(&instance
.m_connection_data_storage[socket_data_offset]));
}
}
instance.m_node_input_connections[connection.target_node_index].push_back(
instance_connection);
instance.m_node_output_connections[connection.source_node_index].push_back(
instance_connection);
*instance_connection.m_socket.m_reference.ptr_ptr =
&instance.m_connection_data_storage[connection_data_offset];
if (source_socket->m_type == SocketType::SocketTypeAnimation) {
instance.m_animdata_blocks.push_back(
(AnimData*)(&instance
.m_connection_data_storage[connection_data_offset]));
}
connection_data_offset += source_socket->m_type_size;
}
//

View File

@ -161,6 +161,9 @@ struct AnimGraphResource : AnimNodeResource {
std::string m_graph_type_name;
BlendTreeResource m_blend_tree_resource;
typedef std::pair<const AnimNodeResource*, std::string> NodeSocketPair;
typedef std::map<NodeSocketPair, int> NodeSocketDataOffsetMap;
StateMachineResource m_state_machine_resource;
void Clear() { m_blend_tree_resource.Reset(); }
@ -174,8 +177,12 @@ struct AnimGraphResource : AnimNodeResource {
// BlendTree
bool SaveBlendTreeResourceToFile(const char* filename) const;
void CreateBlendTreeRuntimeNodeInstances(AnimGraphBlendTree& result) const;
void PrepareBlendTreeIOData(AnimGraphBlendTree& instance) const;
void CreateBlendTreeConnectionInstances(AnimGraphBlendTree& instance) const;
void PrepareBlendTreeIOData(
AnimGraphBlendTree& instance,
NodeSocketDataOffsetMap& node_offset_map) const;
void CreateBlendTreeConnectionInstances(
AnimGraphBlendTree& instance,
NodeSocketDataOffsetMap& node_offset_map) const;
void SetRuntimeNodeProperties(AnimGraphBlendTree& result) const;
bool SaveStateMachineResourceToFile(const char* filename) const;