Partial Rendering refers to a rendering technique where
only a portion of the scene or screen is updated, rather
than redrawing the entire output. It is commonly used as
a performance optimization strategy, focusing on redrawing
only the regions that have changed, often called dirty regions.
This introduces RenderDirtyRegion, which assists
in collecting a compact dirty region from render tasks.
Each backend can utilize this class to support efficient partial rendering.
This is implemented using a Line Sweep and Subdivision Merging O(NlogN).
The basic per-frame workflow is as follows:
1. RenderDirtyRegion::prepare() //Call this in Renderer::preRender().
2. RenderDirtyRegion::add() //Add all dirty paints for the frame before rendering.
3. RenderDirtyRegion::commit() //Generate the partial rendering region list before rendering.
4. RenderDirtyRegion::get() //Retrieve the current dirty region list and use it when drawing paints.
5. RenderDirtyRegion::clear() //Reset the state.
issue: https://github.com/thorvg/thorvg/issues/1747
Implemented support for clipping shapes and images using a render region
bounding box at render time. This allows partial drawing of content,
laying the groundwork for upcoming partial rendering functionality.
for fast access of the drawing region from the linear rle data,
we introduced the binary search for begin/end of rle instead of
additional y index buffer.
There is a reason for not using a y-index buffer:
the shapes in the RLE are not single, continuous shapes
but multiple shapes scattered across the space.
which means that we need a double-associated data structure
per shapes for y indexing, and this data preparation wouldn't be
cheaper enough than realtime binary search especially animated data.
This also helps for current clipping performance by utilizing
the introduced fast-clipping region access.
issue: https://github.com/thorvg/thorvg/issues/1747
- Paint explicity allows a shape as a clipper
- Added clipper getter apis
API Updates
+ Shape* Paint::clip()
* Result Paint::clip(Paint* clipper) -> Result Paint::clip(Shape* clipper)
CAPI Updates
+ Tvg_Paint* tvg_paint_get_clip(const Tvg_Paint* paint)
* Tvg_Result tvg_paint_clip(Tvg_Paint* paint, Tvg_Paint* clipper)
-> Tvg_Result tvg_paint_set_clip(Tvg_Paint* paint, Tvg_Paint* clipper);
Please note that clipper type can be changed again to tvg::Path
in the upcoming update.
This commit has two purposes:
- refactoring to introduce y indexing method for the upcoming partial rendering.
- replaces the RLE-specific memory allocation with a shared array structure,
eliminating potential memory overflows during RLE clipping.
redefiend properties so that min/max are prioritized,
as they are accessed more frequently than pos/size
during rendering calculations.
also introduced miscellaneous functions to improve usability.
This allow more generous handling of failure cases for invalid content,
thorvg can draw other successful contents.
Now, only raster engines can return fail cases in the picture.
A precomposition layer is clipped to its viewport.
If the same layer also had a mask that was optimized
using clipping, this clip was unintentionally overridden
by the viewport clipping. This conflict is now fixed.
In some clipping cases, the memory allocated for storing spans
was too small. As a result, the entire clipped area might not
have been rendered.
This has been resolved by adding an experimental factor to increase
the size of allocated memory.
@issue: https://github.com/thorvg/thorvg/issues/3461
If stop is declared immediately after Gradient is closed, the stop is registered in latestGradient.
Change latestGradient to a Stack and add a stop only to the last added gradient.
When that gradient is closed, no more stops should be registered for that gradient.
And gradients do not allow nested declarations, so only the earliest declared Gradient is valid.
The time remapping logic had an issue where animations with zero value "tm"(Time Remap) were not being processed correctly.
This was happening because the previous implementation only applied time remapping when the value was non-zero. (A zero-value Time Remap should be applied, but is ignored)
The fix changes the default time remap value to `-1.0` (since frame values cannot be negative) and applies time remapping when the value is 0.0 or greater. This ensures that zero value time remapping is properly processed.
The first margin value shifts the starting point where the text
begins along the path. Now cases where firstMargin < 0 are handled,
for both closed and open paths.
Added drawing exceptions when target is not properly ready.
Now, Canvas::update() Canvas::draw() will return InsufficientCondition
if the target has not been set beforehand.
The "s" key does not have to appear at the beginning
of the position block. Previously, such cases would
result in a parsing error — now they are handled correctly.
no any 3rd-party libs, such as glfw or glad did not used
support windows, linux, macos and emsdk
only the actually used set of functions are loaded
Co-Authored-By: Sergii Liebodkin <sergii@lottiefiles.com>
Co-Authored-BY: Hermet Park <hermet@lottiefiles.com>
issue: https://github.com/thorvg/thorvg/issues/2453
- prioritize valid (positive) cases first
- continue parsing even when encountering parsing errors
Co-Authored-By: Mira Grudzinska <mira@lottiefiles.com>
revert the alpha skip condition introduced in
commit 2990e72b23.
color values with alpha = 0 must be transformed to 0
to ensure correct intermediate composition results.