Commit graph

29 commits

Author SHA1 Message Date
Sergii Liebodkin
03b36cea7b 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-09-30 15:35:10 +09:00
Sergii Liebodkin
f7728a8b7a 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-09-30 15:29:22 +09:00
Hermet Park
b00c55169e wg_engine: code refactoring
- apply thorvg compact coding style.
- separate private / public methods designated in sectors.
2024-09-30 12:56:51 +09:00
Sergii Liebodkin
a49a15af75 wg_engine: fix dispose render data in MT environment
Store desposed object in MT-safe list and then despose objects in sync stage
2024-09-30 12:56:45 +09:00
Sergii Liebodkin
e27ce23d4b 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-09-30 12:51:02 +09:00
Hermet Park
7008d26d05 wg_engine: --redundant code 2024-06-24 14:54:49 +09:00
Sergii Liebodkin
47b9866f8b 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-24 14:50:28 +09:00
Hermet Park
5b3a045f15 renderer/engines: added mainSurface() interface.
This interface expects the main surface of the raster engine.
2024-06-24 14:19:43 +09:00
Hermet Park
a3fe9c25f2 wg_engine: code refactoring
Use the override specifier so that
a compiler could warn any human mistake.
2024-06-24 14:14:02 +09:00
Sergii Liebodkin
366c1be6bd 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-07 15:15:59 +09:00
Sergii Liebodkin
7d8a261a83 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-06 12:48:30 +09:00
Sergii Liebodkin
850e6ef466 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-04-06 12:08:21 +09:00
Hermet Park
6df111bc23 renderer: code refactoring.
removed unnused return value.
2024-04-05 17:46:54 +09:00
Sergii Liebodkin
9e0cc0298c 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-04-05 17:41:44 +09:00
Sergii Liebodkin
84d3ef7184 wg_engine: introduced compute pipeline entities
introduces posibility to create compute pipelines
does not affect functionality
2024-04-05 17:37:49 +09:00
Sergii Liebodkin
96e0794a67 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-04-05 17:28:34 +09:00
Sergii Liebodkin
af6969e15e 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-04-05 17:28:08 +09:00
Hermet Park
38c625d070 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
2024-01-02 20:34:12 +09:00
Jinny You
92288c8291 updated copyright date (#1866) 2024-01-02 20:34:12 +09:00
Sergii Liebodkin
003464b7e5 wg_engine: refactor context handles
New approach provide:
- instance, adaptor, device and default queue
- device capabilitieas
- command buffer executor
- error handling
2024-01-02 20:34:11 +09:00
Sergii Liebodkin
e797cf63f4 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
2024-01-02 20:34:11 +09:00
Hermet Park
a6378fc673 wg_engine: apply tvg coding style. 2024-01-02 20:34:11 +09:00
Sergii Liebodkin
9742cfe293 wg_engine: pipelines and bind groups refactoring
- shader and system types synchronized
- pipelens and bind groups description separated
- pipelines description simplified
2024-01-02 20:34:11 +09:00
Sergii Liebodkin
c5b642e3e7 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-12-26 18:36:45 +09:00
Sergii Liebodkin
41ea198a5e 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-12-26 18:18:42 +09:00
SergeyLebedkin
4f0fbc459c wg_engine: Added a feature to draw multiple radial gradient filled shapes 2023-12-26 17:51:59 +09:00
Sergii Liebodkin
db1f171d2a 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-12-26 17:51:39 +09:00
Sergii Liebodkin
938b69688d 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-12-26 17:51:17 +09:00
SergeyLebedkin
35b03c826e 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-12-26 17:49:16 +09:00