Commit graph

115 commits

Author SHA1 Message Date
Oriol Brufau
7ae2c754c5
compositing_traits: Properly cache cumulative node transforms (#39402)
`cumulative_node_transform()` returns the cached value if present, and
otherwise calls `cumulative_node_transform_inner()` to compute it.
However, `cumulative_node_transform_inner()` was just calling itself
recursively to compute the ancestor transforms, ignoring the cache.

Therefore, this patch makes `cumulative_node_transform_inner()` call
`cumulative_node_transform()` for the parent. This requires merging
`AncestorStickyInfo` into `ScrollTreeNodeTransformationCache` in order
to cache that data too.

Testing: Not needed, no behavior change

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
2025-09-22 09:52:47 +00:00
Alex Touchet
8590c4edcf
Use more workspace dependencies (#39404)
I noticed that there are various dependencies that are listed
independently even though they are already in the Servo workspace. Is
there any issue with converting these to workspace dependencies?

Testing: No tests for Cargo.toml edits.

Signed-off-by: Alex Touchet <26315797+atouchet@users.noreply.github.com>
2025-09-20 06:01:59 +00:00
Alex Touchet
5a0332f57e
Cargo.toml cleanup (#39403)
Cargo.toml cleanups. Mostly ordering fixes.

Testing: No tests for Cargo.toml edits.

---------

Signed-off-by: Alex Touchet <26315797+atouchet@users.noreply.github.com>
2025-09-20 03:09:37 +00:00
Oriol Brufau
2c3d580ef1
layout: Take sticky offsets into account for offset queries (#39385)
`offsetLeft` and `offsetTop` were ignoring that sticky positioned boxes
can be shifted out of their normal position.

Testing: Various test improvements.

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
2025-09-19 14:20:15 +00:00
Oriol Brufau
1473121fe5
layout: Avoid ClipId, ExternalScrollId and ScrollTreeNodeId references (#39372)
Changes function signatures to accept `ClipId`, `ExternalScrollId` and
`ScrollTreeNodeId` instead of `&ClipId`, `&ExternalScrollId` and
`&ScrollTreeNodeId`. This avoids several `&` and `*`.

Testing: not needed, no behavior change.

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
2025-09-18 23:34:49 +00:00
Jonathan Schwender
eaca68472b
migrate GenerateImageKey reply to generic channel (#39347)
Testing: No functional changes. Covered by existing wpt tests.
Part of https://github.com/servo/servo/issues/38912

Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
2025-09-17 11:30:26 +00:00
Narfinger
84465e7768
Removed FnvHash and transformed the rest to FxHashmap (#39233)
This should be the final PR for the Hash Function series that is
trivial.

Of note: I decided to transform `HashMapTracedValues<Atom,..>` to use
FxBuildHasher. This is likely not going to improve performance as Atom's
already have a unique u32 that is used as the Hash but it safes a few
bytes for the RandomState that is normally in the HashMap.

Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>

Testing: Hash function changes should not change functionality, we
slightly decrease the size and unit tests still work.

Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>
2025-09-10 13:34:54 +00:00
Sam
1f0f079203
webgpu: Simplify presentation and handle cleared in script (#38717)
There are many important changes here:

- Generalize the presentation buffer into standalone staging buffers
that hold their own state. This allow them to be used by getImage.
- Move all clear handling to the ScriptThread and send the configuration
on each request present/getimage, thus avoiding any recreate/clearing
messages. This means that we prepare staging buffers lazily, on the
first request.

Try run for this change:
https://github.com/sagudev/servo/actions/runs/17341982368
Testing: This is covered by existing WebGPU CTS tests. There are some
bad expectations updates, but they are also on main (presumably from
last update the rendering work) although I think CTS is actually wrong
(see https://github.com/gpuweb/cts/issues/4440).
Fixes: #36820
Fixes: #37705
Fixes: #33368 (we now keep reference alive in hashmap)

---------

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
2025-09-09 03:35:12 +00:00
Narfinger
5c7ea4bdee
constellation: Use FnvHashMap for hashmaps that use ids as keys (#39106)
FNV is faster for hashing less than 16 bytes of data and the
cryptographic properties of the default HashMap are not needed for the
various ids.

Testing: This does not change functionality.

Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>
2025-09-03 18:15:19 +00:00
Jonathan Schwender
e5f9d81058
Add generic cross process callback mechanism (#38973)
One commonly encountered mechanism in servo is using ipc channels
together with the router, to register a custom callback to run in the
current process, when receiving a reply.
The new `GenericCallback` abstracts over this, and allows executing an
arbitrary callback in the process of the `GenericCallback` creator. In
multiprocess mode, this internally uses ipc channels and follows the
existing pattern.
In single process mode, we execute the callback directly, which avoids
one call to the router.
Executing the callback still incurs synchronization, since we need to
support cloning the abstraction, and the callback closure may be
`FnMut`. Future work could provide more optimized abstractions for
callbacks that don't have these requirements.

This PR allows applying #38782 again, which was previously reverted in
#38940 due to the lack of custom callback support.

See also the module documentation in `generic_channel/callback.rs`.

Testing: This PR adds unit tests. Also passes the manual testcase from
#38939

Part of #38912

---------

Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
Signed-off-by: Jonathan Schwender <55576758+jschwe@users.noreply.github.com>
Co-authored-by: Josh Matthews <josh@joshmatthews.net>
2025-08-30 16:58:49 +00:00
Sam
8beef6c21f
compositor: Allow canvas to upload rendered contents asynchronously (#37776)
Adds epoch to each WR image op command that is sent to compositor. The
renderer now has a `FrameDelayer` data structure that is responsible for
tracking when a frame is ready to be displayed. When asking canvases to
update their rendering, they are given an optional `Epoch` which denotes
the `Document`'s canvas epoch. When all image updates for that `Epoch`
are seen in the renderer, the frame can be displayed.

Testing: Existing WPT tests
Fixes: #35733

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
2025-08-29 10:04:41 +00:00
Jonathan Schwender
a5d890c13a
compositor: Preserve CompositorMsg deserialization errors (#38972)
Forward any deserialization errors to the receiver, instead of panicking
on the router thread. This change was previously part of #38782, which
got reverted, since generic channels don't support custom router
callbacks yet. Propagating the error is still something we want, and
landing this separately will reduce the diff of the PR that introduces
generic callbacks.

Testing: Should be covered by existing tests. Also manually tested
https://github.com/servo/servo/issues/38939

---------

Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
Signed-off-by: Jonathan Schwender <55576758+jschwe@users.noreply.github.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
2025-08-27 14:11:20 +00:00
Jonathan Schwender
33e934421e
compositor: Hide IpcSender as implementation detail (#38963)
The `CrossProcessCompositorApi` already provides methods for most
messages.
Remove the `sender()` method, and hide the IpcSender as an
implementation detail. This is a preparation for abstracting over the
internal IpcSender.

Testing: No functional changes

---------

Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
2025-08-27 09:42:01 +00:00
Jonathan Schwender
35f0dd352d
compositor: Port GenerateFontKeys result sender to generic channel (#38917)
Ports the channel returning the result of `GenerateFontKeys` to generic
channel

Testing: No functional changes - Covered by existing tests
Part of https://github.com/servo/servo/issues/38912

Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
2025-08-27 08:32:13 +00:00
Martin Robinson
e7a963cca0
script: Generate only a single frame during "update the rendering" (#38858)
Instead of generating a frame for every display list, which might be one
rendered frame per `<iframe>`, generate only a single frame per call to
"update the rendering." This should make rendering more efficient when
there are `<iframe>`s present and also open up optimizations for
non-display list frames.

Testing: This could potentially reduce flashing of content during
rendering
updates, but that is very difficult to test.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2025-08-26 16:09:10 +00:00
Mukilan Thiyagarajan
c75995ec87
Revert "GenericChannel: Migrate compositor channels to GenericChannel (#38782)" (#38940)
This reverts commit fb1c0a4c48.

Previously in `create_compositor_channel`, the [routing callback][1] was
setup so that a message received on the Compositor's IPC receiver will
be
forwarded to the local receiver using the `CompositorProxy` which also
takes care of waking up the event loop. In #38782, this was changed so
that the routing callbacks simply forwards the message directly without
going via the `CompositorProxy`. This breaks behaviours that rely on the
event loop being woken up on message sending, e.g. updating image frames
for animated gifs.

Since the GenericChannel API doesn't allow custom routing callbacks,
revert this change until we figure out a better solution.

[1]:
d2ccce6052/components/servo/lib.rs (L1114)

Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com>

Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com>
2025-08-26 14:16:58 +00:00
Jonathan Schwender
fb1c0a4c48
GenericChannel: Migrate compositor channels to GenericChannel (#38782)
Besides migrating the channel to GenericChannel, this PR adds
`routed_channel_with_local_sender()` to `generic_channel`. This is for
existing use-cases, where we want to provide both an IPC capable
GenericSender, as well as a crossbeam Sender, for efficient sending if
the sender is in the same process.

Testing: All of our channels should send / receive at least some
messages during WPT tests.

Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
2025-08-25 11:05:21 +00:00
Rahul Menon
9cd019403f
layout: Measure stacking context tree in layout thread memory report (#38762)
Measures the memory usage of the stacking context tree in the memory
report of the layout thread by adding `MallocSizeOf` to
`StackingContextTree` and all the types required for that. Also requires
adding `MallocSizeOf` to some webrender types.

Testing: Manually looked at about:memory
<img width="636" height="241" alt="image"
src="https://github.com/user-attachments/assets/6bf9d65a-0bf0-4a99-99b5-ddedba3269c1"
/>

Fixes: https://github.com/servo/servo/issues/38725

---------

Signed-off-by: Rahul Menon <menonrahul02@gmail.com>
2025-08-21 07:21:59 +00:00
webbeef
3225d19907
cargo: Bump rustc to 1.89 (#36818)
Update Rustc to 1.89.

Reviewable by commit.

Leftover work:
- #37330 
- #38777

---------

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
Co-authored-by: sagudev <16504129+sagudev@users.noreply.github.com>
2025-08-19 11:07:53 +00:00
Simon Wülker
7471ad7730
fonts: Implement CSS font-variation-settings property for FreeType platforms (#38642)
This change adds support for variable fonts via the
[`font-variation-settings`](https://developer.mozilla.org/en-US/docs/Web/CSS/font-variation-settings)
property.

There are three areas where we need to set the variation values:
* Webrender (`compositor.rs`), for drawing the glyphs
* Harfbuzz (`shaper.rs`), for most shaping tasks
* PlatformFont (`fonts/platform/`), for horizontal advances and kerning

For now, freetype is the only platform shaper that supports variable
fonts. I can't easily test the fonts with non-freetype shapers. Thats
why variable fonts are behind the `layout_variable_fonts_enabled` pref,
which is disabled by default.

<img width="1250" height="710" alt="image"
src="https://github.com/user-attachments/assets/1aee1407-f3a2-42f6-a106-af0443fcd588"
/>

<details><summary>HTML test file</summary>

```html
<style>
@font-face {
  font-family: "Amstelvar VF";
  src: url("https://mdn.github.io/shared-assets/fonts/variable-fonts/AmstelvarAlpha-VF.woff2")
    format("woff2-variations");
  font-weight: 300 900;
  font-stretch: 35% 100%;
  font-style: normal;
  font-display: swap;
}

p {
  font:
    1.2em "Amstelvar VF",
    Georgia,
    serif;
  font-size: 4rem;
  margin: 1rem;
  display: inline-block;
}

.p1 {
  font-variation-settings: "wght" 300;
}

.p2 {
  font-variation-settings: "wght" 625;
}

.p3 {
  font-variation-settings: "wght" 900;
}

</style>
<div>
  <p class="p1">Weight</p>
  <span>(font-variation-settings: "wght" 300)</span>
</div>
<div>
  <p class="p2">Weight</p>
  <span>(font-variation-settings: "wght" 625)</span>
</div>
<div>
  <p class="p3">Weight</p>
  <span>(font-variation-settings: "wght" 900)</span>
</div>
</div>
```
</details>



https://github.com/user-attachments/assets/9e21101a-796a-49fe-b82c-8999d8fa9ee1


Testing: Needs decision on whether we want to enable the pref in CI
Works towards https://github.com/servo/servo/issues/37236

Depends on https://github.com/servo/stylo/pull/230

---------

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
2025-08-18 16:30:14 +00:00
sagudev
85588fada0
compositing: Use webrender_api::ExternalImageSource instead of WebRenderImageSource (#38703)
There is no reason to roll our own type.

Motivation: I need `ExternalImageSource::Invalid`.

Testing: Covered by existing WPT tests, but it's just refactor

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
2025-08-15 19:39:07 +00:00
Oriol Brufau
4ff1e8dbd9
layout: Use FastTransform for hit testing (#38554)
`FastTransform` provides faster matrix operations when the involved
transforms are just translations.

Testing: Not needed (no change in behavior)

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
2025-08-11 16:23:17 +00:00
Martin Robinson
ad805e3110
compositor/layout: Rely on layout for fine-grained input event hit testing (#38480)
Before, the compositor was responsible for doing the hit testing during
input events within a page. This change moves that hit testing to
layout.  With this change, epoch mismatches are no longer a bit deal and
we can simply ignore them, as the Constellation and Script will take
care of ignoring hit tests against scroll nodes and browsing contexts
that no longer exist. This means that hit testing retry support can be
removed.

Add the concept of a Script `HitTest` that transforms the coarse-grained
renderer hit test into one that hit tests against the actual layout
items.

Testing: Currently we do not have good tests for verifying the behavior
of
input events, but WebDriver tests should cover this.
Fixes: This is part of #37932.
Fixes: #26608.
Fixes: #25282.
Fixes: #38090.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
Co-authored-by: kongbai1996 <1782765876@qq.com>
2025-08-07 08:38:43 +00:00
Martin Robinson
11844ca5af
layout: Add a layout hit test and use it for document.elementsFromPoint (#38463)
In #18933, hit testing was moved from layout to WebRender. This presents
some issues. For instance, the DOM can change at the same time that hit
test is happening. This can mean that hit test returns references to
defunct DOM nodes, introducing memory safety issues. Currently, Servo
will try to ensure that the epochs used for testing and those recorded
in the DOM match, but this is not very reliable and has led to code that
retries failed hit tests.

This change reintroduces (8 years later) a layout hit tester and turns
it on for `document.elementFromPoint` and `document.elementsFromPoint`.
The idea is that this hit tester will gradually replace the majority of
the WebRender hit testing happening in the renderer.

Testing: This shouldn't really change the behavior hit testing, but it
seems to improve one WPT test.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
Co-authored-by: kongbai1996 <1782765876@qq.com>
2025-08-05 09:48:21 +00:00
Euclid Ye
625d636b04
compositor: Add more doc for size of different RenderingContext implementation (#38399)
For more details, see
https://github.com/servo/servo/issues/38369#issuecomment-3138378527.

Fixes:
https://github.com/servo/servo/issues/38369#issuecomment-3138458772
Testing: Just adding docs.

Signed-off-by: Euclid Ye <euclid.ye@huawei.com>
2025-08-01 09:07:32 +00:00
Martin Robinson
5da55adfd3
layout: Account for sticky nodes in ScrollTree transforms and cache transforms (#38391)
When calculating the node to world transform for use in bounding box
queries, cache the values of the transform. In addition, when scroll
offsets change, ensure that the cached values are invalided properly.
This change necessitated the storage of children for each node in the
tree, so that we can walk both up and down the tree. The purpose of this
part of the change is to increase performance when doing multiple
queries and prepare the tree for hit testing.

In addition, this change also tries to take into account sticky offsets,
using the algorithm from WebRender to calculate sticky offsets. This is
also going to be important for hit testing.

Testing: Newly passing tests:
 - /css/css-position/position-sticky-dynamic-ancestor-001.html
 - /css/css-tables/tentative/position-sticky-container.html

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
2025-07-31 13:36:32 +00:00
Jo Steven Novaryo
900dd8d191
layout: Consider transform for bounding box queries (#37871)
The recent changes that cached the Scroll Tree present an opportunity to
calculate the queries that consider transform and scroll (dubbed as post
composite queries) accurately.

This PR propose a solution for this calculation by noting the lowest
scroll tree nodes that would affect a fragment. To do this, each
fragment would store a new attribute `spatial_tree_node` -- scroll tree
node id that we could use for the query. This referencing is considered
because the scroll tree node construction is managed by the fragment
itself. Therefore it would ease the managing the possibly stale
reference and future query cache invalidation considering the
development of incremental layout.

The bounding box query then could transform the bounding content rect of
a fragment using the computed current transformation matrix.

Fixes: https://github.com/servo/servo/issues/35768
Testing: Existing and new WPT

---------

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>
Signed-off-by: Jo Steven Novaryo <jo.steven.novaryo@huawei.com>
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
2025-07-30 08:13:54 +00:00
Martin Robinson
8d5faa9bf9
compositor: Request reflow when doing a page zooming (#38166)
Request a reflow when doing page zoom and only modify the scaling of the
WebView scene after the first root pipeline display list with the new
zoom is ready. In addition:

  - store zoom limits in `Scale` types
  - send `ViewportDetails` along with the display list so that we can
    detect when the root pipeline scale is ready.

Testing: This is quite hard to test as it requires verification that
contents are zoomed appropriately at the right time.
Fixes: #38091.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2025-07-29 10:04:37 +00:00
Euclid Ye
0e4b2bfef0
cargo: Remove unused dependency (#38239)
Remove unused `Cargo.toml` dependency to reduce binary size.

Testing: Can still compile in different platforms.

Signed-off-by: Euclid Ye <euclid.ye@huawei.com>
2025-07-23 13:32:50 +00:00
Euclid Ye
57fc569818
Remove Webdriver Server's access to Constellation (#38212)
`WebDriverCommandMsg::TakeScreenshot` was the last thing blocking us
from removing constellation access in webdriver server. Now we can
happily remove it.

Surprisingly, this reduces binary size by 185KB for release profile in
Windows. #37737 removes a net total of 300 lines, but only reduced 98KB.

Testing: No regression after testing.

Signed-off-by: Euclid Ye <euclid.ye@huawei.com>
2025-07-22 10:17:19 +00:00
Euclid Ye
d38ffb82b2
script: Get the screen metrics from the WebViewDelegate instead of via the compositor (#38020)
Similar to #37960, previously, `AvailHeight`, `AvailWidth`, `Height`,
`Width` ask compositor for screen metrics. This PR moves the request to
embedder.

This simplifies code, and reduces workload of compositor, which is
busier most of time.

Testing: No behaviour change. Updated some tests. `Width/Height` matches
other browsers.

---------

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
2025-07-12 16:07:39 +00:00
Euclid Ye
c5aeac3cea
script: Get the window rectangle from the WebViewDelegate instead of via the compositor (#37960)
Previously, `screenX`, `screenY`, `outerHeight`, `outerWidth`, `moveBy`,
`resizeBy` ask compositor for window rectangle, which then return
"inner" rectangle after consulting Embedder.

This PR 
1. removes `GetClientWindowRect` from compositor, and directly let
script ask embedder.
2. add `window_size` to `ScreenGeometry`
3. add a lot of docs to `ScreenGeometry`

Testing: `tests\wpt\mozilla\tests\mozilla\window_resizeTo.html` can now
pass for Headed Window.
Fixes: #37824

---------

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
2025-07-11 18:31:24 +00:00
Martin Robinson
0db02702e7
layout: When setting post-layout / renderer scroll offsets limit by scroll area (#37829)
Previously when scroll offsets were restored to a new scroll tree
post-layout or when receiving scroll offsets from the compositor, they
were not clamped to the available scroll area. This change fixes that.

Testing: This change fixes some WPT subtests.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2025-07-08 19:27:42 +00:00
batu_hoang
940eff9497
Move webdriver actions commands to servoshell (#37669)
Move webdriver actions commands to servoshell.

Testing: Test with webdriver enable in the CI
[Test result
1](https://github.com/longvatrong111/servo/actions/runs/15875355256)
[Test result
2](https://github.com/longvatrong111/servo/actions/runs/15875356595)
[Test result
3](https://github.com/longvatrong111/servo/actions/runs/15875361886)

Fixes: https://github.com/servo/servo/issues/37370

Signed-off-by: batu_hoang <longvatrong111@gmail.com>
2025-07-04 16:29:38 +00:00
Euclid Ye
70b0fb840e
embedder: Improve documentation for various places that talk about "available screen size" (#37879)
Testing: Just add comment. It turns out difficult to achieve, see
https://github.com/rust-windowing/winit/issues/2494.
Fixes: Nothing. Provide some guidance to #37878

---------

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
2025-07-04 16:05:01 +00:00
Narfinger
ca47cc2fa3
Add a basic caching mechanism for ImageKeys. (#37369)
This creates a new method in shared/compositing/lib to generate image
keys that are send over the webview. This does not immediately return
the keys but goes over the constellation to receive the keys from the
IOCompositor. To make this more efficient, we now cache the keys in
image_cache in a simple FIFO order. The old blocking method stays intact
for now but got renamed to make the blocking clear.
The blocking calls that are left are in:
- `components/canvas/canvas_data.rs`
- `components/script/dom/htmlmediaelement.rs`

Testing: WPT tests should cover this as this doesn't change any
functionality.
Fixes: Was mentioned in
https://github.com/servo/servo/issues/37161#issuecomment-2915750051 and
part of https://github.com/servo/servo/issues/37086

---------

Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>
Signed-off-by: gterzian <2792687+gterzian@users.noreply.github.com>
Co-authored-by: gterzian <2792687+gterzian@users.noreply.github.com>
2025-07-03 13:16:43 +00:00
Martin Robinson
89bfa26f00
libservo|compositor: Have scroll offset directionality match that of WebRender and the web (#37752)
Previously, our Servo-specific spatial tree scroll offsets were opposite
to
that of WebRender and also the web platform. This is due to the fact,
likely, that `winit` wheel directionality is also flipped. This change
has both the Servo spatial tree and the API take offsets that are
consistent with the web.

Any possible changes to the meaning of wheel directionality will be
handled in a followup change.

This is a breaking change to the Servo API.

Testing: This change updates unit tests.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
2025-07-03 13:04:06 +00:00
sagudev
4dded465a4
compositor: only UpdateImages that accepts SmallVec and add helpers for single image (#37730)
Before we only offered helper to add single image (no update or delete)
that got special IPC message, now we simplify this by offering all ops
helpers for dealing with single image (that happens most of the time),
that simply uses `update_images` under the hood. We also optimize for
this use case by using `SmallVec<[ImageUpdate; 1]>` to avoid alloc.

Testing: Just refactor, but code is covered by WPT tests

---------

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
2025-06-26 14:57:15 +00:00
Martin Robinson
3774ef00d4
script: Get scroll offsets from layout (#37509)
No longer store scroll offsets for elements in the DOM. Instead
consistently get and set these in layout's `ScrollTree`. This more
consistently requires layout to run when querying scroll offsets, which
ensures that they are up-to-date and properly bounded by scrollable
overflow area.

Testing: This causes several WPT tests to start passing, and one to
start
failing. In the case of
`/shadow-dom/scroll-to-the-fragment-in-shadow-tree.html`, I believe the
issue
is that we don't properly handle scrolling and shadow DOM elements.
Before, the
faulty scrolling was hiding this issue.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2025-06-20 09:39:12 +00:00
Steven Novaryo
b622157c10
Layout: Add Debug Print for The Scroll Tree (#37522)
Add debug option `dump-scroll-tree` to print the scroll tree that had
been stored after each reflow, or log that the scoll tree is not
initialized yet..

To reduce the coupling, the debug print operation will process the
scroll tree node list that have been constructed in the stacking context
tree. It will generate a adjacency list and do preorder traversal. The
order of the tree then will depends on the order of the node in the node
list that has been constructed. Which, in turn, correspond to the
declaration order of the nodes.

This would help with the analysis and development of post composite
queries and its caching.

cc: @xiaochengh

Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>
2025-06-20 07:16:30 +00:00
Martin Robinson
c0970ea655
compositor: Wait for both Script and the Constellation when shutting down Pipelines (#37505)
Previously, the Constellation would immediately ask the Compositor to
shut down a pipeline, even before the ScriptThread finished shutting it
down. This meant that the Compositor might remove a Pipeline and then
re-add it if the ScriptThread sent a Pipeline-related message (such as a
new display list) in the meantime.

This change makes it so that the Compositor waits for both the
Constellation and the ScriptThread to finish shutting down a Pipeline
before removing its data. In addition, the Constellation no longer
synchronously waits on the Compositor when shutting down Pipelines. This
was important when the Compositor would talk to the ScriptThread
directly, but isn't necessary any longer.

Testing: This is very hard to test, because it depends on the creation
and destruction of many iframes and the particular timing of of all
the messaging between Servo bits. That said, this was tested manually
by observing the completion of Speedometer 2.1.
Fixes: #37458.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
2025-06-17 09:56:31 +00:00
Martin Robinson
f451dccd0b
layout: Store scroll offsets in the ScrollTree (#37428)
There are currently five places that scroll offsets are stored:

 - DOM: A set of scroll offsets used for script.
 - Layout: An array of scroll offsets that is used for tracking
   layout-side scroll offsets.
 - Layout: The scroll offsets stored in the `ScrollTree`. These are
   currently unset and unused.
 - Compositor: The scroll offsets stored in the `ScrollTree` mirrored
   from layout.
 - WebRender: The scrolled offsets stored in the WebRender spatial tree.

This change is the first step in combining the first three into the
layout `ScrollTree`. It eliminates the extra array of scroll offsets
stored in layout in favor of the storing them in the `ScrollTree`. A
followup change will eliminate the ones stored in the DOM.

- In addition the `ScrollState` data structure is eliminated as these
are
now stored in a `HashMap` everywhere when passing them via IPC.
- The offsests stored in layout can now never scroll past the boundaries
of the scrolled content.

Testing: This should not change behavior and is thus covered by existing
WPT tests.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: stevennovaryo <steven.novaryo@gmail.com>
2025-06-13 12:01:27 +00:00
Martin Robinson
29fc878e15
compositor: Do not allow script to scroll beyond node boundaries (#37412)
The compositor was accepting scroll offsets from the ScriptThread
without checking their boundaries. In some cases this could cause a
temporary discrepancy with the rendered scroll offset. This change makes
it so that all offset updates for scroll ayers in the compositor do not
scroll past the scroll boundaries of the node.

Testing: Two new tests pass with this change:
 - `/css/css-position/sticky/position-sticky-left-003.html`
 -  `/css/css-position/sticky/position-sticky-top-003.html`

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
2025-06-12 17:32:50 +00:00
Kenzie Raditya Tirtarahardja
15eadb56a4
[webdriver] Add synchronization for wheel action (#37260)
Implement action synchronization for wheel event. Previously only done
for pointer here https://github.com/servo/servo/pull/36932.

Testing:
`tests/wpt/meta/webdriver/tests/classic/perform_actions/wheel.py`

---------

Signed-off-by: PotatoCP <kenzieradityatirtarahardja18@gmail.com>
2025-06-11 09:03:08 +00:00
Shubham Gupta
aff2a85372
Add support for parsing and applying viewport <meta> (#35901)
This patch comprises following steps:
1. Parses the `viewport` Attribute from `<meta>`.
2. Creates a `ViewportDescription` struct.
3. Populate values into Viewport struct.
4. Pass & Stash Viewport Description to Webview.
5. Process parsed values of `viewport <meta>`

Testing: Tested locally.
Fixes: #36159

---------

Signed-off-by: Shubham Gupta <shubham13297@gmail.com>
Signed-off-by: Xiaocheng Hu <xiaochengh.work@gmail.com>
Co-authored-by: Xiaocheng Hu <xiaochengh.work@gmail.com>
2025-06-06 15:13:51 +00:00
Mukilan Thiyagarajan
8a20e42de4
Add support for static SVG images using resvg crate (#36721)
This change adds support for rendering static SVG images using the
`resvg` crate, allowing svg sources in the `img` tag and in CSS
`background` and `content` properties. There are some limitations in
using resvg:

1. There is no support for animations or interactivity as these would
require implementing the full DOM layer of SVG specification.
2. Only system fonts can be used for text rendering. There is some
mechanism to provide a custom font resolver to usvg, but that is not
explored in this change.
3. resvg's handling of certain edge cases involving lack of explicit
`width` and `height` on the root svg element deviates from what the
specification expects from browsers. For example, resvg uses the values
in `viewBox` to derive the missing width or height dimension, but
without scaling that dimension to preserve the aspect ratio. It also
doesn't allow overriding this behavior.

Demo screenshot:
![servo - resvg
img](https://github.com/user-attachments/assets/8ecb2de2-ab7c-48e2-9f08-2d09d2cb8791)

<details>
<summary>Source</summary>

```
<style>
 #svg1 {
   border: 1px solid red;
 }

 #svg2 {
   border: 1px solid red;
   width: 300px;
 }
 #svg3 {
   border: 1px solid red;
   width: 300px;
   height: 200px;
   object-fit: contain;
 }
 #svg4 {
   border: 1px solid red;
   width: 300px;
   height: 200px;
   object-fit: cover;
 }
 #svg5 {
   border: 1px solid red;
   width: 300px;
   height: 200px;
   object-fit: fill;
 }
 #svg6 {
   border: 1px solid red;
   width: 300px;
   height: 200px;
   object-fit: none;
 }
</style>
</head>
<body>
        <div>
          <img id="svg1" src="https://raw.githubusercontent.com/servo/servo/refs/heads/main/resources/servo.svg" alt="Servo logo">
        </div>
        <div>
          <img id="svg2" src="https://raw.githubusercontent.com/servo/servo/refs/heads/main/resources/servo.svg" alt="Servo logo">
          <img id="svg3" src="https://raw.githubusercontent.com/servo/servo/refs/heads/main/resources/servo.svg" alt="Servo logo">
          <img id="svg4" src="https://raw.githubusercontent.com/servo/servo/refs/heads/main/resources/servo.svg" alt="Servo logo">
        </div>
        <div>
          <img id="svg5" src="https://raw.githubusercontent.com/servo/servo/refs/heads/main/resources/servo.svg" alt="Servo logo">
          <img id="svg6" src="https://raw.githubusercontent.com/servo/servo/refs/heads/main/resources/servo.svg" alt="Servo logo">
        </div>
</body>
```

</details>

---------

Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com>
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
2025-05-27 11:02:40 +00:00
batu_hoang
f52fa9b672
Synchronize dispatch_actions in WebDriver (#36932)
Implement missing synchronization in `dispatch_actions` of `WebDriver`.
https://w3c.github.io/webdriver/#dispatching-actions

> The user agent event loop has spun enough times to process the DOM
events generated by the last invocation of the >[dispatch tick
actions](https://w3c.github.io/webdriver/#dfn-dispatch-tick-actions)
steps.

- Add a way for `ScriptThread` to notify `WebDriver` about the
completion of input commands.
- Add a `webdriver_id` field for `InputEvent`. `ScriptThread` uses it to
distinguish WebDriver events and sends notification.

Tests:
`./mach test-wpt --product servodriver -r
tests\wpt\tests\webdriver\tests\classic\element_click\events.py` pass if
`hit_testing` pass. Check
[issue](https://github.com/servo/servo/issues/36676#issuecomment-2882917136)

cc: @xiaochengh

---------

Signed-off-by: batu_hoang <longvatrong111@gmail.com>
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
2025-05-21 11:03:04 +00:00
Martin Robinson
d8294fa423
layout: Split stacking context and display list construction (#37047)
Previously, after a layout was finished (or skipped in the case of
repaint-only layout), both the stacking context tree and display list
were built. In the case of repaint-only layout, we should be able to
skip the reconstruction of the stacking context tree and only do display
list building.

This change does that, also generally cleaning and up and clarifying the
data structure used during this phase of layout. This opens up the
possibility of a new kind of incremental layout that does both repaint
and a rebuild of the stacking context tree.

On the blaster.html test case[^1], this reduces tightly-measured layout
time from ~45-50 milliseconds to ~25-30 milliseconds on my M3.

[^1]: https://gist.github.com/mrobinson/44ec87d028c0198917a7715a06dd98a0

Testing: There are currently no performance tests for layout. :( This
should
not modify the results of WPT tests.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
2025-05-20 13:42:39 +00:00
Kenzie Raditya Tirtarahardja
eaf9224799
Implement wheel action in webdriver (#36744)
https://w3c.github.io/webdriver/#wheel-actions

Test:
`tests/wpt/tests/webdriver/tests/classic/perform_actions/wheel.py::{test_null_response_value,test_params_actions_origin_outside_viewport[element],test_params_actions_origin_outside_viewport[viewport]},
tests/wpt/tests/webdriver/tests/classic/perform_actions/perform.py`
Fixes: https://github.com/servo/servo/issues/36720

cc: @xiaochengh @longvatrong111 @yezhizhen

Signed-off-by: PotatoCP <kenzieradityatirtarahardja.18@gmail.com>
Co-authored-by: PotatoCP <kenzieradityatirtarahardja.18@gmail.com>
2025-05-07 08:41:34 +00:00
Josh Matthews
ba8f923201
Various memory measurement improvements (#36834)
The two significant changes here are 1) a commit that frees memory used
to perform memory reporting once the reporting is complete, 2) memory
reporting for the system font service. There are various other commits
that remove `#[ignore_malloc_size_of]` attributes for data that we are
now able to measure, but they do not significantly change our
measurements when testing servo.org.

Testing: Comparing the output of about:memory on servo.org.

---------

Signed-off-by: Josh Matthews <josh@joshmatthews.net>
2025-05-07 04:00:12 +00:00