Browse Source

Performance improvements, avoid unnecessary allocations

Michael Ragazzon 6 years ago
parent
commit
b82e1123a0

+ 1 - 1
Include/Rocket/Core/Element.h

@@ -688,7 +688,7 @@ private:
 
 
 	void DirtyStructure();
 	void DirtyStructure();
 
 
-	void DirtyTransformState(bool perspective_changed, bool transform_changed, bool parent_pv_changed);
+	void DirtyTransformState(bool perspective_changed, bool transform_changed, bool parent_transform_changed);
 	void UpdateTransformState();
 	void UpdateTransformState();
 
 
 	// Start an animation, replacing any existing animations of the same property name. If start_value is null, the element's current value is used.
 	// Start an animation, replacing any existing animations of the same property name. If start_value is null, the element's current value is used.

+ 1 - 1
Include/Rocket/Core/Property.h

@@ -74,7 +74,7 @@ public:
 		PC = 1 << 16,				// number suffixed by 'pc'; fetch as < float >
 		PC = 1 << 16,				// number suffixed by 'pc'; fetch as < float >
 		PPI_UNIT = INCH | CM | MM | PT | PC,
 		PPI_UNIT = INCH | CM | MM | PT | PC,
 
 
-		TRANSFORM = 1 << 17,			// transform; fetch as < TransformRef >
+		TRANSFORM = 1 << 17,			// transform; fetch as < TransformRef >, may be empty
 		TRANSITION = 1 << 18,           // transition; fetch as < TransitionList >
 		TRANSITION = 1 << 18,           // transition; fetch as < TransitionList >
 		ANIMATION = 1 << 19,            // animation; fetch as < AnimationList >
 		ANIMATION = 1 << 19,            // animation; fetch as < AnimationList >
 
 

+ 0 - 4
Source/Core/Context.cpp

@@ -120,10 +120,6 @@ void Context::SetDimensions(const Vector2i& _dimensions)
 				document->DirtyLayout();
 				document->DirtyLayout();
 				document->UpdatePosition();
 				document->UpdatePosition();
 			}
 			}
-
-			// We need to rebuild our projection matrices when the
-			// dimensions change.
-			root->GetChild(i)->DirtyTransformState(true, false, false);
 		}
 		}
 		
 		
 		clip_dimensions = dimensions;
 		clip_dimensions = dimensions;

+ 27 - 17
Source/Core/Element.cpp

