css: Track hover state changes separately

The idea is that this reduce the amount of frequently
changing state that css nodes are sensitive to.

This is going to reduce the amount of style recomputation.
This commit is contained in:
Matthias Clasen 2020-01-15 15:10:06 -05:00
parent e8eb1df29f
commit fcceac6d11
5 changed files with 108 additions and 60 deletions

View File

@ -529,7 +529,7 @@ _gtk_css_matcher_superset_init (GtkCssMatcher *matcher,
GtkCssChange relevant)
{
g_return_if_fail (subset != NULL);
g_return_if_fail ((relevant & ~(GTK_CSS_CHANGE_CLASS | GTK_CSS_CHANGE_NAME | GTK_CSS_CHANGE_POSITION | GTK_CSS_CHANGE_STATE)) == 0);
g_return_if_fail ((relevant & ~(GTK_CSS_CHANGE_CLASS | GTK_CSS_CHANGE_NAME | GTK_CSS_CHANGE_POSITION | GTK_CSS_CHANGE_STATE | GTK_CSS_CHANGE_HOVER)) == 0);
matcher->superset.klass = &GTK_CSS_MATCHER_SUPERSET;
matcher->superset.subset = subset;

View File

@ -1138,9 +1138,21 @@ void
gtk_css_node_set_state (GtkCssNode *cssnode,
GtkStateFlags state_flags)
{
GtkStateFlags old_state;
old_state = gtk_css_node_declaration_get_state (cssnode->decl);
if (gtk_css_node_declaration_set_state (&cssnode->decl, state_flags))
{
gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_STATE);
GtkStateFlags states = old_state ^ state_flags;
GtkCssChange change = 0;
if (states & GTK_STATE_FLAG_PRELIGHT)
change |= GTK_CSS_CHANGE_HOVER;
if (states & ~GTK_STATE_FLAG_PRELIGHT)
change |= GTK_CSS_CHANGE_STATE;
gtk_css_node_invalidate (cssnode, change);
g_object_notify_by_pspec (G_OBJECT (cssnode), cssnode_properties[PROP_STATE]);
}
}

View File

