1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 06:58:11 +00:00
Commit graph

618 commits

Author SHA1 Message Date
Shannon Booth
88f8ea7c60 LibWeb: Make BrowsingContex::page() return a Page&
This exposed a whole slew of now-unnecessary null checks. :^)

Co-Authored-By: Andreas Kling <kling@serenityos.org>
2023-12-05 09:38:32 +01:00
Aliaksandr Kalenik
5c0cd0f484 LibAccelGfx+LibWeb: Add text shadow support in GPU painter 2023-12-05 09:09:56 +01:00
Aliaksandr Kalenik
b5f9c1d003 LibWeb: Use glyph run to represent text in PaintTextShadow command
Given that we have a glyph run where the position of each glyph is
calculated for text fragments during layout, we can reuse it to avoid
this work during painting.
2023-12-05 09:09:56 +01:00
Aliaksandr Kalenik
f93cab7679 LibWeb/Painting: Use scaled font for selected text
Fixes regression introduced in:
681771d210
2023-12-03 23:16:17 +01:00
Aliaksandr Kalenik
681771d210 LibGfx+LibWeb: Calculate and save glyph positions during layout
Previously, we determined the positions of glyphs for each text run at
the time of painting, which constituted a significant portion of the
painting process according to profiles. However, since we already go
through each glyph to figure out the width of each fragment during
layout, we can simultaneously gather data about the position of each
glyph in the layout phase and utilize this information in the painting
phase.

I had to update expectations for a couple of reference tests. These
updates are due to the fact that we now measure glyph positions during
layout using a 1x font, and then linearly scale each glyph's position
to device pixels during painting. This approach should be acceptable,
considering we measure a fragment's width and height with an unscaled
font during layout.
2023-12-02 22:06:11 +01:00
Aliaksandr Kalenik
cc2008ea0d LibWeb: Skip painting of empty stacking contexts in GPU painter
Fixes crashing on https://twinings.co.uk/ that was happening because
of 0 size texture allocation.
2023-12-01 09:28:10 +01:00
Aliaksandr Kalenik
c28f6828c9 LibAccelGfx+LibWeb: Support non-translation transforms in GPU painter
This change introduces GPU painter support for rotate(), skew(),
scale(), and other transformations that could be applied to stacking
context.
2023-12-01 09:28:10 +01:00
Aliaksandr Kalenik
504aef470a LibWeb: Restore painter state if push_stacking_context() has failed
If `SkipStackingContext` is returned we also need to restore saved
painter state because corresponding pop_stacking_context command that
is supposed to do that will be skipped.

Fixes https://github.com/SerenityOS/serenity/issues/22092
2023-11-30 10:32:33 +01:00
Aliaksandr Kalenik
7a0191cbe9 LibWeb: Clear texture allocated for stacking context painting
In OpenGL newly allocated texture has undefined initial state so we
need to clear it before stacking context painting.
2023-11-29 21:49:23 +01:00
Aliaksandr Kalenik
24da32c884 LibAccelGfx+LibWeb: Store state of all stacking contexts in GPU painter
This change ensures that the GPU painting executor follows the pattern
of the CPU executor, where the state is stored for each stacking
context, but a painter is created only for those with opacity.

Fixes crashing on apple.com because now save() and restore() are called
on correct painters.
2023-11-29 21:48:47 +01:00
Aliaksandr Kalenik
9fa6628efa LibWeb: Apply stacking context transform in GPU painter 2023-11-29 09:48:10 +01:00
Shannon Booth
56d10bf198 LibWeb: Port Layout::TextNode from DeprecatedString 2023-11-28 17:15:27 -05:00
Aliaksandr Kalenik
1b3223dd9e LibWeb: Rename painter() to recording_painter() in PaintContext
Using recording_painter() as a name is less misleading, indicating
the painter in stacking context traversal doesn't perform actual
painting commands.
2023-11-27 21:53:38 +01:00
Aliaksandr Kalenik
0ff977bd04 LibWeb: Add fixed position stacking context support in GPU painter 2023-11-27 17:26:39 +01:00
Aliaksandr Kalenik
17fb82d49b LibAccelGfx+LibWeb: Discard painting of commands outside of viewport 2023-11-26 21:26:26 +01:00
Aliaksandr Kalenik
28723d8be1 LibAccelGfx+LibWeb: Move glyph atlas into a singleton class
This is going to allow us reuse glyph texture across painters and page
repaints.
2023-11-26 21:26:26 +01:00
Aliaksandr Kalenik
a1c8fb10fa LibAccelGfx+LibWeb: Add texture cache for immutable bitmaps
This change introduces a texture cache for immutable bitmaps in the
GPU painter. The cache is persisted across page repaints, so now, on
page scroll repaint, in many cases, we won't need to upload any new
textures. Also, if the same image is painted more than once on a page,
its texture will only be uploaded once.