@@ -1738,7 +1738,12 @@ void Element::OnAttributeChange(const AttributeNameList& changed_attributes)
 // Called when properties on the element are changed.
 // Called when properties on the element are changed.
 void Element::OnPropertyChange(const PropertyNameList& changed_properties)
 void Element::OnPropertyChange(const PropertyNameList& changed_properties)
 {
 {
-	bool all_dirty = StyleSheetSpecification::GetRegisteredProperties() == changed_properties;
+	bool all_dirty = false;
+	{
+		auto& registered_properties = StyleSheetSpecification::GetRegisteredProperties();
+		if (&registered_properties == &changed_properties || registered_properties == changed_properties)
+			all_dirty = true;
+	}
 
 
 	if (!IsLayoutDirty())
 	if (!IsLayoutDirty())
 	{
 	{
@@ -2547,6 +2552,7 @@ void Element::DirtyTransformState(bool perspective_changed, bool transform_chang
 	}
 	}
 }
 }
 
 
+
 void Element::UpdateTransformState()
 void Element::UpdateTransformState()
 {
 {
 	if (!(transform_state_perspective_dirty || transform_state_transform_dirty || transform_state_parent_transform_dirty))
 	if (!(transform_state_perspective_dirty || transform_state_transform_dirty || transform_state_parent_transform_dirty))
@@ -2554,12 +2560,6 @@ void Element::UpdateTransformState()
 		return;
 		return;
 	}
 	}
 
 
-	if (!transform_state.get())
-	{
-		transform_state.reset(new TransformState());
-	}
-
-
 	if(transform_state_perspective_dirty || transform_state_transform_dirty)
 	if(transform_state_perspective_dirty || transform_state_transform_dirty)
 	{
 	{
 		Context *context = GetContext();
 		Context *context = GetContext();
@@ -2641,10 +2641,12 @@ void Element::UpdateTransformState()
 
 
 			if (have_perspective && context)
 			if (have_perspective && context)
 			{
 			{
+				if (!transform_state)
+					transform_state = std::make_unique<TransformState>();
 				perspective_value.view_size = context->GetDimensions();
 				perspective_value.view_size = context->GetDimensions();
 				transform_state->SetPerspective(&perspective_value);
 				transform_state->SetPerspective(&perspective_value);
 			}
 			}
-			else
+			else if (transform_state)
 			{
 			{
 				transform_state->SetPerspective(0);
 				transform_state->SetPerspective(0);
 			}
 			}
@@ -2661,10 +2663,10 @@ void Element::UpdateTransformState()
 			Matrix4f transform_value = Matrix4f::Identity();
 			Matrix4f transform_value = Matrix4f::Identity();
 			Vector3f transform_origin(pos.x + size.x * 0.5f, pos.y + size.y * 0.5f, 0);
 			Vector3f transform_origin(pos.x + size.x * 0.5f, pos.y + size.y * 0.5f, 0);
 
 
-			const Property *transform = GetTransform();
-			if (transform && (transform->unit != Property::KEYWORD || transform->value.Get< int >() != TRANSFORM_NONE))
+			const Property *transform_property = GetTransform();
+			TransformRef transforms;
+			if (transform_property && (transforms = transform_property->value.Get<TransformRef>()))
 			{
 			{
-				TransformRef transforms = transform->value.Get< TransformRef >();
 				int n = transforms->GetNumPrimitives();
 				int n = transforms->GetNumPrimitives();
 				for (int i = 0; i < n; ++i)
 				for (int i = 0; i < n; ++i)
 				{
 				{
@@ -2745,10 +2747,12 @@ void Element::UpdateTransformState()
 
 
 			if (have_local_perspective && context)
 			if (have_local_perspective && context)
 			{
 			{
+				if (!transform_state)
+					transform_state = std::make_unique<TransformState>();
 				local_perspective.view_size = context->GetDimensions();
 				local_perspective.view_size = context->GetDimensions();
 				transform_state->SetLocalPerspective(&local_perspective);
 				transform_state->SetLocalPerspective(&local_perspective);
 			}
 			}
-			else
+			else if(transform_state)
 			{
 			{
 				transform_state->SetLocalPerspective(0);
 				transform_state->SetLocalPerspective(0);
 			}
 			}
@@ -2765,9 +2769,15 @@ void Element::UpdateTransformState()
 					Matrix4f::Translate(transform_origin)
 					Matrix4f::Translate(transform_origin)
 					* transform_value
 					* transform_value
 					* Matrix4f::Translate(-transform_origin);
 					* Matrix4f::Translate(-transform_origin);
-			}
 
 
-			transform_state->SetTransform(have_transform ? &transform_value : 0);
+				if (!transform_state)
+					transform_state = std::make_unique<TransformState>();
+				transform_state->SetTransform(&transform_value);
+			}
+			else if (transform_state)
+			{
+				transform_state->SetTransform(0);
+			}
 
 
 			transform_state_transform_dirty = false;
 			transform_state_transform_dirty = false;
 		}
 		}
@@ -2782,7 +2792,7 @@ void Element::UpdateTransformState()
 			parent->UpdateTransformState();
 			parent->UpdateTransformState();
 		}
 		}
 
 
-		if (transform_state.get())
+		if (transform_state)
 		{
 		{
 			// Store the parent's new full transform as our parent transform
 			// Store the parent's new full transform as our parent transform
 			Element *node = 0;
 			Element *node = 0;
@@ -2808,9 +2818,9 @@ void Element::UpdateTransformState()
 	// transform, we don't need to keep the large TransformState object
 	// transform, we don't need to keep the large TransformState object
 	// around. GetEffectiveTransformState() will then recursively visit
 	// around. GetEffectiveTransformState() will then recursively visit
 	// parents in order to find a non-trivial TransformState.
 	// parents in order to find a non-trivial TransformState.
-	if (transform_state.get() && !transform_state->GetLocalPerspective(0) && !transform_state->GetPerspective(0) && !transform_state->GetTransform(0))
+	if (transform_state && !transform_state->GetLocalPerspective(0) && !transform_state->GetPerspective(0) && !transform_state->GetTransform(0))
 	{
 	{
-		transform_state.reset(0);
+		transform_state.reset();
 	}
 	}
 }
 }
 
 

+ 36 - 9
Source/Core/ElementAnimation.cpp

@@ -332,8 +332,14 @@ static bool PrepareTransforms(std::vector<AnimationKey>& keys, Element& element,
 			continue;
 			continue;
 		}
 		}
 
 
-		auto& t0 = keys[i - 1].property.value.Get<TransformRef>();
-		auto& t1 = keys[i].property.value.Get<TransformRef>();
+		auto& prop0 = keys[i - 1].property;
+		auto& prop1 = keys[i].property;
+
+		if(prop0.unit != Property::TRANSFORM || prop1.unit != Property::TRANSFORM)
+			return false;
+
+		auto& t0 = prop0.value.Get<TransformRef>();
+		auto& t1 = prop1.value.Get<TransformRef>();
 
 
 		auto result = PrepareTransformPair(*t0, *t1, element);
 		auto result = PrepareTransformPair(*t0, *t1, element);
 
 
