Commit Graph

669 Commits

Author SHA1 Message Date
Jelle Raaijmakers
57a9c795d3 LibGfx+LibRegex: Prevent double hashing of values
We had three instances of `pair_int_hash()` being called with a value
that was pulled through `u32_hash()`, which is not necessary - both
arguments to `pair_int_hash()` will be properly hashed.
2026-02-23 16:44:07 +01:00
Timothy Flynn
6bc66fe786 AK+LibGfx: Prefer if consteval over is_constant_evaluated
This is a new language construct in C++23, meant to generally replace
is_constant_evaluated. See:

https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1938r3.html#problems-with-status-quo
2026-02-22 13:56:12 -05:00
Andreas Kling
80b80b28ef LibGfx: Fall back to CPU surface when GPU surface creation fails
GPU backends have maximum texture dimension limits (e.g. 16384 on
macOS Metal). When a surface exceeds this limit, Skia's RenderTarget
returns null and we would VERIFY crash.

Instead, fall back to a CPU-backed surface via SkSurfaces::WrapPixels.
This produces a correct rendering, just without GPU acceleration.
2026-02-22 14:22:51 +01:00
Ben Wiederhake
fb7095ab88 LibCore: Remove unused header in Resource 2026-02-21 19:27:35 +01:00
Callum Law
1be9f1ae9d LibWeb: Move Gfx::FontVariantAlternates to CSS namespace
This is only ever used in the CSS namespace
2026-02-20 22:01:44 +00:00
Callum Law
1faaf83121 LibWeb: Move Gfx::FontVariantLigatures to the CSS namespace
This is only ever used in the CSS namespace and having it there allows
us to reuse existing enums
2026-02-20 22:01:44 +00:00
Callum Law
afc6b7b24c LibWeb: Move Gfx::FontVariantLigatures to the CSS namespace
This is only ever used in the CSS namespace and having it there allows
us to reuse existing enums
2026-02-20 22:01:44 +00:00
Callum Law
f0dd7ec4e9 LibWeb: Move Gfx::FontVariantEastAsian to CSS namespace
This is only ever used in the CSS namespace and having it there allows
us to reuse existing enums
2026-02-20 22:01:44 +00:00
Jelle Raaijmakers
1745926fc6 AK+Everywhere: Use MurmurHash3 for int/u64 hashing
Rework our hash functions a bit for significant better performance:

* Rename int_hash to u32_hash to mirror u64_hash.
* Make pair_int_hash call u64_hash instead of multiple u32_hash()es.
* Implement MurmurHash3's fmix32 and fmix64 for u32_hash and u64_hash.

On my machine, this speeds up u32_hash by 20%, u64_hash by ~290%, and
pair_int_hash by ~260%.

We lose the property that an input of 0 results in something that is not
0. I've experimented with an offset to both hash functions, but it
resulted in a measurable performance degradation for u64_hash. If
there's a good use case for 0 not to result in 0, we can always add in
that offset as a countermeasure in the future.
2026-02-20 22:47:24 +01:00
Andreas Kling
e87f889e31 Everywhere: Abandon Swift adoption
After making no progress on this for a very long time, let's acknowledge
it's not going anywhere and remove it from the codebase.
2026-02-17 10:48:09 -05:00
Jelle Raaijmakers
d37691a0d4 LibGfx: Add Rect<T>::inflate_primary/secondary_for_orientation()
This mirrors the 2-param `::inflate(T, T)` method but allows for passing
in an orientation.
2026-02-17 10:51:48 +01:00
Jelle Raaijmakers
8654e2caf4 LibWeb: Apply letter-spacing for selection rects and grapheme bounds
Fixes the selection rect on the title text of https://modern-css.com/
being misaligned with the actual characters.
2026-02-17 10:51:48 +01:00
Andreas Kling
61c0fb1940 LibGfx: Support incremental WebP animation decode
Instead of decoding all animation frames at once in decode_webp_image()
and caching them in frame_descriptors, decode frames one at a time
on demand. This avoids holding all decoded frames in memory at once.

The WebPAnimDecoder is kept alive across frame() calls and supports
reset for backward seeks (needed for animation looping).
2026-02-13 18:34:24 +01:00
Andreas Kling
2d811fb432 LibGfx: Add frame_duration() to ImageDecoderPlugin
Add a virtual method to query frame durations without decoding pixel
data. This is needed by the ImageDecoder service to extract timing
metadata upfront for streaming animation decode.

