Commit Graph

142 Commits

Author SHA1 Message Date
Benjamin Otte
5e3cbff8d2 cssselector: Rework how we handle the bloom filter
Instead of foreaching through all the previous selectors every time we
bloom-filter, just bloom-filter the current element and return a special
value if that filter fails (FALSE). If that happens, don't try
filter-matching more nodes in the caller as we know it's an abort.
2020-01-29 04:20:47 +01:00
Benjamin Otte
c6158f1684 cssselector: Reorder functions
This just changes the order of functions in the source code in
preparation for the next commit.
2020-01-28 18:28:32 +01:00
Benjamin Otte
c7dca199ae selector: Rework iterating over subnodes
Instead of a foreach() function, introduce an iterator, so that the
caller can drive the iteration.

This allows doing stuff inbetween callbacks and avoids closures when
more than one data object should be passed.

As a side effect I even get a small, but noticeable performance
improvement in the 2-10% range depending on benchmark, I guess that's
because there's no function pointer passing going on anymore.
2020-01-28 04:32:15 +01:00
Benjamin Otte
495eaf31d4 css: Use the bloom filter for change matching
Instead of just doing radical change matching on the node itself, also
consider the parent nodes via the bloom filter.

This means a radical change is now also one where the parent
name/id/classes change, but since that's considered a radical change on
the parent already, those things are slow anyway.

Improves the benchmark times for CSS validation during backdrop
transitions in widget-factory from 45ms to 35ms on my machine.
2020-01-28 02:17:03 +01:00
Benjamin Otte
ccdc3ee406 selector: Make :not() selectors not radical
:not() selectors cannot be radical because the bloomfilter only knows if
a value is set in any of the nodes, but cannot determine the opposite
(if a value is not set in at least one node), but that would be required
for:not() selectors.
However, this is very unlikely to happen in the real world, so it's not
worth optimizing.

Unfortunately, change tracking could know this, so by excluding the
:not() selectors from radical changes, the change tracking will now pick
them up. If that turns out to be a performance problem, we need to add a
special category for radical not filters, so change tracking and bloom
filters can deal with them.

The testcase demonstrating the problem in widget-factory has been
extrated and added.
2020-01-28 02:17:03 +01:00
Benjamin Otte
170130f1d9 css: Add fast-path for parent selector matching
Add a fast path for parent selector matching that uses a bloom filter to
quickly discard selectors that can't possibly match.

Keep in mind that we match using a bloom filter, so we might
accidentally include too many selectors when hash/bucket collisions
occur.
That's not a correctness problem though, because we'll do a real check
afterwards.

The idea for this change is taken from browsers, in particular WebKit.
2020-01-28 02:17:03 +01:00
Benjamin Otte
2d5a8974b3 selector: Hash differently
This will be relevant for a bloom filter. And bloom filters want 12bit
hashes, so we try to produce hash values < 4096.
2020-01-28 02:17:03 +01:00
Benjamin Otte
146b921246 cssnode: Convert name + id from interned string to GQuark
The reason for this is simply that I want to get hash functions that
have their values close together, so they can fit in a smaller range
(the goal here is 12 bits). By using GQuark, we get consecutive numbers
starting with 1 (and applications have <1000 quarks usually), whereas
interned strings can be all over the place.

As a side effect we also save 64 bytes per declaration.
2020-01-28 02:17:03 +01:00
Benjamin Otte
8b93ea9238 css: Get rid of GtkCssMatcher 2020-01-28 02:17:02 +01:00
Benjamin Otte
c2d69643a8 css: Move utility function
The function was not selector-specific, so putting it with all the other
utility functions makes more sense.

Also use the utility function in the node declaration printing.
2020-01-28 02:17:02 +01:00
Matthias Clasen
5b6b4f5075 Revert "css: Print out relative costs of selectors"
This reverts commit 5dcce0c0bd.

