Commit graph

150 commits

Author SHA1 Message Date
Andreas Kling
877391d569 LibWeb: Add more fast_is<T> helpers for layout and paintable nodes 2025-04-18 14:45:56 +02:00
Andrew Kaster
ea68944149 LibWeb: Store LibGfx objects in RefPtr to const for draw commands 2025-04-16 10:41:44 -06:00
Andrew Kaster
4b7f4aef10 LibWeb: Pass RefPtr to const to ClippableAndScrollable setters
We were already storing the ClipFrame and ScrollFrame in RefPtr to const
but we were passing them as RefPtr to non-const to the setters.
2025-04-16 10:41:44 -06:00
Andrew Kaster
be2dd91289 LibGfx+LibWeb: Store Typeface and Font-related types in RefPtr to const 2025-04-16 10:41:44 -06:00
Andrew Kaster
6d11414957 LibWeb: Make storage of CSS::StyleValues const-correct
Now we consistently use `RefPtr<StyleValue const>` for all StyleValues.
2025-04-16 10:41:44 -06:00
Mehran Kamal
6ba60188b4 LibWeb+LibGfx: Paint dash array and offset for SVG and Canvas 2025-04-14 18:00:38 +01:00
Mehran Kamal
a64902ba25 LibWeb+LibGfx: Paint miter_limit for SVG and Canvas 2025-04-14 18:00:38 +01:00
Aliaksandr Kalenik
6507d23e29 LibWeb: Save ScrollState snapshot in DisplayList to avoid race condition
Some checks are pending
CI / Lagom (arm64, Sanitizer_CI, false, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (x86_64, Fuzzers_CI, false, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, false, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, true, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (arm64, macos-15, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (x86_64, ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
With this change we save a copy of of scroll state at the time of
recording a display list, instead of actual ScrollState pointer that
could be modifed by the main thread while display list is beings
rasterized on the rendering thread, which leads to a frame painted with
inconsistent scroll state.

Fixes https://github.com/LadybirdBrowser/ladybird/issues/4288
2025-04-12 02:55:18 +02:00
Viktor Szépe
5cc371d54c LibWeb: Fix typos - act II 2025-04-09 15:05:20 +01:00
Andrew Kaster
8fd81c3338 LibGC+LibWeb+LibJS: Remove workaround for Swift boolean bitfield issue
We're using a main snapshot everywhere, so we can yeet the workaround.
2025-04-04 13:06:53 -06:00
Andrew Kaster
e4c88915ab LibGC+LibJS+LibWeb: Add workaround for Swift boolean bitfield issue
This patch adds a workaround for a Swift issue where boolean bitfields
with getters and setters in SWIFT_UNSAFE_REFERENCE types are improperly
imported, causing an ICE.
2025-04-03 16:47:48 -06:00
Aliaksandr Kalenik
cf143cf118 LibWeb: Don't call flush() when no surface is passed in execute_impl()
`DisplayListPlayer::execute_impl()` can receive null surface if it was
invoked to rasterize nested display lists (we use them for iframes). In
this case we should not call `flush()` by the end of execution and wait
until outer display list execution will do that.
2025-04-02 23:22:38 +02:00
Aliaksandr Kalenik
fd147e6be0 LibWeb: Protect SkiaBackendContext with a mutex
The Skia Ganesh backend we currently use doesn't support painting from
multiple threads, which could happen before this change when the main
thread used Skia to paint on the HTML canvas while the rendering thread
was working on display list rasterization.

Fixes https://github.com/LadybirdBrowser/ladybird/issues/4172
2025-04-01 23:39:05 +02:00
Aliaksandr Kalenik
24527b6ae3 LibWeb: Pass PaintingSurface into DisplayListPlayer::execute()
Deleteing set_surface() makes DisplayListPlayer API a bit more intuitive
because now caller doesn't have to think whether it's necessary to
restore previous surface after execution, instead DisplayListPlayer
takes care of it by maintaining a stack of surfaces.
2025-04-01 23:39:05 +02:00
Glenn Skrzypczak
da09608156 LibWeb/Painting: Fix blending with viewport background
The viewport is now drawn onto transparent black instead of the
background color of the viewport.
2025-04-01 13:38:00 +02:00
Glenn Skrzypczak
9973b01848 LibWeb/CSS: Improved implementation of background-blend-mode
This is a improved version of a73cd88f0c
The old commit was reverted in 552dd18696

The new version only paints an element into a new layer if background
blend modes other than normal are used. The rasterization performance
of most websites should therefore not suffer.

Co-Authored-By: Alexander Kalenik <kalenik.aliaksandr@gmail.com>
2025-04-01 13:38:00 +02:00
Glenn Skrzypczak
6906f1722a LibWeb/Painting: Add back SaveLayer command
This reverts commit 552dd18696.
2025-04-01 13:38:00 +02:00
Aliaksandr Kalenik
e33174fca1 LibWeb: Make BackingStore atomic ref-counted
Some checks are pending
CI / Lagom (x86_64, Sanitizer_CI, true, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (arm64, Sanitizer_CI, false, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (x86_64, Fuzzers_CI, false, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, false, ubuntu-24.04, Linux, GNU) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (macos-14, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
This is required to make sure rendering thread will keep backing stores
alive in case backing stores reallocation happens during rasterization.

Fixes https://github.com/LadybirdBrowser/ladybird/issues/4164
2025-04-01 03:05:21 +02:00
Aliaksandr Kalenik
24e2c402f5 LibWeb+WebContent: Move display list rasterization off the main thread
The display list is an immutable data structure, so once it's created,
rasterization can be moved to a separate thread. This allows more room
for performing other tasks between processing HTML rendering tasks.

This change makes PaintingSurface, ImmutableBitmap, and GlyphRun atomic
ref-counted, as they are shared between the main and rendering threads
by being included in the display list.
2025-03-31 15:58:15 +01:00
Tim Ledbetter
568531f06a Everywhere: Mark GC::Cell derived classes as Weakable explicitly
Some checks are pending
CI / Lagom (arm64, Sanitizer_CI, false, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (x86_64, Fuzzers_CI, false, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, false, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, true, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (macos-14, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
Previously, all `GC::Cell` derived classes were Weakable. Marking only
those classes that require this functionality as Weakable allows us to
reduce the memory footprint of some frequently used classes.
2025-03-29 17:36:33 -05:00
Andreas Kling
ba8aabdeb0 Revert "LibWeb: Skip "overlay" paint phase when there's no inspected node"
This reverts commit dc56435ecd.

It broke overlay scrollbars.
2025-03-28 20:08:48 +00:00
Aliaksandr Kalenik
1229328adc Revert "LibWeb/Painting: Add SaveLayer command"
This reverts commit 1898643ba4.
2025-03-28 16:48:03 +00:00
Aliaksandr Kalenik
552dd18696 Revert "LibWeb/CSS: Implement 'background-blend-mode'"
This reverts commit a73cd88f0c.

Emitting SaveLayer for each paintable made rasterization a lot slower
on every website because now Skia has to allocate enormous amounts of
temporary surfaces. Let's revert it for now and figure how to implement
it with less aggressive SaveLayer usage.
2025-03-28 16:48:03 +00:00
Glenn Skrzypczak
a73cd88f0c LibWeb/CSS: Implement 'background-blend-mode'
This implements the 'background-blend-mode' CSS property.
2025-03-28 09:41:06 +00:00
Glenn Skrzypczak
1898643ba4 LibWeb/Painting: Add SaveLayer command
This adds a command for saving the current layer of the canvas.
This is useful for painting content onto a blank background in
isolation and later compositing it onto the canvas.
2025-03-28 09:41:06 +00:00
Aliaksandr Kalenik
e655b77393 LibWeb: Fix scroll offset application for SVG root box
Now we use `before_paint()` and `after_paint()` calls for SVG root box
to make sure that both clip and scroll are applied.

Fixes painting of SVG arrows on www.ubereats.com
2025-03-26 20:12:45 +00:00
Psychpsyo (Cameron)
c7926b2212 LibWeb: Change while to for loop 2025-03-25 15:50:45 +00:00
Andreas Kling
dc56435ecd LibWeb: Skip "overlay" paint phase when there's no inspected node
This avoids a bunch of tree traversal that doesn't find anything to
paint anyway.
2025-03-25 07:31:42 +00:00
Jelle Raaijmakers
c2e21d33eb LibWeb: Do not calculate corner radii if no radius is set
The `as_corner()` and `floored_device_pixels()` functions popped up
frequently in profiles when selecting text on some Tweakers.net pages.
For every corner we're performing multiple device pixel calculations
regardless of whether any radius was actually set.

Add an early return if no radius is set. On my machine this reduces the
time taken in both `as_corner()` and `floored_device_pixels()` by 46%
(63% fewer calls).
2025-03-19 14:22:10 +01:00
Aliaksandr Kalenik
2e256d2eac LibWeb: Invalidate text-decoration-thickness as paint-only property
Fixes underinvalidation caused by resolving text-decoration-thickness
during layout commit, while this property can be invalidated
independently of layout.
2025-03-16 22:25:26 +01:00
Mehran Kamal
12968ff025 LibGfx: Move to_skia_cap, to_skia_join to SkiaUtils 2025-03-15 14:02:27 +01:00
Aliaksandr Kalenik
9e287465b9 LibWeb: Fix CSS transform invalidation when transitioning to none
Fixes https://github.com/LadybirdBrowser/ladybird/issues/2707
2025-03-15 13:30:45 +01:00
Mehran Kamal
670a7ab048 LibWeb/SVG: Implement cap_style, join_style for Skia painting backend 2025-03-13 15:09:41 +01:00
InvalidUsernameException
d76f841994 LibWeb: Do not deform bitmaps partially outside the img-box
Instead of trying to manually determine which parts of a bitmap fall
within the box of the `<img>` element, just draw the whole bitmap and
let Skia clip the draw-area to the correct rectangle.

This fixes a bug where the entire bitmap was squashed into the rectangle
of the image box instead of being clipped.

With this change, image rendering is now correct enough to import some
of the WPT tests for object-fit and object-position. To get some good
coverage I have imported all tests for the `<img>` tag. I also wanted to
import a subset of the tests for the `<object>` tag, since those are
passing as well now. Unfortunately, they are flaky for unknown reasons.

This is the second attempt at this bugfix. The prior one was e055927ead
and broke image rendering whenever the page was scrolled. It has
subsequently been reverted in 16b14273d1. Hopefully this time it is not
horribly broken.
2025-03-10 17:14:13 +01:00
Tim Ledbetter
88d35c547c LibWeb/CSS: Implement the caret-color property 2025-03-09 19:36:29 +01:00
Gingeh
31853c13d3 LibWeb: Implement css gradient-interpolation-method 2025-03-06 11:33:12 +00:00
Aliaksandr Kalenik
16b14273d1 Revert "LibWeb: Do not deform bitmaps partially outside the img-box"
This change broken image rendering.

This reverts commit e055927ead.
2025-03-05 19:44:49 +01:00
InvalidUsernameException
e055927ead LibWeb: Do not deform bitmaps partially outside the img-box
Instead of trying to manually determine which parts of a bitmap fall
within the box of the `<img>` element, just draw the whole bitmap and
let Skia clip the draw-area to the correct rectangle.

This fixes a bug where the entire bitmap was squashed into the rectangle
of the image box instead of being clipped.

With this change, image rendering is now correct enough to import some
of the WPT tests for object-fit and object-position. To get some good
coverage I have imported all tests for the `<img>` tag. I also wanted to
import a subset of the tests for the `<object>` tag, since those are
passing as well now. Unfortunately, they are flaky for unknown reasons.
2025-03-05 16:32:47 +01:00
InvalidUsernameException
5f1a146afd LibWeb: Draw floating replaced elements more correctly
Previously floating replaced elements were drawn incorrectly and also
twice.
2025-03-03 21:49:44 +01:00
Vaxry
c5d0af54d0 LibWeb: Don't handle scroll if no axes are accepted
In some cases, we might be hovering directly on an element
scrollable e.g. horizontally, but we are scrolling vertically.
In these cases, we need to delegate the scroll to the parent
instead of stalling the user's scroll.
2025-03-01 23:54:48 +01:00
Sam Atkins
532c01c388 LibWeb: Implement text-decoration: spelling-error and grammar-error 2025-02-28 16:34:08 +00:00
Sam Atkins
d8a73a8165 LibWeb/Painting: Paint triangle waves using Skia
This has been left unimplemented since we switched to the Skia renderer.
Now `text-decoration-style: wavy` actually paints a wavy line. :^)

We had a text-decoration test, but it only checked `solid` lines, so
I've replaced it with a modified version of the old test page from
Serenity, without the blink option, and with some thickness parameters.

I did experiment with using a `SkPath1DPathEffect` to make it repeat the
pattern for us, but I couldn't make it look good at all.
2025-02-28 16:34:08 +00:00
Sam Atkins
bfd7ac1204 LibWeb+WebContent+UI: Support image cursors
The `cursor` property accepts a list of possible cursors, which behave
as a fallback: We use whichever cursor is the first available one. This
is a little complicated because initially, any remote images have not
loaded, so we need to use the fallback standard cursor, and then switch
to another when it loads.

So, ComputedValues stores a Vector of cursors, and then in EventHandler
we scan down that list until we find a cursor that's ready for use.

The spec defines cursors as being `<url>`, but allows for `<image>`
instead. That includes functions like `linear-gradient()`.

This commit implements image cursors in the Qt UI, but not AppKit.
2025-02-28 13:50:13 +01:00
Sam Atkins
fd2414ba35 LibWeb/Painting: Call Base::resolve_paint_properties() from children 2025-02-28 13:50:13 +01:00
Sam Atkins
9cbd8a82c7 LibWeb: Only require NodeWithStyle for gradient size resolution
None of the code here actually needs a NodeWithStyleAndBoxModelMetrics,
and we'll need to be able to resolve images from inside
NodeWithStyle::apply_style().
2025-02-28 13:50:13 +01:00
Timothy Flynn
72905c84d5 LibWeb+LibWebView+WebContent: Support both inspecting/highlighting nodes
Our own Inspector differs from most other DevTools implementations with
regard to highlighting DOM nodes as you hover elements in the inspected
DOM tree. In other implementations, as you change the hovered node, the
browser will render a box model overlay onto the page for that node. We
currently don't do this; we wait until you click the node, at which
point we both paint the overlay and inspect the node's properties.

This patch does not change that behavior, but separates the IPCs and
internal tracking of inspected nodes to support the standard DevTools
behavior. So the DOM document now stores an inspected node and a
highlighted node. The former is used for features such as "$0" in the
JavaScript console, and the latter is used for the box model overlay.
Our Inspector continues to set these to the same node.
2025-02-24 12:05:29 -05:00
InvalidUsernameException
f7276bfab3 LibWeb: Reduced number of recompiled files for CSS property headers
Some checks are pending
CI / Lagom (x86_64, Sanitizer_CI, false, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (arm64, Sanitizer_CI, false, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (x86_64, Fuzzers_CI, false, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, true, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (macos-14, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
This reduces the number of `.cpp` files that need to be recompiled when
one of the below header files changes as follows:

CSS/ComputedProperties.h: 1113 -> 49
CSS/ComputedValues.h: 1120 -> 209
2025-02-23 10:14:39 -05:00
InvalidUsernameException
be47f95180 LibWeb: Reduce number of recompiled files for display list headers
This reduces the number of `.cpp` files that need to be recompiled when
one of the below header files changes as follows:

Painting/Command.h: 1030 -> 61
Painting/DisplayList.h: 1030 -> 60
Painting/DisplayListRecorder.h: 557 -> 59
2025-02-23 10:14:39 -05:00
Tim Ledbetter
d410fa8381 LibWeb: Ensure inert elements are not selectable 2025-02-21 12:41:57 +00:00
Tim Ledbetter
cb405c773b LibWeb: Ensure inert elements are not visible for hit testing 2025-02-21 12:41:57 +00:00