Implement the method for GIF, PNG, WebP, AVIF, and JPEGXL decoders.
For WebP, extract durations from the demuxer during header decode so
they are available before any frames are decoded.
2026-02-13 18:34:24 +01:00
Luke Wilde
e9f5df2131 LibWeb/SVG: Implement the feTurbulence filter 2026-02-11 09:39:39 +01:00
Jelle Raaijmakers
6251f18d9b LibGfx: Add GlyphRun::slice()
Skia does not seem to have an API to easily draw parts of text runs, so
introduce ::slice() with which we can more easily construct spans of
text to render individually in future changes (e.g. ::selection
text-shadow support).
2026-02-06 10:47:50 +00:00
Callum Law
11d524bda4 LibWeb: Support CSS font-optical-sizing property 2026-02-03 11:44:25 +00:00
Undefine
416f586c11 LibGfx+Meta: Move the USE_VULKAN_IMAGES definition to CMake
We had the same check in both places so let's just unify it.
2026-02-02 10:41:30 -07:00
Callum Law
b55023fad3 LibGfx+LibWeb: Resolve font features per font rather than per element
Previously we would resolve font features
(https://drafts.csswg.org/css-fonts-4/#feature-variation-precedence)
per element, while this works for the current subset of the font feature
resolution algorithm that we support, some as yet unimplemented parts
require us to know whether we are resolving against a CSS @font-face
rule, and if so which one (e.g. applying descriptors from the @font-face
rule, deciding which @font-feature-values rules to apply, etc).

To achieve this we store the data required to resolve font features in a
struct and pass that to `FontComputer` which resolves the font features
and stores them with the computed `Font`.

We no longer need to invalidate the font shaping cache when features
change since the features are defined per font (and therefore won't ever
change).
2026-02-02 14:11:43 +00:00
Callum Law
c93336c72f LibGfx: Implement hash functions for some more types
We are going to be using these types in HashTable keys in a future
commit.
2026-02-02 14:11:43 +00:00
Callum Law
5917a8c1c8 LibGfx+LibWeb: Allow setting FontVariationSettings for default font
While our default font supporting variations is unlikely, this is
nevertheless required for our fallback font to be considered equal to
it's non-default/fallback equivalent (i.e. `font-family: serif`) which
in turn is required for LineBuilder to merge chunks into a single
fragment.
2026-02-02 14:11:43 +00:00
Tim Ledbetter
72d48c7a03 LibGfx: Default reserved, unspecified or invalid CICP values to BT.709 2026-01-27 11:34:24 -06:00
Aliaksandr Kalenik
a1d538ae58 LibGfx: Cache GPU textures for bitmap-backed ImmutableBitmaps
Previously, bitmap-backed images were stored as raster SkImages and
re-uploaded to the GPU every frame. This caused significant overhead
in createProxyFromBitmap, uploadToTexture, and memmove.

Now, ensure_sk_image() converts raster SkImages to GPU textures using
SkImages::TextureFromImage() on first use. The texture is cached and
reused for subsequent frames.

- Mipmaps disabled (kNo) to reduce upload time and memory
- Budgeted (kYes) to let Skia manage GPU memory and evict under pressure
- Falls back to raster rendering if no GPU context available
2026-01-24 21:21:28 +01:00
Aliaksandr Kalenik
44d90af3d6 LibGfx+LibWeb: Cache SkTextBlob in GlyphRun
Previously, SkTextBlob was built on every paint in
DisplayListPlayerSkia::draw_glyph_run(), which meant:
- Repeated work when the same display list is painted multiple times
- Glyph arrays were allocated and populated on each paint

Now the blob is built once during display list recording and cached in
GlyphRun.
2026-01-24 15:22:03 +01:00
Luke Wilde
1494599b82 LibGfx: Add missing SkiaBackendContext locks
This adds locking for:
- Creating a sk_image from ImmutableBitmap
- Destroying ImmutableBitmap's sk_image
- Read/writing PaintingSurface for Bitmaps
2026-01-23 17:15:23 +01:00
Aliaksandr Kalenik
cb8ecb3c11 LibGfx+LibWeb: Move SVG mask/clip composition from CPU to GPU
Previously, both mask and clip-path were rendered to separate mutable
Gfx::Bitmap objects which forced CPU rasterization. They were then
combined using a CPU pixel-by-pixel operation before being returned
as an ImmutableBitmap.

Instead of including mask in the final bitmap as already rasterized
images, we now use display lists which opens opportunity to utilize
GPU if available.

Bitmap::apply_mask() and ApplyMaskBitmap display list command are no
longer used and have been removed.
2026-01-23 16:23:06 +01:00
Zaggy1024
e6dbcccb99 LibGfx+LibMedia: Send video frames to Skia as subsampled YUV
This saves us from having our own color conversion code, which was
taking up a fair amount of time in VideoDataProvider. With this change,
we should be able to play high resolution videos without interruptions
on machines where the CPU can keep up with decoding.

In order to make this change, ImmutableBitmap is now able to be
constructed with YUV data instead of an RBG bitmap. It holds onto a
YUVData instance that stores the buffers of image data, since Skia
itself doesn't take ownership of them.

In order to support greater than 8 bits of color depth, we normalize
the 10- or 12-bit color values into a 16-bit range.
2026-01-22 19:44:36 +01:00
Andreas Kling
177809db6e LibGfx: Validate color space size and deserialization result on decode
A malicious IPC peer could claim an enormous color space size, causing
OOM when we try to allocate a buffer. Add a 1 MiB limit since color
space profiles shouldn't be anywhere near that large.

Also validate that SkColorSpace::Deserialize() actually succeeded
before using the result.
2026-01-22 17:38:15 +01:00
Andreas Kling
039fa00bfc LibGfx: Use checked arithmetic when encoding BitmapSequence
The total_buffer_size calculation could theoretically overflow if we
tried to encode a sequence of bitmaps with combined size > SIZE_MAX.

Use Checked<size_t> and VERIFY to catch this (unlikely) encoding bug.
2026-01-22 17:38:15 +01:00
Callum Law
c35ecc8b1c LibWeb: Respect font-width for variable fonts 2026-01-21 23:49:25 +01:00
Callum Law
3f97f1579f LibGfx: Remove default parameters for some font related functions
We always pass these values so there is no need for default parameters
2026-01-21 23:49:25 +01:00
Callum Law
89a360e643 LibGfx+LibWeb: Remove unused FontWeight.h 2026-01-21 23:49:25 +01:00
Tim Ledbetter
3e704e0fd6 LibGfx+LibWeb: Fall back to system fonts for missing glyphs
When rendering text, if none of the fonts in the cascade list contain a
glyph for a given code point, we now query Skia's font manager to find
a system font that can render it.
2026-01-21 14:01:35 +01:00
Aliaksandr Kalenik
a36fcdb9c5 LibGfx: Add to_svg_string() method to Path
This converts a Path to its SVG path data string representation using
Skia's SkParsePath::ToSVGString().
2026-01-19 04:01:37 +01:00
ayeteadoe
5279e0ce73 CMake: Remove ENABLE_WINDOWS_CI option and adjust presets to match Unix
ENABLE_WINDOWS_CI and the *_CI presets were initially added back when
the AK library and all the AK Test* executables were the only targets
that supported building and running in CI. Since then, almost all the
targets in the codebase are built on Windows besides the following:
    - LibLine
    - test-262-runner

Since these targets above are not required to actually run or test the
browser on Windows in its current experimental state, fully disabling
them should be fine for now.

ENABLE_WINDOWS_CI was also used to exclude test-web from ctest. This
can be fully disabled on Windows for now until proper runtime support
is added.

The remaining locations were all using ENABLE_WINDOWS_CI as a proxy for
ENABLE_ADDRESS_SANITIZER, so we can just be explicit instead.

The new presets map much more directly to the unix Release, Debug, and
Sanitizer presets which should make setting up ladybird on Windows less
confusing.

We also make the new Windows_Experimental_Release preset the default in
ladybird.py to match Unix.
2026-01-16 11:15:16 -07:00
Jonathan Gamble
8f1cb4cbb0 LibWeb: Implement resizing for eligible elements and update scrollbars
Add ElementResizeAction to Page (maybe there's a better place). It's
just a mousemove delegate that updates styles on the target element.

Add ChromeMetrics for zoom-invariant chrome like scrollbar thumb
thickness, resize gripper size, paddings, etc. It's not user-stylable
but separates basic concerns in a way that a visually gifted
designer unlike myself can adjust to taste.

These values are pre-divided by zoom factor so that PaintableBox can
continue using device_pixels_per_css_pixel calls as normal.

The adjusted metrics are computed on demand from Page multiple times
per paint cycle, which is not ideal but avoids lifetime management and
atomics. Maybe someone with more surety about the painting flow control
can improve this, but it won't be a huge win. If profiling shows
this slowing paints, then Ladybird is in good shape.

Update PaintableBox to draw the resize gripper and deconflict
the scrollbars. Set apropriate cursors for scrollbars and gripper in
mousemove. We override EventHandler's cursor handling because nothing
should ever come between a man and his resize gripper.

Chrome metrics use the CSSPixels class. This is good because it's
broadly compatible but bad because they're actually different units
when zoom is not 1.0. If that's a problem, we could make a new type
or just use double.
2026-01-12 11:00:14 +00:00
Andreas Kling
98a1bff615 LibGfx: Avoid guessing HarfBuzz segment properties for ASCII text
For ASCII text, we know the script is Latin and direction is LTR.
Set these properties directly instead of calling
hb_buffer_guess_segment_properties(), which scans the text buffer
to detect script and direction.

For non-ASCII text, use the text_type parameter to set direction
when known (Ltr/Rtl), reducing guesswork to just script detection.
2026-01-11 11:10:19 +01:00
Rocco Corsi
bec3f04637 LibGfx: Make NVIDIA 10 series GPU work with Dedicated Memory Allocation 2026-01-06 17:28:43 +01:00
Luke Wilde
2058c05d50 LibGfx: Create Gfx::Bitmap for PaintingSurface in ImmutableBitmap 2026-01-05 15:56:15 +01:00
Undefine
7f42cf3a0e LibGfx: Switch Vulkan image sharing mode to VK_SHARING_MODE_EXCLUSIVE
The validation layers complain if it's set to concurrent and we have
only one queue.
2026-01-02 10:23:46 +01:00
Undefine
d71e5f676f LibGfx: Remove incorrect Vulkan queue family index from image creation
This does not seem to impact functionality and gets rid of a validation
layer warning.
2026-01-02 10:23:46 +01:00
Undefine
988f631cdf LibGfx: Request the VK_EXT_external_memory_dma_buf Vulkan extensions
Otherwise the validation layers complain that this is required when
using VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT as an image
handle.
2026-01-02 10:23:46 +01:00
Undefine
8601430f5b LibGfx: Request the VK_KHR_image_format_list Vulkan extensions
Otherwise the validation layers complain that it's required by
`VK_EXT_image_drm_format_modifier`.
2026-01-02 10:23:46 +01:00
ayeteadoe
ee3aa865af Meta+LibGfx+LibWeb: Update skia to 144 and remove overlay port
Skia deprecated some non-span versions of their API, but they provided
SK_SUPPORT_UNSPANNED_APIS to expose the legacy versions.

SkFontMgr_New_FontConfig now requires a font scanner to be passed in.

There were a few screenshot tests that visibily looked the same but skia
must've changed some rendering infrastructure as the PNGs were not
matching anymore so I rebaselined those and adjusted the fuzzy matching
config to allow them to pass on both macOS and Linux.

The empty-radial-gradient-crash Ref test started to fail as we were
setting the horizontal scale factor to inf in when the height = 0. It
looks like something changed to make doing that not valid anymore.

The overlay port is removed as the issues, mainly skcms symbol import
and export were resolved upstream in skia and utilized in the new port
version.
2025-12-17 12:00:33 +01:00
Andreas Kling
2577c5ce67 Revert "Meta+LibGfx+LibWeb: Update skia to 144 and remove overlay port"
This reverts commit ac9688ea1e.

Broke the build on arm64 Linux.
2025-12-15 14:12:34 -06:00
ayeteadoe
ac9688ea1e Meta+LibGfx+LibWeb: Update skia to 144 and remove overlay port
Skia deprecated some non-span versions of their API, but they provided
SK_SUPPORT_UNSPANNED_APIS to expose the legacy versions.

SkFontMgr_New_FontConfig now requires a font scanner to be passed in.

There were a few screenshot tests that visibily looked the same but skia
must've changed some rendering infrastructure as the PNGs were not
matching anymore so I rebaselined those and adjusted the fuzzy matching
config to allow them to pass on both macOS and Linux.

The empty-radial-gradient-crash Ref test started to fail as we were
setting the horizontal scale factor to inf in when the height = 0. It
looks like something changed to make doing that not valid anymore.

The overlay port is removed as the issues, mainly skcms symbol import
and export were resolved upstream in skia and utilized in the new port
version.
2025-12-15 10:56:27 +01:00
Timothy Flynn
612558144b LibGfx: Add a stringifier for StandardCursor 2025-12-03 12:23:56 +01:00
Timothy Flynn
dcf8463886 LibGfx: Remove unused StandardCursor::__Count 2025-12-03 12:23:56 +01:00
InvalidUsernameException
ce2c4a3417 LibGfx+LibWeb: Fix compile errors in clang-cl from recent header cleanup
The recent commits 28ba610f32 and
70c4ed261f adjusted some include
directives to avoid excessive recompilation when changing some header
files. This has broken compilation with clang-cl on Windows without
getting noticed before the PRs were merged.
2025-11-30 08:45:29 -05:00
InvalidUsernameException
1f8a42c367 LibGfx: Add a test for bitmap export
The verified pixel output in this test just reflects currently observed
behavior, I have not verified that all cases output the correct data wrt
what the spec expects.
2025-11-28 18:32:48 +01:00