Browse Source

Optimize handing of properties in cases of full updates

Avoid looping through changed properties and checking invididual propeties in case we know it's a full update
Victor Luchitz 13 years ago
parent
commit
a147bff0ad
2 changed files with 60 additions and 33 deletions
  1. 30 14
      Source/Core/Element.cpp
  2. 30 19
      Source/Core/ElementStyle.cpp

+ 30 - 14
Source/Core/Element.cpp

@@ -1348,22 +1348,31 @@ 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;
+
 	// Force a relayout if any of the changed properties require it.
 	// Force a relayout if any of the changed properties require it.
-	for (PropertyNameList::const_iterator i = changed_properties.begin(); i != changed_properties.end(); ++i)
+	if (all_dirty)
+	{
+		DirtyLayout();
+	}
+	else
 	{
 	{
-		const PropertyDefinition* property_definition = StyleSheetSpecification::GetProperty(*i);
-		if (property_definition)
+		for (PropertyNameList::const_iterator i = changed_properties.begin(); i != changed_properties.end(); ++i)
 		{
 		{
-			if (property_definition->IsLayoutForced())
+			const PropertyDefinition* property_definition = StyleSheetSpecification::GetProperty(*i);
+			if (property_definition)
 			{
 			{
-				DirtyLayout();
-				break;
+				if (property_definition->IsLayoutForced())
+				{
+					DirtyLayout();
+					break;
+				}
 			}
 			}
 		}
 		}
 	}
 	}
 
 
 	// Update the visibility.
 	// Update the visibility.
-	if (changed_properties.find(VISIBILITY) != changed_properties.end() ||
+	if (all_dirty || changed_properties.find(VISIBILITY) != changed_properties.end() ||
 		changed_properties.find(DISPLAY) != changed_properties.end())
 		changed_properties.find(DISPLAY) != changed_properties.end())
 	{
 	{
 		bool new_visibility = GetProperty< int >(VISIBILITY) == VISIBILITY_VISIBLE &&
 		bool new_visibility = GetProperty< int >(VISIBILITY) == VISIBILITY_VISIBLE &&
@@ -1377,7 +1386,8 @@ void Element::OnPropertyChange(const PropertyNameList& changed_properties)
 				parent->DirtyStackingContext();
 				parent->DirtyStackingContext();
 		}
 		}
 
 
-		if (changed_properties.find(DISPLAY) != changed_properties.end())
+		if (all_dirty || 
+			changed_properties.find(DISPLAY) != changed_properties.end())
 		{
 		{
 			if (parent != NULL)
 			if (parent != NULL)
 				parent->DirtyStructure();
 				parent->DirtyStructure();
@@ -1385,7 +1395,8 @@ void Element::OnPropertyChange(const PropertyNameList& changed_properties)
 	}
 	}
 
 
 	// Update the position.
 	// Update the position.
-	if (changed_properties.find(LEFT) != changed_properties.end() ||
+	if (all_dirty ||
+		changed_properties.find(LEFT) != changed_properties.end() ||
 		changed_properties.find(RIGHT) != changed_properties.end() ||
 		changed_properties.find(RIGHT) != changed_properties.end() ||
 		changed_properties.find(TOP) != changed_properties.end() ||
 		changed_properties.find(TOP) != changed_properties.end() ||
 		changed_properties.find(BOTTOM) != changed_properties.end())
 		changed_properties.find(BOTTOM) != changed_properties.end())
@@ -1395,7 +1406,8 @@ void Element::OnPropertyChange(const PropertyNameList& changed_properties)
 	}
 	}
 
 
 	// Update the z-index.
 	// Update the z-index.
-	if (changed_properties.find(Z_INDEX) != changed_properties.end())
+	if (all_dirty || 
+		changed_properties.find(Z_INDEX) != changed_properties.end())
 	{
 	{
 		const Property* z_index_property = GetProperty(Z_INDEX);
 		const Property* z_index_property = GetProperty(Z_INDEX);
 
 
@@ -1449,11 +1461,13 @@ void Element::OnPropertyChange(const PropertyNameList& changed_properties)
 	}
 	}
 
 
 	// Dirty the background if it's changed.
 	// Dirty the background if it's changed.
-	if (changed_properties.find(BACKGROUND_COLOR) != changed_properties.end())
+	if (all_dirty ||
+		changed_properties.find(BACKGROUND_COLOR) != changed_properties.end())
 		background->DirtyBackground();
 		background->DirtyBackground();
 
 
 	// Dirty the border if it's changed.
 	// Dirty the border if it's changed.