Generally, the GPU painter works much faster with this change on all
pages that have images.
2023-11-26 12:55:43 +01:00
Aliaksandr Kalenik
f4a5c136c3 LibGfx+LibWeb: Add ImmutableBitmap for images bitmap caching in painter
Before this change, we used Gfx::Bitmap to represent both decoded
images that are not going to be mutated and bitmaps corresponding
to canvases that could be mutated.

This change introduces a wrapper for bitmaps that are not going to be
mutated, so the painter could do caching: texture caching in the case
of GPU painter and potentially scaled bitmap caching in the case of CPU
painter.
2023-11-26 12:55:43 +01:00
Aliaksandr Kalenik
5f7ac559a7 LibAccelGfx+LibWeb: Add support for stacking context opacity
For each stacking context with an opacity less than 1, we create a
separate framebuffer. We then blit the texture attached to this
framebuffer with the specified opacity.

To avoid the performance overhead of reading pixels from the texture
into Gfx::Bitmap, a new method that allows for direct blitting from
the texture is introduced, named blit_scaled_texture().
2023-11-24 08:39:55 +01:00
Aliaksandr Kalenik
d9990c6ea9 LibWeb: Remove opacity parameter for DrawScaledBitmap painting command
Every usage of this command specifies opacity equal to 1.
2023-11-21 17:00:56 +01:00
Aliaksandr Kalenik
a5cf875e23 LibWeb: Fix typo in FillEllipse painting command name 2023-11-21 17:00:56 +01:00
Aliaksandr Kalenik
2471f07356 LibWeb: Skip painting of empty borders in GPU painter 2023-11-21 17:00:56 +01:00
Aliaksandr Kalenik
01058dac95 LibWeb: Skip execution of painting commands with empty bounding rect 2023-11-21 17:00:56 +01:00
Aliaksandr Kalenik
1b0cc67a28 LibAccelGfx+LibWeb: Add basic push/pop stacking context implementation
With basic PushStackingContext and PopStackingContext commands
implementation scrolling works again after changes being made in:
4e04f81626
2023-11-20 23:44:19 +01:00
Aliaksandr Kalenik
7320fdc1f5 LibWeb: Implement FillEllipse command for GPU executor 2023-11-20 20:08:41 +01:00
Aliaksandr Kalenik
53c015695e LibAccelGfx+LibWeb: Implement rounded corners rectangle painting
For now corners antialiasing is missing.
2023-11-20 19:35:25 +01:00
Aliaksandr Kalenik
9888db1c27 LibWeb: Add basic support for borders painting in GPU executor
For now all borders are painted without rounded corners.
2023-11-20 14:59:47 +01:00
Aliaksandr Kalenik
29ff1f67be LibWeb: Introduce dedicated painting command for borders
Currently, in CPU painter, border painting is implemented by building
a Gfx::Path that is filled by Gfx::AntiAliasingPainter. In the GPU
painter, we will likely want to do something different, and with a
special command, it becomes possible.

Also, by making this change, the CPU executor also benefits because now
we can skip building paths for borders that are out of the viewport.
2023-11-20 14:59:47 +01:00
Aliaksandr Kalenik
70353b79af LibWeb: Change paint_all_borders() to accept only device pixel values
By consistently accepting only device pixel values instead of a mix of
CSSPixels and DevicePixels values, we can simplify the implementation
of paint_border() and paint_all_borders().
2023-11-20 14:59:47 +01:00
MacDue
4e04f81626 LibWeb: Don't encode painting limitations in RecordingPainter API
The current set of stacking context commands do not encode the
information needed to correctly paint the stacking context, instead,
they're based on the limitations of the current CPU renderer.

