Hermet Park
407fc84796
common: spec out Scene Clipper
...
Scene Clipper is an unusual feature
that is too unstable and ambiguous in ThorVG.
Users can achieve the same functionality
with multiple composed shapes instead of scene clipping.
size: -2.5kb
issues:
- https://github.com/thorvg/thorvg/issues/1548
- https://github.com/thorvg/thorvg/issues/1549
- https://github.com/thorvg/thorvg/issues/1573
2024-08-13 10:21:54 +09:00
Sergii Liebodkin
a4bbf14371
wg_engine: composition and blend optimization
...
* bind groups creation in real time removed - performance boost
* blend and composition shaders decomposed - performance boost
* shader modules and pipeline layouts generalized - less memory usage
* shared single stencil buffer used - less memory usage
* bind groups usage simplified
* general context API simplified and generalized
* all rendering logic moved into new composition class
* ready for hardware MSAA (in next steps)
* ready for direct mask applience (in next steps)
2024-08-09 14:30:17 +09:00
Sergii Liebodkin
6cd745dd2e
wg_engine: emscripten and browser support
...
[issues 2410: emscripten support](https://github.com/thorvg/thorvg/issues/2410 )
- Research and prototype the Emscripten build with WebGPU.
meson setup script:
meson setup builddir -Ddefault_library=static -Dloaders=all -Dsavers="all" -Dbindings="wasm_beta" -Dengines="wg_beta" --cross-file ./cross/wasm_webgpu.txt
2024-08-01 14:20:08 +09:00
Hermet Park
036ae3c2af
renderer: code refactoring
...
Replaced the transformation with
a strong associated data field.
This helps to reduce the binary size (-1k).
2024-07-29 23:27:19 +09:00
Hermet Park
c4d89d0983
common: code refactoring
...
Trimming the transform data pass,
from RenderTransform to Matrix.
No logical changes.
2024-07-29 12:16:58 +09:00
Sergii Liebodkin
2c948a33d3
wg_engine: ClipPath support
...
[issues 1479: ClipPath](#1479 )
Supports ClipPath composition.
Clip path composition is an only composition type who doesn't ignore blend method.
Clip path is a combination of composition approach and blend approach using compute shader
2024-07-16 00:01:47 +09:00
Sergii Liebodkin
3223f17f9c
wg_engine: Viewport support
...
[issues 1479: Viewport](#1479 )
Supports viewport settings and rectangular clip path.
Scissors cliping used as a way to clip viewport
2024-07-11 21:24:18 +09:00
Hermet Park
8be44e66d2
wg_engine: code refactoring
...
- apply thorvg compact coding style.
- separate private / public methods designated in sectors.
2024-07-06 11:37:57 +09:00
Sergii Liebodkin
1932107097
wg_engine: fix dispose render data in MT environment
...
Store desposed object in MT-safe list and then despose objects in sync stage
2024-07-06 11:22:30 +09:00
Sergii Liebodkin
e7e6839571
wg_engine: fix blend methods support
...
Full review of blending support.
Support Solid color, Gradient fill and Image blending workflows
See Blending, SceneBlending, Opacity examples
2024-07-04 16:19:50 +09:00
Hermet Park
846ae09151
wg_engine: --redundant code
2024-06-17 15:59:53 +09:00
Sergii Liebodkin
7e493f91f2
wg_engine: cross-platform support
...
it provide changes public API for webgpu canvas interface to provide nessessary handles to native window for different platforms:
API Change:
- Result target(void *instance, void *surface, uint32_t w, uint32_t h) noexcept;
2024-06-12 12:39:37 +09:00
Hermet Park
7e5800df89
renderer/engines: added mainSurface() interface.
...
This interface expects the main surface of the raster engine.
2024-05-18 18:10:50 +09:00
Hermet Park
03d2505b0a
wg_engine: code refactoring
...
Use the override specifier so that
a compiler could warn any human mistake.
2024-05-14 17:14:32 +09:00
Sergii Liebodkin
392f59db9d
wg_engine: vertex, index and unifroms buffers, render objects caching
...
[issues 1479: lottie](#1479 )
Vertex, Index and uniform buffers now updates instead of recreate.
Implemented pools form mesh objects and render shapes data
it increase performance in 30-40% in massive animations scenes
2024-04-05 11:40:57 +09:00
Sergii Liebodkin
b0280150db
wg_engine: Blending optimization
...
[issues 1479: lottie](#1479 )
To optimize bled operations hardware pipeline blend stage are used for some blend methods:
BlendMethod::SrcOver
BlendMethod::Normal
BlendMethod::Add
BlendMethod::Multiply
BlendMethod::Darken
BlendMethod::Lighten
Other types compute shaders used
2024-04-04 11:03:59 +09:00
Sergii Liebodkin
1794ec0924
wg_engine: antialiasing
...
[issues 1479: antialiasing](#1479 )
Anti-aliasing implementation
Implements antialiasing as a post process on cimpute shaders and original render target with scale of 2x.
Can be modified as an external settings
2024-03-04 19:33:34 +09:00
Hermet Park
a1c43a9518
renderer: code refactoring.
...
removed unnused return value.
2024-02-02 03:02:56 +09:00
Sergii Liebodkin
6b6947f679
wg_engine: introduced blending
...
[issues 1479: blending](#1479 )
Supported blend settings:
Normal
Add
Screen
Multiply
Overlay
Difference
Exclusion
SrcOver
Darken
Lighten
ColorDodge
ColorBurn
HardLight
SoftLight
2024-01-30 11:49:20 +09:00
Sergii Liebodkin
4f528d45f5
wg_engine: introduced compute pipeline entities
...
introduces posibility to create compute pipelines
does not affect functionality
2024-01-23 18:08:26 +09:00
Sergii Liebodkin
edd8756b73
wg_engine: introduced scene opacity
...
[issues 1479: opacity](#1479 )
Supported opacity value for scene
Usage example:
//Create a Scene
auto scene = tvg::Scene::gen();
scene->opacity(100);
//Prepare Circle
auto shape1 = tvg::Shape::gen();
shape1->appendCircle(400, 400, 250, 250);
shape1->fill(255, 255, 0);
shape1->opacity(100);
scene->push(std::move(shape1));
//Round rectangle
auto shape2 = tvg::Shape::gen();
shape2->appendRect(450, 100, 200, 200, 50, 50);
shape2->fill(0, 255, 0);
shape2->strokeWidth(10);
shape2->strokeFill(255, 255, 255);
scene->push(std::move(shape2));
canvas->push(std::move(scene));
2024-01-18 18:00:08 +09:00
Sergii Liebodkin
45368c319e
wg_engine: introduced composition ability
...
[issues 1479: Masking](#1479 )
Supported composition methods:
AlphaMask
InvAlphaMask
LumaMask
InvLumaMask
AddMask
SubtractMask
IntersectMask
DifferenceMask
Usage example:
//Solid Rectangle
auto shape = tvg::Shape::gen();
shape->appendRect(0, 0, 400, 400);
shape->fill(0, 0, 255);
//Mask
auto mask = tvg::Shape::gen();
mask->appendCircle(200, 200, 125, 125);
mask->fill(255, 255, 255); //AlphaMask RGB channels are unused.
//Nested Mask
auto nMask = tvg::Shape::gen();
nMask->appendCircle(220, 220, 125, 125);
nMask->fill(255, 255, 255); //AlphaMask RGB channels are unused.
mask->composite(std::move(nMask), tvg::CompositeMethod::AlphaMask);
shape->composite(std::move(mask), tvg::CompositeMethod::AlphaMask);
canvas->push(std::move(shape));
//Star
auto star = tvg::Shape::gen();
star->fill(80, 80, 80);
star->moveTo(599, 34);
star->lineTo(653, 143);
star->lineTo(774, 160);
star->lineTo(687, 244);
star->lineTo(707, 365);
star->lineTo(599, 309);
star->lineTo(497, 365);
star->lineTo(512, 245);
star->lineTo(426, 161);
star->lineTo(546, 143);
star->close();
star->strokeWidth(30);
star->strokeJoin(tvg::StrokeJoin::Miter);
star->strokeFill(255, 255, 255);
//Mask3
auto mask3 = tvg::Shape::gen();
mask3->appendCircle(600, 200, 125, 125);
mask3->fill(255, 255, 255); //AlphaMask RGB channels are unused.
mask3->opacity(200);
star->composite(std::move(mask3), tvg::CompositeMethod::AlphaMask);
if (canvas->push(std::move(star)) != tvg::Result::Success) return;
2024-01-15 17:33:59 +09:00
Hermet Park
468b132739
renderer: enhanced shared surface handling with mutex implementation
...
Introduced a dedicated mutex for each surface instance
to ensure safe sharing between the loader, renderer, and engine.
This enhancement allows for secure modification and access to bitmap data,
addressing potential concurrency issues.
Multiple Picture instances can now safely share a single loader instance,
optimizing performance.
This change builds upon the previous Loader Cache improvements:
ff6ea4b6c4
2023-12-31 11:37:12 +09:00
Jinny You
2c6c8d3b21
updated copyright date ( #1866 )
2023-12-28 10:43:25 +09:00
Sergii Liebodkin
93f0e493ac
wg_engine: refactor context handles
...
New approach provide:
- instance, adaptor, device and default queue
- device capabilitieas
- command buffer executor
- error handling
2023-12-20 10:43:18 +09:00
Sergii Liebodkin
1a6571f596
wg_engine: refactor render targets handling
...
For further development of features, we need to create off-screen buffers that will allow us to implement functionality related to composition and blending, as well as for loading data to system memory from the framebuffer. Separating the framebuffer into a separate entity allows you to create several instances of them, switch between them, and blend them according to given rules.
For current time we have only a single render target instance, that have a handle to drawing into surface surface, like a native window.
New approach allows:
- offscreen rendering
- render pass handling
- switching between render targets
- ability to render images, strokes and shapes into independent render targets
2023-12-20 01:33:23 +09:00
Hermet Park
9d06308207
wg_engine: apply tvg coding style.
2023-12-18 23:34:13 +09:00
Sergii Liebodkin
e2458570f8
wg_engine: pipelines and bind groups refactoring
...
- shader and system types synchronized
- pipelens and bind groups description separated
- pipelines description simplified
2023-12-18 22:45:13 +09:00
Sergii Liebodkin
548962f5f8
apis/engines: Revise the clear() buffer behavior.
...
ThorVG has offered an option to clear the buffer since version 1.0.
This is essential when users utilize the canvas target buffer
with the main render target. They share the buffer
and need to draw contents onto the existing contents.
API:
Result Canvas::clear(bool free = true)
-> Result Canvas::clear(bool paints = true, bool buffer = true)
Tvg_Result tvg_canvas_clear(Tvg_Canvas* canvas, bool free);
-> Tvg_Result tvg_canvas_clear(Tvg_Canvas* canvas, bool paints, bool buffer);
Issue: https://github.com/thorvg/thorvg/issues/1779
Co-Authored-By: Hermet Park <hermet@lottiefiles.com>
2023-11-20 18:23:00 +09:00
Sergii Liebodkin
25513b591a
wg_engine: introduced images drawing support
...
[issues 1479: pictures](https://github.com/thorvg/thorvg/issues/1479 )
auto picture = tvg::Picture::gen();
picture->load("images/test.png");
picture->translate(0, 0);
picture->size(100, 100);
picture->opacity(255);
canvas->push(std::move(picture));
2023-11-17 19:34:32 +09:00
Sergii Liebodkin
a3adbef2c2
Added ability to draw solid strokes
...
[issues 1479: Shape](https://github.com/thorvg/thorvg/issues/1479 )
In order to build you need third party libraries. Before you start please read this: [LearnWebGPU](https://eliemichel.github.io/LearnWebGPU/getting-started/hello-webgpu.html )
Usage example:
// init glfw
glfwInit();
// create a windowed mode window and its opengl context
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
GLFWwindow* window = glfwCreateWindow(800, 800, "WebGPU base app", nullptr, nullptr);
// get window size
int width{}, height{};
glfwGetWindowSize(window, &width, &height);
// init engine webgpu
tvg::Initializer::init(tvg::CanvasEngine::Wg, 0);
// create wg canvas
auto canvasWg = tvg::WgCanvas::gen();
canvas_wg->target(glfwGetWin32Window(window), width, height);
//Test for Stroke Dash for Arc, Circle, Rect
auto shape = tvg::Shape::gen();
shape->appendArc(70, 600, 160, 10, 30, true);
shape->appendCircle(70, 700, 20, 60);
shape->appendRect(130, 710, 100, 40);
shape->strokeFill(255, 0, 0);
shape->strokeWidth(5);
shape->strokeJoin(tvg::StrokeJoin::Round);
shape->strokeCap(tvg::StrokeCap::Round);
if (canvas_wg->push(std::move(shape)) != tvg::Result::Success) return;
while (!glfwWindowShouldClose(window)) {
// webgpu
canvas_wg->draw();
canvas_wg->sync();
// pull events
glfwPollEvents();
}
// terminate engine and window
tvg::Initializer::term(tvg::CanvasEngine::Wg);
glfwDestroyWindow(window);
glfwTerminate();
2023-11-06 20:35:26 +09:00
SergeyLebedkin
8200bc5fc3
wg_engine: Added a feature to draw multiple radial gradient filled shapes
2023-10-24 18:24:16 +09:00
Sergii Liebodkin
94eabc609c
wg_engine: Added ability to draw multiple linear gradient filled shapes
...
[issues 1479: LinearGradient](thorvg#1479)
In order to build you need third party libraries. Before you start please read this: [LearnWebGPU](https://eliemichel.github.io/LearnWebGPU/getting-started/hello-webgpu.html )
Usage example:
// init glfw
glfwInit();
// create a windowed mode window and its opengl context
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
GLFWwindow* window = glfwCreateWindow(800, 800, "WebGPU base app", nullptr, nullptr);
// get window size
int width{}, height{};
glfwGetWindowSize(window, &width, &height);
// init engine webgpu
tvg::Initializer::init(tvg::CanvasEngine::Wg, 0);
// create wg canvas
auto canvasWg = tvg::WgCanvas::gen();
canvas_wg->target(glfwGetWin32Window(window), width, height);
// gradient color stops
tvg::Fill::ColorStop colorStops[2];
colorStops[0] = {0, 0, 0, 0, 255};
colorStops[1] = {1, 255, 255, 255, 255};
// linear gradient
auto fill = tvg::LinearGradient::gen();
fill->linear(0, 0, 400, 400);
fill->colorStops(colorStops, 2);
// prepare rectangle
auto shape1 = tvg::Shape::gen();
shape1->appendRect(0, 0, 400, 400); //x, y, w, h
shape1->fill(std::move(fill));
canvas_wg->push(std::move(shape1));
// gradient color stops
tvg::Fill::ColorStop colorStops2[3];
colorStops2[0] = { 0, 255, 0, 0, 255 };
colorStops2[1] = { 0.5, 255, 255, 0, 255 };
colorStops2[2] = { 1, 255, 255, 255, 255 };
// linear gradient
auto fill2 = tvg::LinearGradient::gen();
fill2->linear(400, 200, 400, 600);
fill2->colorStops(colorStops2, 3);
// prepare circle
auto shape2 = tvg::Shape::gen();
shape2->appendCircle(400, 400, 200, 200); //cx, cy, radiusW, radiusH
shape2->fill(std::move(fill2));
canvas_wg->push(std::move(shape2));
// gradient color stops
tvg::Fill::ColorStop colorStops3[4];
colorStops3[0] = { 0, 0, 127, 0, 127 };
colorStops3[1] = { 0.25, 0, 170, 170, 170 };
colorStops3[2] = { 0.5, 200, 0, 200, 200 };
colorStops3[3] = { 1, 255, 255, 255, 255 };
// linear gradient
auto fill3 = tvg::LinearGradient::gen();
fill3->linear(450, 600, 750, 600);
fill3->colorStops(colorStops3, 4);
// prepare ellipse
auto shape3 = tvg::Shape::gen();
shape3->appendCircle(600, 600, 150, 100); //cx, cy, radiusW, radiusH
shape3->fill(std::move(fill3));
canvas_wg->push(std::move(shape3));
while (!glfwWindowShouldClose(window)) {
// webgpu
canvas_wg->draw();
canvas_wg->sync();
// pull events
glfwPollEvents();
}
// terminate engine and window
tvg::Initializer::term(tvg::CanvasEngine::Wg);
glfwDestroyWindow(window);
glfwTerminate();
2023-10-23 18:05:56 +09:00
Sergii Liebodkin
14b2508cd1
wg_engine: Added ability to draw multiple solid color filled shapes
...
[issues 1479: Shape](https://github.com/thorvg/thorvg/issues/1479 )
In order to build you need third party libraries. Before you start please read this: [LearnWebGPU](https://eliemichel.github.io/LearnWebGPU/getting-started/hello-webgpu.html )
Usage example:
// init glfw
glfwInit();
// create a windowed mode window and its opengl context
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
GLFWwindow* window = glfwCreateWindow(800, 800, "WebGPU base app", nullptr, nullptr);
// get window size
int width{}, height{};
glfwGetWindowSize(window, &width, &height);
// init engine webgpu
tvg::Initializer::init(tvg::CanvasEngine::Wg, 0);
// create wg canvas
auto canvasWg = tvg::WgCanvas::gen();
canvas_wg->target(glfwGetWin32Window(window), width, height);
// prepare a shape (Rectangle + Rectangle + Circle + Circle)
auto shape1 = tvg::Shape::gen();
shape1->appendRect(0, 0, 200, 200); //x, y, w, h
shape1->appendRect(100, 100, 300, 300, 100, 100); //x, y, w, h, rx, ry
shape1->appendCircle(400, 400, 100, 100); //cx, cy, radiusW, radiusH
shape1->appendCircle(400, 500, 170, 100); //cx, cy, radiusW, radiusH
shape1->fill(255, 255, 0); //r, g, b
canvas_wg->push(std::move(shape1));
while (!glfwWindowShouldClose(window)) {
// webgpu
canvas_wg->draw();
canvas_wg->sync();
// pull events
glfwPollEvents();
}
// terminate engine and window
tvg::Initializer::term(tvg::CanvasEngine::Wg);
glfwDestroyWindow(window);
glfwTerminate();
2023-10-20 18:37:52 +09:00
SergeyLebedkin
8d5c728119
wg_engine: introduce a webgpu canvas(engine)
...
WebGPU is a Render Hardware Interface built on top of the various APIs
provided by the driver/OS depending on your platform.
WebGPU exposes an API for performing operations,
such as rendering and computation, on a Graphics Processing Unit.
WebGPU official documentation: https://www.w3.org/TR/webgpu/
The new engine type introduced: tvg::CanvasEngine::Wg
The new canvas type introduced: tvg::WgCanvas
Example:
$meson setup build -Dengines=wg_beta
`
// init engine webgpu
tvg::Initializer::init(tvg::CanvasEngine::Wg, 0);
// create wg canvas
auto canvasWg = tvg::WgCanvas::gen();
canvas_wg->target(glfwGetWin32Window(window), width, height);
// ...
// terminate engine and window
tvg::Initializer::term(tvg::CanvasEngine::Wg);
`
Still this feature is under the beta
Issue: https://github.com/thorvg/thorvg/issues/1479
2023-10-13 22:59:32 +09:00