-	if (changed_properties.find(BORDER_TOP_WIDTH) != changed_properties.end() ||
+	if (all_dirty || 
+		changed_properties.find(BORDER_TOP_WIDTH) != changed_properties.end() ||
 		changed_properties.find(BORDER_RIGHT_WIDTH) != changed_properties.end() ||
 		changed_properties.find(BORDER_RIGHT_WIDTH) != changed_properties.end() ||
 		changed_properties.find(BORDER_BOTTOM_WIDTH) != changed_properties.end() ||
 		changed_properties.find(BORDER_BOTTOM_WIDTH) != changed_properties.end() ||
 		changed_properties.find(BORDER_LEFT_WIDTH) != changed_properties.end() ||
 		changed_properties.find(BORDER_LEFT_WIDTH) != changed_properties.end() ||
@@ -1464,7 +1478,8 @@ void Element::OnPropertyChange(const PropertyNameList& changed_properties)
 		border->DirtyBorder();
 		border->DirtyBorder();
 
 
 	// Fetch a new font face if it has been changed.
 	// Fetch a new font face if it has been changed.
-	if (changed_properties.find(FONT_FAMILY) != changed_properties.end() ||
+	if (all_dirty ||
+		changed_properties.find(FONT_FAMILY) != changed_properties.end() ||
 		changed_properties.find(FONT_CHARSET) != changed_properties.end() ||
 		changed_properties.find(FONT_CHARSET) != changed_properties.end() ||
 		changed_properties.find(FONT_WEIGHT) != changed_properties.end() ||
 		changed_properties.find(FONT_WEIGHT) != changed_properties.end() ||
 		changed_properties.find(FONT_STYLE) != changed_properties.end() ||
 		changed_properties.find(FONT_STYLE) != changed_properties.end() ||
@@ -1503,7 +1518,8 @@ void Element::OnPropertyChange(const PropertyNameList& changed_properties)
 	}
 	}
 	
 	
 	// Check for clipping state changes
 	// Check for clipping state changes
-	if (changed_properties.find(CLIP) != changed_properties.end() ||
+	if (all_dirty ||
+		changed_properties.find(CLIP) != changed_properties.end() ||
 		changed_properties.find(OVERFLOW_X) != changed_properties.end() ||
 		changed_properties.find(OVERFLOW_X) != changed_properties.end() ||
 		changed_properties.find(OVERFLOW_Y) != changed_properties.end())
 		changed_properties.find(OVERFLOW_Y) != changed_properties.end())
 	{
 	{

+ 30 - 19
Source/Core/ElementStyle.cpp

@@ -469,27 +469,24 @@ void ElementStyle::DirtyChildDefinitions()
 // Dirties every property.
 // Dirties every property.
 void ElementStyle::DirtyProperties()
 void ElementStyle::DirtyProperties()
 {
 {
-	PropertyNameList properties;
-	StyleSheetSpecification::GetRegisteredProperties(properties);
-
+	const PropertyNameList &properties = StyleSheetSpecification::GetRegisteredProperties();
 	DirtyProperties(properties);
 	DirtyProperties(properties);
 }
 }
 
 
 // Dirties em-relative properties.
 // Dirties em-relative properties.
 void ElementStyle::DirtyEmProperties()
 void ElementStyle::DirtyEmProperties()
 {
 {
-	PropertyNameList properties;
-	StyleSheetSpecification::GetRegisteredProperties(properties);
+	const PropertyNameList &properties = StyleSheetSpecification::GetRegisteredProperties();
 
 
 	// Check if any of these are currently em-relative. If so, dirty them.
 	// Check if any of these are currently em-relative. If so, dirty them.
 	PropertyNameList em_properties;
 	PropertyNameList em_properties;
-	for (PropertyNameList::iterator list_iterator = properties.begin(); list_iterator != properties.end(); ++list_iterator)
+	for (PropertyNameList::const_iterator list_iterator = properties.begin(); list_iterator != properties.end(); ++list_iterator)
 	{
 	{
 		// Skip font-size; this is relative to our parent's em, not ours.
 		// Skip font-size; this is relative to our parent's em, not ours.
 		if (*list_iterator == FONT_SIZE)
 		if (*list_iterator == FONT_SIZE)
 			continue;
 			continue;
 
 
-		// Get this element from this element. If this is em-relative, then add it to the list to
+		// Get this property from this element. If this is em-relative, then add it to the list to
 		// dirty.
 		// dirty.
 		if (element->GetProperty(*list_iterator)->unit == Property::EM)
 		if (element->GetProperty(*list_iterator)->unit == Property::EM)
 			em_properties.insert(*list_iterator);
 			em_properties.insert(*list_iterator);
@@ -536,21 +533,35 @@ void ElementStyle::DirtyProperties(const PropertyNameList& properties)
 	if (properties.empty())
 	if (properties.empty())
 		return;
 		return;
 
 
-	PropertyNameList inherited_properties;
-	for (PropertyNameList::const_iterator i = properties.begin(); i != properties.end(); ++i)
-	{
-		// If this property is an inherited property, then push it into the list to be passed onto our children.
-		const PropertyDefinition* property = StyleSheetSpecification::GetProperty(*i);
-		if (property != NULL &&
-			property->IsInherited())
-			inherited_properties.insert(*i);
-	}
+	bool all_inherited_dirty = 
+		StyleSheetSpecification::GetRegisteredProperties() == properties ||
+		StyleSheetSpecification::GetRegisteredInheritedProperties() == properties;
 
 
-	// Pass the list of those properties that are inherited onto our children.
-	if (!inherited_properties.empty())
+	if (all_inherited_dirty)
 	{
 	{
+		const PropertyNameList &all_inherited_properties = StyleSheetSpecification::GetRegisteredInheritedProperties();
 		for (int i = 0; i < element->GetNumChildren(true); i++)
 		for (int i = 0; i < element->GetNumChildren(true); i++)
-			element->GetChild(i)->GetStyle()->DirtyInheritedProperties(inherited_properties);
+			element->GetChild(i)->GetStyle()->DirtyInheritedProperties(all_inherited_properties);
+	}
+	else
+	{
+		PropertyNameList inherited_properties;
+
+		for (PropertyNameList::const_iterator i = properties.begin(); i != properties.end(); ++i)
+		{
+			// If this property is an inherited property, then push it into the list to be passed onto our children.
+			const PropertyDefinition* property = StyleSheetSpecification::GetProperty(*i);
+			if (property != NULL &&
+				property->IsInherited())
+				inherited_properties.insert(*i);
+		}
+
+		// Pass the list of those properties that are inherited onto our children.
+		if (!inherited_properties.empty())
+		{
+			for (int i = 0; i < element->GetNumChildren(true); i++)
+				element->GetChild(i)->GetStyle()->DirtyInheritedProperties(inherited_properties);
+		}
 	}
 	}
 
 
 	// And send the event.
 	// And send the event.