Stacking contexts should be able to be transformed by an arbitrary
3D transformation matrix, not just scaled from a source to a destination
rect. The `_with_mask()` stacking context also should not be separate
from the regular stacking context.

```c++
push_stacking_context(
	bool semitransparent_or_has_non_identity_transform,
	float opacity, Gfx::FloatRect const& source_rect,
	Gfx::FloatRect const& transformed_destination_rect,
	Gfx::IntPoint const& painter_location);

pop_stacking_context(
	bool semitransparent_or_has_non_identity_transform,
	Gfx::Painter::ScalingMode scaling_mode);

push_stacking_context_with_mask(
	Gfx::IntRect const& paint_rect);

pop_stacking_context_with_mask(
	Gfx::IntRect const& paint_rect,
	RefPtr<Gfx::Bitmap> const& mask_bitmap,
	Gfx::Bitmap::MaskKind mask_kind, float opacity);
```

This patch replaces this APIs with just:

```c++
push_stacking_context(
	float opacity,
        bool is_fixed_position,
        Gfx::IntRect const& source_paintable_rect,
	Gfx::IntPoint post_transform_translation,
	CSS::ImageRendering image_rendering,
	StackingContextTransform transform,
	Optional<StackingContextMask> mask);

pop_stacking_context()
```

And moves the implementation details into the executor, this should
allow future backends to implement stacking contexts without these
limitations.
2023-11-18 19:32:31 +01:00
Aliaksandr Kalenik
f6a9f613c7 LibAccelGfx+LibWeb: Add basic support for linear gradients painting
Linear gradient painting is implemented in the following way:
1. The rectangle is divided into segments where each segment represents
   a simple linear gradient between an adjacent pair of stops.
2. Each quad is filled separately using a fragment shader that
   interpolates between two colors.

For now `angle` and `repeat_length` parameters are ignored.
2023-11-16 18:02:51 +01:00
Aliaksandr Kalenik
01d938c77b LibAccelGfx+LibWeb: Implement SetClipRect and ClearClipRect commands 2023-11-13 19:22:27 +01:00
Aliaksandr Kalenik
f7874d03fc LibWeb: Remove redundant flush() call in PaintingCommandExecutorGPU
Since we already call `Painter::flush()` in `PageHost::paint()` we do
not need to do that again in `PaintingCommandExecutorGPU` destructor.

This makes GPU painting run noticeably faster because `flush()` does
expensive `glReadPixels()` call.
2023-11-12 20:21:07 +01:00
Aliaksandr Kalenik
6d1a1daff9 LibAccelGfx+LibWeb: Use framebuffer object instead of EGLs PBuffer
Framebuffer object is allocated using OpenGL's API and is not platform
specific which means it could be used on both macOS and Linux unlike
EGL specific PBuffer.
2023-11-11 22:19:43 +01:00
Tim Schumacher
a2f60911fe AK: Rename GenericTraits to DefaultTraits
This feels like a more fitting name for something that provides the
default values for Traits.
2023-11-09 10:05:51 -05:00
Aliaksandr Kalenik
28118623f5 LibAccelGfx+LibWeb: Add basic line painting support
For now only solid line style is supported.
2023-11-09 10:47:31 +01:00
Aliaksandr Kalenik
fd3411c868 LibWeb: Ignore document's box during overflow clip rect calculation
Reduction of bug:
```html
<!DOCTYPE html><style>
html {
    overflow-x: hidden;
    overflow-y: scroll;
}
div {
    background: orange;
    height: 1000px;
    width: 500px;
}
</style><body><div>
```