I forgot to ifdef a few things in here, so lets take this out
again.
2020-01-24 11:50:40 -05:00
Matthias Clasen
5dcce0c0bd css: Print out relative costs of selectors
Count how often each tree node is visited, and print the number
at the end. This gives a good indication what selectors are costly
and should be avoided. #ifdefed out.
2020-01-24 09:09:08 -05:00
Benjamin Otte
2a5a52dd4b selector: Add GtkSelectorCategory
This will make it easier to write more complex matching algorithms.
2020-01-21 16:59:37 +01:00
Matthias Clasen
7e2e92a87e cssselector: Inline a few things 2020-01-19 15:56:54 -05:00
Matthias Clasen
95f00c6071 css: Redo the pseudoclass selectors
There is no need to duplicate the classes, we can make
do with a single class for all the states.
2020-01-18 23:06:25 -05:00
Matthias Clasen
a463dccd81 Refine the selector tree printing
Also show which tree nodes have exact matches.
2020-01-18 14:32:55 -05:00
Matthias Clasen
b4a9cf2bfb Remove no longer needed code
We no longer use superset or any matchers to find changes.
2020-01-17 23:47:34 -05:00
Matthias Clasen
2a919a4d4f Go back to the tree for computing change 2020-01-17 23:47:34 -05:00
Matthias Clasen
b2775d9bdd Redo the way we compute change
Instead of expecting a superset matcher, call
gtk_css_selector_match_for_change while walking the tree with the
original matcher. This fixes the handling of :not while determining
changes.
2020-01-17 23:47:34 -05:00
Matthias Clasen
7d72703d54 Revert "Remove no longer used code"
This reverts commit 105acfe908.
2020-01-17 23:47:34 -05:00
Matthias Clasen
93b5b487ae cssmatcher: Change get_state to has_state
This matches all the other vfuncs, and it gets us
out of keeping several big state flag enumerations
in sync.

Update all callers.
2020-01-16 19:24:43 -05:00
Matthias Clasen
105acfe908 Remove no longer used code
We no longer consult the selector tree to find changes,
so this code is no longer needed.
2020-01-16 17:24:34 -05:00
Matthias Clasen
192a24fa1f css: Track selected state separately
Like the previous change, this reduces the number of
css nodes reacting to parent-state changes. The remaining
parent-state cases here are due to :link.

Before (numbers from widget-factory with Adwaita):
2247 nodes
class 612
name 2246
id 2
first-child 148
last-child 156
state 2245
hover 562
disabled 859
backdrop 1080
sibling-name 63
sibling-disabled 51
parent-class 586
parent-name 788
parent-id 2
parent-first-child 78
parent-last-child 78
parent-state 236
parent-hover 5
parent-disabled 91
parent-backdrop 4

After:
2247 nodes
class 612
name 2246
id 2
first-child 148
last-child 156
state 2245
hover 562
disabled 859
backdrop 1080
selected 579
sibling-name 63
sibling-disabled 51
parent-class 586
parent-name 788
parent-id 2
parent-first-child 78
parent-last-child 78
parent-state 115
parent-hover 5
parent-disabled 91
parent-backdrop 4
parent-selected 144
2020-01-16 11:26:46 -05:00
Matthias Clasen
2426b9e23a css: Track backdrop state separately
Like the previous change, this reduces the number of
css nodes reacting to parent-state changes.

Before (numbers from widget-factory with Adwaita):
2247 nodes
class 612
name 2246
id 2
first-child 148
last-child 156
state 2247
hover 562
disabled 859
sibling-name 63
sibling-disabled 51
parent-class 586
parent-name 788
parent-id 2
parent-first-child 78
parent-last-child 78
parent-state 236
parent-hover 5
parent-disabled 91

After:
2247 nodes
class 612
name 2246
id 2
first-child 148
last-child 156
state 2245
hover 562
disabled 859
backdrop 1080
sibling-name 63
sibling-disabled 51
parent-class 586
parent-name 788
parent-id 2
parent-first-child 78
parent-last-child 78
parent-state 236
parent-hover 5
parent-disabled 91
parent-backdrop 4
2020-01-16 11:25:04 -05:00
Matthias Clasen
64848aebf4 css: Track disabled state separately
Significantly reduces the number of nodes that react to
parent-state changes.

Before (numbers from widget-factory with Adwaita):
2247 nodes
class 612
name 2246
id 2
first-child 148
last-child 156
state 2247
hover 2247
sibling-name 63
sibling-state 51
parent-class 586
parent-name 788
parent-id 2
parent-first-child 78
parent-last-child 78
parent-state 2226
parent-hover 5

After:
2247 nodes
class 612
name 2246
id 2
first-child 148
last-child 156
state 2247
hover 562
disabled 859
sibling-name 63
sibling-disabled 51
parent-class 586
parent-name 788
parent-id 2
parent-first-child 78
parent-last-child 78
parent-state 236
parent-hover 5
parent-disabled 91
2020-01-16 11:23:25 -05:00
Matthias Clasen
fcceac6d11 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.
2020-01-16 11:17:48 -05:00
Benjamin Otte
292371932b css: Handle invalid :not() selectors
We weren't correctly ending the ( ) block when encountering an error.

Testcases added.