@@ -360,25 +366,47 @@ static bool PrepareTransforms(std::vector<AnimationKey>& keys, Element& element,
 
 
 ElementAnimation::ElementAnimation(const String& property_name, const Property& current_value, double start_world_time, float duration, int num_iterations, bool alternate_direction, bool is_transition)
 ElementAnimation::ElementAnimation(const String& property_name, const Property& current_value, double start_world_time, float duration, int num_iterations, bool alternate_direction, bool is_transition)
 	: property_name(property_name), duration(duration), num_iterations(num_iterations), alternate_direction(alternate_direction),
 	: property_name(property_name), duration(duration), num_iterations(num_iterations), alternate_direction(alternate_direction),
-	keys({ AnimationKey{0.0f, current_value, Tween{}} }),
 	last_update_world_time(start_world_time), time_since_iteration_start(0.0f), current_iteration(0), reverse_direction(false), animation_complete(false), is_transition(is_transition)
 	last_update_world_time(start_world_time), time_since_iteration_start(0.0f), current_iteration(0), reverse_direction(false), animation_complete(false), is_transition(is_transition)
 {
 {
 	ROCKET_ASSERT(current_value.definition);
 	ROCKET_ASSERT(current_value.definition);
+	InternalAddKey(AnimationKey{ 0.0f, current_value, Tween{} });
 }
 }
 
 
-
-bool ElementAnimation::AddKey(float target_time, const Property & in_property, Element& element, Tween tween, bool extend_duration)
+bool ElementAnimation::InternalAddKey(AnimationKey key)
 {
 {
 	int valid_properties = (Property::NUMBER_LENGTH_PERCENT | Property::ANGLE | Property::COLOUR | Property::TRANSFORM);
 	int valid_properties = (Property::NUMBER_LENGTH_PERCENT | Property::ANGLE | Property::COLOUR | Property::TRANSFORM);
 
 
-	if (!(in_property.unit & valid_properties))
+	if (!(key.property.unit & valid_properties))
+	{
+		Log::Message(Log::LT_WARNING, "Property '%s' is not a valid target for interpolation.", key.property.ToString().CString());
+		return false;
+	}
+
+	if (key.property.unit == Property::TRANSFORM)
+	{
+		if (!key.property.value.Get<TransformRef>())
+			key.property.value.Reset(TransformRef(new Transform));
+	}
+
+	keys.push_back(key);
+
+	return true;
+}
+
+
+bool ElementAnimation::AddKey(float target_time, const Property & in_property, Element& element, Tween tween, bool extend_duration)
+{
+	if (keys.empty())
+	{
+		Log::Message(Log::LT_WARNING, "Element animation was not initialized properly, can't add key.");
+		return false;
+	}
+	if (!InternalAddKey(AnimationKey{ target_time, in_property, tween }))
 	{
 	{
-		Log::Message(Log::LT_WARNING, "Property '%s' is not a valid target for interpolation.", in_property.ToString().CString());
 		return false;
 		return false;
 	}
 	}
 
 
 	bool result = true;
 	bool result = true;
-	keys.push_back({ target_time, in_property, tween });
 	auto& property = keys.back().property;
 	auto& property = keys.back().property;
 
 
 	if (property.unit == Property::TRANSFORM)
 	if (property.unit == Property::TRANSFORM)
@@ -412,7 +440,6 @@ bool ElementAnimation::AddKey(float target_time, const Property & in_property, E
 
 
 float ElementAnimation::GetInterpolationFactorAndKeys(int* out_key0, int* out_key1) const
 float ElementAnimation::GetInterpolationFactorAndKeys(int* out_key0, int* out_key1) const
 {
 {
-
 	float t = time_since_iteration_start;
 	float t = time_since_iteration_start;
 
 
 	if (reverse_direction)
 	if (reverse_direction)

+ 2 - 0
Source/Core/ElementAnimation.h

@@ -63,6 +63,8 @@ private:
 	bool animation_complete;
 	bool animation_complete;
 	bool is_transition;
 	bool is_transition;
 
 
+	bool InternalAddKey(AnimationKey key);
+
 	float GetInterpolationFactorAndKeys(int* out_key0, int* out_key1) const;
 	float GetInterpolationFactorAndKeys(int* out_key0, int* out_key1) const;
 public:
 public:
 	ElementAnimation() {}
 	ElementAnimation() {}

+ 1 - 1
Source/Core/PropertyParserTransform.cpp

@@ -48,7 +48,7 @@ bool PropertyParserTransform::ParseValue(Property& property, const String& value
 {
 {
 	if(value == NONE)
 	if(value == NONE)
 	{
 	{
-		property.value = Variant(TransformRef(new Transform));
+		property.value = Variant(TransformRef());
 		property.unit = Property::TRANSFORM;
 		property.unit = Property::TRANSFORM;
 		return true;
 		return true;
 	}
 	}