Fixes https://github.com/SerenityOS/serenity/issues/21690 and painting
on many other websites (null.com, servo.org).
2023-11-09 07:56:34 +01:00
Sam Atkins
5cf85d30aa LibWeb: Store RadialGradientStyleValue's position as PositionStyleValue 2023-11-07 22:00:24 +00:00
Aliaksandr Kalenik
b6da9abfb2 LibWeb: Implement draw_glyph_run in PaintingCommandExecutorGPU 2023-11-06 09:53:11 +01:00
Aliaksandr Kalenik
ee28ba0c93 LibWeb: Use glyph run to store text paint command in RecordingPainter
Representing a text run panting command as a vector of glyphs, rather
than as a string simplifies collecting of unique glyphs which is a
prerequisite for `prepare_glyphs_texture()` call.
2023-11-06 09:53:11 +01:00
MacDue
4c5d48f861 LibWeb: Support transforms, stroking, gradients, etc for SVG <text>
This makes use of the new Gfx::Path::text() to handle SVG text elements,
with this text is just a regular path, and can be manipulated like any
other graphics element.

This removes the SVGTextPaintable and makes both <text> and geometry
elements use a new (shared) SVGPathPaintable. This is identical to the
old SVGGeometryPaintable. This simplifies painting as once something is
resolved to a Gfx::Path, the painting logic is the same.
2023-11-05 02:46:46 +01:00
Aliaksandr Kalenik
aa6c008450 LibAccelGfx+LibWeb: Implement draw_scaled_bitmap()
Very basic implementation of command to paint bitmap. In the future we
should reuse loaded textures across repaints whenever it is possible.
2023-11-02 07:41:51 +01:00
Aliaksandr Kalenik
1e85bf221d LibAccelGfx+WebContent: Use the same Painter across page repaints
In the upcoming changes, Painter will be used to store the state of
OpenGL context. For example, if Painter is aware of the shader that
have already been loaded, it will be possible to reuse them across
repaints. Also, it would be possible to manage state of loaded textures
and add/remove them depending on which ones are present in the next
sequence of painting commands.
2023-11-02 07:41:51 +01:00
Tobias Christiansen
e60253d64c LibWeb: Respect offsets always when painting with object-position
Previously we didn't always set the bitmap_intersect correctly when
applying an object-position. This lead to images not correctly being
centered when the axis that it should move along was not the specified
axis.
2023-10-31 07:03:05 +01:00
Tobias Christiansen
6f71b8be1b LibWeb: Use local 'offset' variable in ImagePaintable
We created the local and then did not use it everywhere we could.
2023-10-31 07:03:05 +01:00
Tobias Christiansen
3a4d30dddc LibWeb: Avoid truncation of aspect-ratio-computation in ImagePaintable
The value of the aspect ratio of the bitmap got truncated and this
lead to funky rendering problems when using object-fit and
object-position.
2023-10-31 07:03:05 +01:00
MacDue
c93d367d95 LibWeb: Layout SVG <text> elements during layout (not while painting)
Previously, all SVG <text> elements were zero-sized boxes, that were
only actually positioned and sized during painting. This led to a number
of problems, the most visible of which being that text could not be
scaled based on the viewBox.

Which this patch, <text> elements get a correctly sized layout box,
that can be hit-tested and respects the SVG viewBox.

To share code with SVGGeometryElement's the PathData (from the prior
commit) has been split into a computed path and computed transforms.
The computed path is specific to geometry elements, but the computed
transforms are shared between all SVG graphics elements.
2023-10-30 19:44:54 +01:00
MacDue
dc9cb449b1 LibWeb: Store computed SVG path data/transforms in LayoutState
This removes the awkward hack to recompute the layout transform at paint
time, and makes it possible for path sizes to be computed during layout.

For example, it's possible to use relative units in SVG shapes (e.g.
<rect>), which can be resolved during layout, but would be hard to
resolve again during painting.
2023-10-30 19:44:54 +01:00
Tobias Christiansen
647f0ccd3f LibWeb: Add rendering support for 'object-position'
Images now get rendered correctly according to the 'object-position'
property.
2023-10-30 10:40:30 +00:00
Tobias Christiansen
6602b1ddb1 LibWeb: Rename "position" enum to "positioning"
The postitioning enum values are used by the position CSS property.
Unfortunately, the prior naming clashes with the CSS Values-4 type
named position, which will be implemented in a later commit.
2023-10-30 10:40:30 +00:00