Fixes #2281
2019-12-03 18:12:25 +01:00
Timm Bäder
d8df197489 cssprovider: Don't lookup on empty css providers
This should not have a huge performance impact, but debugging is easier
if we don't lookup in empty css providers.
2019-09-09 17:36:24 +02:00
Дилян Палаузов
6ded38de2b Minor typos in the Documentation (a/an) 2019-08-25 12:52:46 +00:00
Benjamin Otte
e1cd996617 selector: Inlcude : sign when reporting errors 2019-04-12 19:34:28 +02:00
Benjamin Otte
e0a01ba174 css: Redo for new parser
This commit is still way too big, but I couldn't make it smaller.

It transitions the old CSS parser to the new parser. CSS parsing is now
tokenized, everything else is probably still buggy.
2019-04-12 19:34:28 +02:00
Benjamin Otte
7f99c1e588 cssparser: Split integer gettig into has/consume functions
We can't try to get an integer because ultimately integer getters
support the same shenanigans that numbers and percentages do with calc()
and whatnot.
2019-04-12 19:34:28 +02:00
Benjamin Otte
dce8c11b07 cssparser: Drop _gtk_css_parser_has_prefix()
Replace it with has_ident/has_function. The old function is a typical
string matching API, not a tokenizing one.
2019-04-12 19:34:28 +02:00
Benjamin Otte
7ccec19501 parser: Get rid of _gtk_css_parser_is_eof()
Use gtk_css_parser_has_token() instead.
2019-04-12 19:34:28 +02:00
Benjamin Otte
684b6459f1 cssparser: Get rid of _gtk_css_parser_begins_with()
Replace it with calls to gtk_css_parser_has_token().
2019-04-12 19:34:28 +02:00
Matthias Clasen
a8531605db Some more interning
This avoids more strdups at startup.
2017-11-18 08:18:11 -05:00
Matthias Clasen
4209c1762d Support the new state in CSS selectors
Make :focus(visible) match the new state.
2017-10-25 17:59:00 -04:00
Benjamin Otte
8549e62d85 Add default return values to switch statements
We are using g_assert_not_reached() without doing anything, assuming it
aborts the program. In release builds however, it is ignored.
2017-10-24 18:21:03 +02:00
Matthias Clasen
d3198536a4 Drop support for deprecated pseudo-classes
We no longer have any of those.
2017-09-17 17:04:16 -04:00
Daniel Boles
79bbd4aca5 cssselector: Ensure we do not index out of bounds
This would only happen if the last element was deprecated, but it should
be avoided anyway.

CID 1388852 (#1 of 1): Out-of-bounds read (OVERRUN)
12. overrun-local: Overrunning array pseudo_classes of 16 32-byte
elements at element index 16 (byte offset 512) using index i + 1U (which
evaluates to 16).
2017-08-01 20:17:02 +01:00
Timm Bäder
b52966a318 cssselector: Stop parsing deprecated selectors 2017-03-02 15:16:08 +01:00
Daniel Boles
a1239a9a6a CssSelector: Fix warning for bad pseudo-class name
It was "Missing name of pseudo-class", but the real problem is exactly
the opposite: we /have/ been given a name, but it is not a valid one.
Change it to "Invalid name of pseudo-class" to minimise confusion.
2017-02-18 21:01:38 +00:00
Benjamin Otte
9b9b475f0a API: stylecontext: Remove regions 2016-10-16 18:17:21 +02:00
Benjamin Otte
35c96c2c1f Add braces to appease gcc
-ftrack-macro-expansion=0 doesn't like if statements without braces when
evaluating indentation levels.
2016-08-25 23:02:27 +02:00
Matthias Clasen
6108c646c5 cssselector: Don't invoke undefined behavior
Avoid undefined behavior in the calculation of some
hash values. Found by gcc's undefined behavior sanitizer.
2016-02-26 15:52:19 -05:00
Benjamin Otte
d48d3b359c cssselector: Remove type references
We don't use types anymore.
2016-02-05 23:47:48 +01:00
Benjamin Otte
e8fca5bbbe cssmatcher: Remove type argument from name matcher
We no longer use types when matching names.
2016-02-05 23:43:05 +01:00
Matthias Clasen
33bb1af277 css: Privately export a function to get pseudoclass names
This function centralizes the mapping for widget states
to pseudoclass names in one place, for easier maintenance.
2016-01-24 10:59:46 -05:00
Matthias Clasen
eb09bee492 css: Deprecate :sorted pseudo class
This was used with regions in GtkTreeView, and is not used
anymore, so deprecate it.
2015-12-27 18:37:19 -05:00
Matthias Clasen
f3069d7e94 css: Redo the pseudo class deprecation warnings
Putting the deprecated class behind the official variant does
not work for the case of :focus and :focused - we were matching
:focus and leave a dangling 'ed'. So, put the deprecated classes
before the official variant, and explicitly mark them as deprecated.
2015-12-27 17:32:11 -05:00