This change makes RecordingPainter to emit a FillRect command instead
of FillRectWithRoundedCorners if all corners have a radius = 0.
`fill_rect_with_rounded_corners()` in LibGfx already has a similar
optimization. But now when we also have LibAccelGfx, which does not
support painting rectangles with rounded corners yet, it makes sense to
emit FillRect whenever possible.
This change introduces a new 2D graphics library that uses OpenGL to
perform painting operations. For now, it has extremely limited
functionality and supports only rectangle painting, but we have to
start somewhere.
Since this library is intended to be used by LibWeb, where the
WebContent process does not have an associated window, painting occurs
in an offscreen buffer created using EGL.
For now it is only possible to compile this library on linux.
Offscreen context creation on SerenityOS and MacOS will have to be
implemented separately in the future.
Co-Authored-By: Andreas Kling <awesomekling@gmail.com>
Since all conditional instructions use a certain number of bits to
encode the condition type (from my observation of `Jcc`, `SETcc` and
`CMOVcc`), let's abuse that to deduplicate some code!
This adds a `Condition` enum that defines the type of condition we are
jumping based on, whose underlying values are the values that must be
encoded to trigger each condition.
The `test` instruction will have the same result as `cmp` when
comparing to zero, so let's always emit that code. This has no effect
until the following commit.
Passing a value of a type different than number or length-percentage
to transform-origin returned a null pointer, and we didn't take care
of that path before.
This patch fixes a crash caused by an incorrect CSS declaration, such as
`transform-origin: "center"`.
Fixes#21609
After 4318bcf447 RecordingPainter
is suppoed to write commands in coordinate system of stacking context.
This commit adds missing translation for FillRect command.
This clears the handler pointer of the current unwind context
before jumping to it. This is necessary to not loop infinitely
when an exception is thrown from the handler.
In that case control flow should go to the finalizer instead.
This mirrors how unwind_context.handler_called is used in the
Bytecode::Interpreter.
`try { throw 1 } catch (e) { throw 2 } finally {}` now runs
without looping infinitely in the catch block.
Instead of emitting the lengthy exception checking/handling routine,
we only emit code for checking the presence of an exception and jump
to a common exception handler.
This code size optimization saves 2.08MiB on Kraken/ai-astar.js
The cxx_new_* functions have the exact same signature as the underlying
function they redirect to, so there's no need for them. Removing them
saves us a couple of opcodes.
This allows us to use the displacement-less MOV encoding when accessing
register $0 (the accumulator).
This reduces code size by 158 KiB on Kraken/ai-astar.js :^)
This is a subset of #21484: Type 2 CFFs never use the special subrs,
so stop doing them for type 2 at least for now.
Fixes an assert in 0000064.pdf in 0000.zip in the pdfa dataset
(a stack underflow because a subr is supposed to push a bunch of
stuff, but instead it ran one of the built-in routines instead of
the subr from the font file).
As discussed in #21484, this isn't right for type 1 CFFs either,
but just removing the code there regresses Tests/LibPDF/type1.pdf.
A slightly more involved thing is needed there; I added a FIXME
for that here.
Previously, an xref stream with a field with larger than 8 would
result in an undefined shift occurring. We now ensure that each field
width is a number and is less than or equal to 8.
The current helpers assume that a valid URL is a full URL (i.e. contains
the "://" separator between the scheme and domain). This isn't true, as
"file:" alone is parsed as a valid URL.
We must also avoid simply searching for the parsed public suffix in the
original URL string. For example, "com" is a public suffix. If we search
for that in the URL "com.com", we will think the public suffix starts at
index 0.
Instead of pushing and popping every single caller-saved registers,
we can optimize code size (and speed!) by only pushing the one register
we actually care about: RDI (since it holds our VM&).
This means that native calls may clobber every other caller-saved
register, so this is something that you have to be aware of when
emitting native calls in the JIT.
This reduces code size on Kraken/ai-astar.js by 553 KiB and makes
execution time ~6% faster as well! :^)
Instead of JIT::Assembler making the decision for everyone and forcing
out every caller-saved register in the ABI onto the stack, we now leave
that decision to users of JIT::Assembler.
Instead of emitting the "restore callee-saved registers and return"
sequence again and again, just emit it once at the end of the generated
code, and have everyone jump to it.
This is a code size optimization that saves 207KiB on Kraken/ai-astar.js