@ -728,6 +728,12 @@ comp_pseudoclass_state (const GtkCssSelector *a,
return a->state.state - b->state.state;
}
#define GTK_CSS_CHANGE_PSEUDOCLASS_HOVER GTK_CSS_CHANGE_HOVER
DEFINE_SIMPLE_SELECTOR(pseudoclass_hover, PSEUDOCLASS_HOVER, print_pseudoclass_state,
match_pseudoclass_state, hash_pseudoclass_state, comp_pseudoclass_state,
FALSE, TRUE, FALSE)
#undef GTK_CSS_CHANGE_PSEUDOCLASS_HOVER
#define GTK_CSS_CHANGE_PSEUDOCLASS_STATE GTK_CSS_CHANGE_STATE
DEFINE_SIMPLE_SELECTOR(pseudoclass_state, PSEUDOCLASS_STATE, print_pseudoclass_state,
match_pseudoclass_state, hash_pseudoclass_state, comp_pseudoclass_state,
@ -1288,9 +1294,14 @@ gtk_css_selector_parse_selector_pseudo_class (GtkCssParser *parser,
{
if (pseudo_classes[i].state_flag)
{
selector = gtk_css_selector_new (negate ? &GTK_CSS_SELECTOR_NOT_PSEUDOCLASS_STATE
: &GTK_CSS_SELECTOR_PSEUDOCLASS_STATE,
selector);
if (pseudo_classes[i].state_flag == GTK_STATE_FLAG_PRELIGHT)
selector = gtk_css_selector_new (negate ? &GTK_CSS_SELECTOR_NOT_PSEUDOCLASS_HOVER
: &GTK_CSS_SELECTOR_PSEUDOCLASS_HOVER,
selector);
else
selector = gtk_css_selector_new (negate ? &GTK_CSS_SELECTOR_NOT_PSEUDOCLASS_STATE
: &GTK_CSS_SELECTOR_PSEUDOCLASS_STATE,
selector);
selector->state.state = pseudo_classes[i].state_flag;
}
else

View File

@ -74,19 +74,17 @@ _gtk_css_change_for_sibling (GtkCssChange match)
| GTK_CSS_CHANGE_LAST_CHILD \
| GTK_CSS_CHANGE_NTH_CHILD \
| GTK_CSS_CHANGE_NTH_LAST_CHILD \
| GTK_CSS_CHANGE_STATE )
| GTK_CSS_CHANGE_STATE \
| GTK_CSS_CHANGE_HOVER)
#define KEEP_STATES ( ~(BASE_STATES|GTK_CSS_CHANGE_SOURCE|GTK_CSS_CHANGE_PARENT_STYLE) \
| GTK_CSS_CHANGE_NTH_CHILD \
| GTK_CSS_CHANGE_NTH_LAST_CHILD)
#define SIBLING_SHIFT 8
return (match & KEEP_STATES) | ((match & BASE_STATES) << SIBLING_SHIFT);
return (match & KEEP_STATES) | ((match & BASE_STATES) << GTK_CSS_CHANGE_SIBLING_SHIFT);
#undef BASE_STATES
#undef KEEP_STATES
#undef SIBLING_SHIFT
}
GtkCssChange
@ -100,6 +98,7 @@ _gtk_css_change_for_child (GtkCssChange match)
| GTK_CSS_CHANGE_NTH_CHILD \
| GTK_CSS_CHANGE_NTH_LAST_CHILD \
| GTK_CSS_CHANGE_STATE \
| GTK_CSS_CHANGE_HOVER \
| GTK_CSS_CHANGE_SIBLING_CLASS \
| GTK_CSS_CHANGE_SIBLING_NAME \
| GTK_CSS_CHANGE_SIBLING_ID \
@ -107,14 +106,15 @@ _gtk_css_change_for_child (GtkCssChange match)
| GTK_CSS_CHANGE_SIBLING_LAST_CHILD \
| GTK_CSS_CHANGE_SIBLING_NTH_CHILD \
| GTK_CSS_CHANGE_SIBLING_NTH_LAST_CHILD \
| GTK_CSS_CHANGE_SIBLING_STATE )
| GTK_CSS_CHANGE_SIBLING_STATE \
| GTK_CSS_CHANGE_SIBLING_HOVER)
#define PARENT_SHIFT 16
#define KEEP_STATES (~(BASE_STATES|GTK_CSS_CHANGE_SOURCE|GTK_CSS_CHANGE_PARENT_STYLE))
return (match & ~(BASE_STATES|GTK_CSS_CHANGE_SOURCE|GTK_CSS_CHANGE_PARENT_STYLE)) | ((match & BASE_STATES) << PARENT_SHIFT);
return (match & KEEP_STATES) | ((match & BASE_STATES) << GTK_CSS_CHANGE_PARENT_SHIFT);
#undef BASE_STATES
#undef PARENT_SHIFT
#undef KEEP_STATES
}
void
@ -133,6 +133,8 @@ gtk_css_change_print (GtkCssChange change,
{ GTK_CSS_CHANGE_NTH_CHILD, "nth-child" },
{ GTK_CSS_CHANGE_NTH_LAST_CHILD, "nth-last-child" },
{ GTK_CSS_CHANGE_STATE, "state" },
{ GTK_CSS_CHANGE_HOVER, "hover" },
{ GTK_CSS_CHANGE_SIBLING_CLASS, "sibling-class" },
{ GTK_CSS_CHANGE_SIBLING_NAME, "sibling-name" },
{ GTK_CSS_CHANGE_SIBLING_ID, "sibling-id" },
@ -141,6 +143,8 @@ gtk_css_change_print (GtkCssChange change,
{ GTK_CSS_CHANGE_SIBLING_NTH_CHILD, "sibling-nth-child" },
{ GTK_CSS_CHANGE_SIBLING_NTH_LAST_CHILD, "sibling-nth-last-child" },
{ GTK_CSS_CHANGE_SIBLING_STATE, "sibling-state" },
{ GTK_CSS_CHANGE_SIBLING_HOVER, "sibling-hover" },
{ GTK_CSS_CHANGE_PARENT_CLASS, "parent-class" },
{ GTK_CSS_CHANGE_PARENT_NAME, "parent-name" },
{ GTK_CSS_CHANGE_PARENT_ID, "parent-id" },
@ -149,6 +153,8 @@ gtk_css_change_print (GtkCssChange change,
{ GTK_CSS_CHANGE_PARENT_NTH_CHILD, "parent-nth-child" },
{ GTK_CSS_CHANGE_PARENT_NTH_LAST_CHILD, "parent-nth-last-child" },
{ GTK_CSS_CHANGE_PARENT_STATE, "parent-state" },
{ GTK_CSS_CHANGE_PARENT_HOVER, "parent-hover" },
{ GTK_CSS_CHANGE_PARENT_SIBLING_CLASS, "parent-sibling-" },
{ GTK_CSS_CHANGE_PARENT_SIBLING_NAME, "parent-sibling-name" },
{ GTK_CSS_CHANGE_PARENT_SIBLING_ID, "parent-sibling-id" },
@ -157,6 +163,8 @@ gtk_css_change_print (GtkCssChange change,
{ GTK_CSS_CHANGE_PARENT_SIBLING_NTH_CHILD, "parent-sibling-nth-child" },
{ GTK_CSS_CHANGE_PARENT_SIBLING_NTH_LAST_CHILD, "parent-sibling-nth-last-child" },
{ GTK_CSS_CHANGE_PARENT_SIBLING_STATE, "parent-sibling-state" },
{ GTK_CSS_CHANGE_PARENT_SIBLING_HOVER, "parent-sibling-hover" },
{ GTK_CSS_CHANGE_SOURCE, "source" },
{ GTK_CSS_CHANGE_PARENT_STYLE, "parent-style" },
{ GTK_CSS_CHANGE_TIMESTAMP, "timestamp" },

View File

@ -36,61 +36,78 @@ typedef struct _GtkCssStyle GtkCssStyle;
#define GTK_CSS_CHANGE_NTH_CHILD (1ULL << 5)
#define GTK_CSS_CHANGE_NTH_LAST_CHILD (1ULL << 6)
#define GTK_CSS_CHANGE_STATE (1ULL << 7)
#define GTK_CSS_CHANGE_SIBLING_CLASS (1ULL << 8)
#define GTK_CSS_CHANGE_SIBLING_NAME (1ULL << 9)
#define GTK_CSS_CHANGE_SIBLING_ID (1ULL << 10)
#define GTK_CSS_CHANGE_SIBLING_FIRST_CHILD (1ULL << 11)
#define GTK_CSS_CHANGE_SIBLING_LAST_CHILD (1ULL << 12)
#define GTK_CSS_CHANGE_SIBLING_NTH_CHILD (1ULL << 13)
#define GTK_CSS_CHANGE_SIBLING_NTH_LAST_CHILD (1ULL << 14)
#define GTK_CSS_CHANGE_SIBLING_STATE (1ULL << 15)
#define GTK_CSS_CHANGE_PARENT_CLASS (1ULL << 16)
#define GTK_CSS_CHANGE_PARENT_NAME (1ULL << 17)
#define GTK_CSS_CHANGE_PARENT_ID (1ULL << 18)
#define GTK_CSS_CHANGE_PARENT_FIRST_CHILD (1ULL << 19)
#define GTK_CSS_CHANGE_PARENT_LAST_CHILD (1ULL << 20)
#define GTK_CSS_CHANGE_PARENT_NTH_CHILD (1ULL << 21)
#define GTK_CSS_CHANGE_PARENT_NTH_LAST_CHILD (1ULL << 22)
#define GTK_CSS_CHANGE_PARENT_STATE (1ULL << 23)
#define GTK_CSS_CHANGE_PARENT_SIBLING_CLASS (1ULL << 24)
#define GTK_CSS_CHANGE_PARENT_SIBLING_ID (1ULL << 25)
#define GTK_CSS_CHANGE_PARENT_SIBLING_NAME (1ULL << 26)
#define GTK_CSS_CHANGE_PARENT_SIBLING_FIRST_CHILD (1ULL << 27)
#define GTK_CSS_CHANGE_PARENT_SIBLING_LAST_CHILD (1ULL << 28)
#define GTK_CSS_CHANGE_PARENT_SIBLING_NTH_CHILD (1ULL << 29)
#define GTK_CSS_CHANGE_PARENT_SIBLING_NTH_LAST_CHILD (1ULL << 30)
#define GTK_CSS_CHANGE_PARENT_SIBLING_STATE (1ULL << 31)
#define GTK_CSS_CHANGE_HOVER (1ULL << 8)
#define GTK_CSS_CHANGE_SIBLING_SHIFT 9
#define GTK_CSS_CHANGE_SIBLING_CLASS (1ULL << 9)
#define GTK_CSS_CHANGE_SIBLING_NAME (1ULL << 10)
#define GTK_CSS_CHANGE_SIBLING_ID (1ULL << 11)
#define GTK_CSS_CHANGE_SIBLING_FIRST_CHILD (1ULL << 12)
#define GTK_CSS_CHANGE_SIBLING_LAST_CHILD (1ULL << 13)
#define GTK_CSS_CHANGE_SIBLING_NTH_CHILD (1ULL << 14)
#define GTK_CSS_CHANGE_SIBLING_NTH_LAST_CHILD (1ULL << 15)
#define GTK_CSS_CHANGE_SIBLING_STATE (1ULL << 16)
#define GTK_CSS_CHANGE_SIBLING_HOVER (1ULL << 17)
#define GTK_CSS_CHANGE_PARENT_SHIFT (GTK_CSS_CHANGE_SIBLING_SHIFT + GTK_CSS_CHANGE_SIBLING_SHIFT)
#define GTK_CSS_CHANGE_PARENT_CLASS (1ULL << 18)
#define GTK_CSS_CHANGE_PARENT_NAME (1ULL << 19)
#define GTK_CSS_CHANGE_PARENT_ID (1ULL << 20)
#define GTK_CSS_CHANGE_PARENT_FIRST_CHILD (1ULL << 21)
#define GTK_CSS_CHANGE_PARENT_LAST_CHILD (1ULL << 22)
#define GTK_CSS_CHANGE_PARENT_NTH_CHILD (1ULL << 23)
#define GTK_CSS_CHANGE_PARENT_NTH_LAST_CHILD (1ULL << 24)
#define GTK_CSS_CHANGE_PARENT_STATE (1ULL << 25)
#define GTK_CSS_CHANGE_PARENT_HOVER (1ULL << 26)
#define GTK_CSS_CHANGE_PARENT_SIBLING_SHIFT (GTK_CSS_CHANGE_PARENT_SHIFT + GTK_CSS_CHANGE_SIBLING_SHIFT)
#define GTK_CSS_CHANGE_PARENT_SIBLING_CLASS (1ULL << 27)
#define GTK_CSS_CHANGE_PARENT_SIBLING_ID (1ULL << 28)
#define GTK_CSS_CHANGE_PARENT_SIBLING_NAME (1ULL << 29)
#define GTK_CSS_CHANGE_PARENT_SIBLING_FIRST_CHILD (1ULL << 30)
#define GTK_CSS_CHANGE_PARENT_SIBLING_LAST_CHILD (1ULL << 31)
#define GTK_CSS_CHANGE_PARENT_SIBLING_NTH_CHILD (1ULL << 32)
#define GTK_CSS_CHANGE_PARENT_SIBLING_NTH_LAST_CHILD (1ULL << 33)
#define GTK_CSS_CHANGE_PARENT_SIBLING_STATE (1ULL << 34)
#define GTK_CSS_CHANGE_PARENT_SIBLING_HOVER (1ULL << 35)
/* add more */
#define GTK_CSS_CHANGE_SOURCE (1ULL << 32)
#define GTK_CSS_CHANGE_PARENT_STYLE (1ULL << 33)
#define GTK_CSS_CHANGE_TIMESTAMP (1ULL << 34)
#define GTK_CSS_CHANGE_ANIMATIONS (1ULL << 35)
#define GTK_CSS_CHANGE_SOURCE (1ULL << 36)
#define GTK_CSS_CHANGE_PARENT_STYLE (1ULL << 37)
#define GTK_CSS_CHANGE_TIMESTAMP (1ULL << 38)
#define GTK_CSS_CHANGE_ANIMATIONS (1ULL << 39)
#define GTK_CSS_CHANGE_RESERVED_BIT (1ULL << 62) /* Used internally in gtkcssselector.c */
typedef guint64 GtkCssChange;
#define GTK_CSS_CHANGE_POSITION (GTK_CSS_CHANGE_FIRST_CHILD | GTK_CSS_CHANGE_LAST_CHILD | \
GTK_CSS_CHANGE_NTH_CHILD | GTK_CSS_CHANGE_NTH_LAST_CHILD)
#define GTK_CSS_CHANGE_SIBLING_POSITION (GTK_CSS_CHANGE_SIBLING_FIRST_CHILD | GTK_CSS_CHANGE_SIBLING_LAST_CHILD | \
GTK_CSS_CHANGE_SIBLING_NTH_CHILD | GTK_CSS_CHANGE_SIBLING_NTH_LAST_CHILD)
#define GTK_CSS_CHANGE_PARENT_POSITION (GTK_CSS_CHANGE_PARENT_FIRST_CHILD | GTK_CSS_CHANGE_PARENT_LAST_CHILD | \
GTK_CSS_CHANGE_PARENT_NTH_CHILD | GTK_CSS_CHANGE_PARENT_NTH_LAST_CHILD)
#define GTK_CSS_CHANGE_PARENT_SIBLING_POSITION (GTK_CSS_CHANGE_PARENT_SIBLING_FIRST_CHILD | GTK_CSS_CHANGE_PARENT_SIBLING_LAST_CHILD | \
GTK_CSS_CHANGE_PARENT_SIBLING_NTH_CHILD | GTK_CSS_CHANGE_PARENT_SIBLING_NTH_LAST_CHILD)
#define GTK_CSS_CHANGE_POSITION (GTK_CSS_CHANGE_FIRST_CHILD | \
GTK_CSS_CHANGE_LAST_CHILD | \
GTK_CSS_CHANGE_NTH_CHILD | \
GTK_CSS_CHANGE_NTH_LAST_CHILD)
#define GTK_CSS_CHANGE_SIBLING_POSITION (GTK_CSS_CHANGE_POSITION << GTK_CSS_CHANGE_SIBLING_SHIFT)
#define GTK_CSS_CHANGE_ANY_SELF (GTK_CSS_CHANGE_CLASS | \
GTK_CSS_CHANGE_NAME | \
GTK_CSS_CHANGE_ID | \
GTK_CSS_CHANGE_POSITION | \
GTK_CSS_CHANGE_STATE | \
GTK_CSS_CHANGE_HOVER)
#define GTK_CSS_CHANGE_ANY_SIBLING (GTK_CSS_CHANGE_ANY_SELF << GTK_CSS_CHANGE_SIBLING_SHIFT)
#define GTK_CSS_CHANGE_ANY_PARENT (GTK_CSS_CHANGE_ANY_SELF << GTK_CSS_CHANGE_PARENT_SHIFT)
#define GTK_CSS_CHANGE_ANY_PARENT_SIBLING (GTK_CSS_CHANGE_ANY_SELF << GTK_CSS_CHANGE_PARENT_SIBLING_SHIFT)
#define GTK_CSS_CHANGE_ANY ((1 << 19) - 1)
#define GTK_CSS_CHANGE_ANY_SELF (GTK_CSS_CHANGE_CLASS | GTK_CSS_CHANGE_NAME | GTK_CSS_CHANGE_ID | GTK_CSS_CHANGE_POSITION | GTK_CSS_CHANGE_STATE)
#define GTK_CSS_CHANGE_ANY_SIBLING (GTK_CSS_CHANGE_SIBLING_CLASS | GTK_CSS_CHANGE_SIBLING_NAME | \
GTK_CSS_CHANGE_SIBLING_ID | \
GTK_CSS_CHANGE_SIBLING_POSITION | GTK_CSS_CHANGE_SIBLING_STATE)
#define GTK_CSS_CHANGE_ANY_PARENT (GTK_CSS_CHANGE_PARENT_CLASS | GTK_CSS_CHANGE_PARENT_SIBLING_CLASS | \
GTK_CSS_CHANGE_PARENT_NAME | GTK_CSS_CHANGE_PARENT_SIBLING_NAME | \
GTK_CSS_CHANGE_PARENT_ID | GTK_CSS_CHANGE_PARENT_SIBLING_ID | \
GTK_CSS_CHANGE_PARENT_POSITION | GTK_CSS_CHANGE_PARENT_SIBLING_POSITION | \
GTK_CSS_CHANGE_PARENT_STATE | GTK_CSS_CHANGE_PARENT_SIBLING_STATE)
#define GTK_CSS_CHANGE_ANY (GTK_CSS_CHANGE_ANY_SELF | \
GTK_CSS_CHANGE_ANY_SIBLING | \
GTK_CSS_CHANGE_ANY_PARENT | \
GTK_CSS_CHANGE_ANY_PARENT_SIBLING | \
GTK_CSS_CHANGE_SOURCE | \
GTK_CSS_CHANGE_PARENT_STYLE | \
GTK_CSS_CHANGE_TIMESTAMP | \
GTK_CSS_CHANGE_ANIMATIONS)
/*
* GtkCssAffects: