Commit Graph

21 Commits

Author SHA1 Message Date
Zaggy1024
3cfe1f7542 LibGfx: Implement YUV->RGBA color conversion for CPU painting
Using the Rust yuv crate, eagerly convert from YUV to RGBA on the CPU
when a GPU context is unavailable.

Time spent converting an 8-bit YUV frame with this crate is better than
libyuv on ARM by about 20%, and on x86 with AVX2, it achieves similar
numbers to libyuv.
2026-04-18 01:25:00 -05:00
Zaggy1024
f434b56ffa LibGfx: Upload YUV data to Skia eagerly when creating ImmutableBitmaps 2026-04-18 01:25:00 -05:00
Zaggy1024
8504706ade LibGfx: Store and use a ColorSpace instance for YUV bitmaps
This removes the need for a separate path for setting up Skia color
spaces for videos.
2026-04-18 01:25:00 -05:00
Zaggy1024
c47971e563 LibGfx: Stop storing SkYUVAPixmaps in YUVData
Storing these was pointless, since they're only used briefly to provide
the info needed to upload the buffers to the GPU.

For BT.2020 coefficients, we can just say that the bit depth is 16 bits
since we're always bit replicating to that for Skia's shaders.
2026-04-18 01:25:00 -05:00
Zaggy1024
f704294ae8 LibGfx: Treat HLG transfer characteristics as sRGB
HLG is designed to be backward-compatible with sRGB, so this is the
intended rendering in non-HDR devices.
2026-04-18 01:25:00 -05:00
Zaggy1024
7c5d264977 LibGfx: Fix some clang-tidy warnings in ImmutableBitmap.cpp 2026-04-18 01:25:00 -05:00
Jelle Raaijmakers
b2e0a2515a LibGfx: Ensure sk_image is available in ::export_to_byte_buffer()
When an ImmutableBitmap is constructed from video data, there's a
probability that we're dealing with YUV data and we do not yet have an
sk_image to work with.

No regression test since we require a GPU to end up in this situation.

Fixes the background scenery on https://screen.toys/roadtrip/.
2026-04-15 17:08:02 -05:00
Jelle Raaijmakers
6596f27475 LibGfx: Use accelerated painting surface snapshots if available
If we have a Skia backend context available, use it to make image
snapshots. Drops blitting CPU usage from 55% to 0.6% for slither.io on
my machine.

Adds a fallback to ::bitmap() to store a bitmap blitted from an SkImage
if that's available.
2026-02-27 10:06:48 +01: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
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
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
Luke Wilde
2058c05d50 LibGfx: Create Gfx::Bitmap for PaintingSurface in ImmutableBitmap 2026-01-05 15:56:15 +01: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
InvalidUsernameException
a81e407c44 LibWeb: Do not crash when converting a bitmap to RGB888
This makes it so that we can visit satellite and hybrid view on
maps.apple.com. Previously this would crash from a bounds check due to
us asking Skia to write 32bpp RGBx8888 data into a buffer sized for
24bpp RGB888.
2025-11-28 18:32:48 +01:00
InvalidUsernameException
88c4814de6 LibGfx+LibWeb: Extract bitmap-to-buffer conversion into LibGfx
This factors the conversion logic to be independent from WebGL code,
allowing us to write unit tests for it that can run in CI (since WebGL
can't run in CI).
2025-11-28 18:32:48 +01:00
Jelle Raaijmakers
3b7eede694 LibGfx: Report premultiplied alpha type for opaque Skia surfaces
We don't discern between opaque and non-opaque alpha types in LibGfx,
which at some point we might need to do. But for now, assume all opaque
Skia surfaces have premultiplied alpha.

Fixes #6892.
2025-11-26 09:24:38 +01:00
Jelle Raaijmakers
bf517f9ac2 LibGfx+LibWeb: Convert bitmap alpha type when creating ImmutableBitmaps
When decoding data into bitmaps, we end up with different alpha types
(premultiplied vs. unpremultiplied color data). Unfortunately, Skia only
seems to handle premultiplied color data well when scaling bitmaps with
an alpha channel. This might be due to Skia historically only supporting
premultiplied color blending, with unpremultiplied support having been
added more recently.

When using Skia to blend bitmaps, we need the color data to be
premultiplied. ImmutableBitmap gains a new method to enforce the alpha
type to be used, which is now used by SharedResourceRequest and
CanvasRenderingContext2D to enforce the right alpha type.

Our LibWeb tests actually had a couple of screenshot tests that exposed
the graphical glitches caused by Skia; see the big smiley faces in the
CSS backgrounds tests for example. The failing tests are now updated to
accommodate the new behavior.

Chromium and Firefox both seem to apply the same behavior; e.g. they
actively decode PNGs (which are unpremultiplied in nature) to a
premultiplied bitmap.

Fixes #3691.
2025-03-22 17:49:38 +01:00
Lucas CHOLLET
bd93285811 LibGfx+LibWeb: Do some color management on images with an ICC profile
This patch introduces the `Gfx::ColorSpace` class, this is basically a
serializable wrapper for skia's SkColorSpace. Creation of the instances
of this class (and thus ICC profiles parsing) is performed in the
ImageDecoder process. Then the object is serialized and sent through
IPC, to finally be handed to skia for rendering.

However, to make sure that we're not making all LibGfx's users dependent
on Skia as well, we need to ensure the `Gfx::ColorSpace` object has no
dependency on objects from Skia. To that end, the only member of the
`ColorSpace` class is the opaque `ColorSpaceImpl` struct. Though, there
is on issue with that design, the code in `DisplayListPlayer.cpp` needs
access to the underlying `sk_sp<SkColorSpace>`. It is provided by a
template function, that is only specialized for this type.

Doing this work allows us to pass the following WPT tests:
- https://wpt.live/css/css-color/tagged-images-001.html
- https://wpt.live/css/css-color/tagged-images-003.html
- https://wpt.live/css/css-color/tagged-images-004.html
- https://wpt.live/css/css-color/untagged-images-001.html

Other test cases can also be found here:
- https://github.com/svgeesus/PNG-ICC-tests

Note that SkColorSpace support quite a limited amount of color spaces,
so color profiles like the ones in [1] or the v4 profiles in [2] are not
supported yet. In fact, SkColorSpace only accepts skcms_ICCProfile with
a linear conversion to XYZ D50.

[1] https://www.color.org/browsertest.xalter
[2] https://www.color.org/version4html.xalter
2024-12-05 17:16:41 +01:00
Pavel Shliak
ed80e929e5 LibGfx: Sync to_skia_color_type 2024-11-18 19:17:51 +01:00
Timothy Flynn
93712b24bf Everywhere: Hoist the Libraries folder to the top-level 2024-11-10 12:50:45 +01:00