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
This commit is contained in:
SergeyLebedkin 2023-10-13 16:59:32 +03:00 committed by GitHub
parent 9659f6e1b0
commit 8d5c728119
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 354 additions and 16 deletions

View file

@ -213,7 +213,8 @@ enum class BlendMethod : uint8_t
enum class CanvasEngine enum class CanvasEngine
{ {
Sw = (1 << 1), ///< CPU rasterizer. Sw = (1 << 1), ///< CPU rasterizer.
Gl = (1 << 2) ///< OpenGL rasterizer. Gl = (1 << 2), ///< OpenGL rasterizer.
Wg = (1 << 3), ///< WebGPU rasterizer. @BETA_API
}; };
@ -1593,6 +1594,42 @@ public:
}; };
/**
* @class WgCanvas
*
* @brief A class for the rendering graphic elements with a WebGPU raster engine.
*
* @warning Please do not use it. This class is not fully supported yet.
*
* @BETA_API
*/
class TVG_API WgCanvas final : public Canvas
{
public:
~WgCanvas();
/**
* @brief Sets the target window for the rasterization.
*
* @warning Please do not use it, this API is not official one. It could be modified in the next version.
*
* @BETA_API
*/
Result target(void* window, uint32_t w, uint32_t h) noexcept;
/**
* @brief Creates a new WgCanvas object.
*
* @return A new WgCanvas object.
*
* @BETA_API
*/
static std::unique_ptr<WgCanvas> gen() noexcept;
_TVG_DECLARE_PRIVATE(WgCanvas);
};
/** /**
* @class Initializer * @class Initializer
* *

View file

@ -22,6 +22,10 @@ if get_option('engines').contains('gl_beta') == true
config_h.set10('THORVG_GL_RASTER_SUPPORT', true) config_h.set10('THORVG_GL_RASTER_SUPPORT', true)
endif endif
if get_option('engines').contains('wg_beta') == true
config_h.set10('THORVG_WG_RASTER_SUPPORT', true)
endif
#Loaders #Loaders
all_loaders = false all_loaders = false
@ -124,20 +128,21 @@ Summary:
SIMD Instruction: @3@ SIMD Instruction: @3@
Raster Engine (SW): @4@ Raster Engine (SW): @4@
Raster Engine (GL): @5@ Raster Engine (GL): @5@
Loader (TVG): @6@ Raster Engine (WG): @6@
Loader (SVG): @7@ Loader (TVG): @7@
Loader (PNG): @8@ Loader (SVG): @8@
Loader (JPG): @9@ Loader (PNG): @9@
Loader (WEBP_BETA): @10@ Loader (JPG): @10@
Loader (LOTTIE): @11@ Loader (WEBP_BETA): @11@
Saver (TVG): @12@ Loader (LOTTIE): @12@
Binding (CAPI): @13@ Saver (TVG): @13@
Binding (WASM_BETA): @14@ Binding (CAPI): @14@
Log Message: @15@ Binding (WASM_BETA): @15@
Tests: @16@ Log Message: @16@
Examples: @17@ Tests: @17@
Tool (Svg2Tvg): @18@ Examples: @18@
Tool (Svg2Png): @19@ Tool (Svg2Tvg): @19@
Tool (Svg2Png): @20@
'''.format( '''.format(
meson.project_version(), meson.project_version(),
@ -146,6 +151,7 @@ Summary:
simd_type, simd_type,
get_option('engines').contains('sw'), get_option('engines').contains('sw'),
get_option('engines').contains('gl_beta'), get_option('engines').contains('gl_beta'),
get_option('engines').contains('wg_beta'),
all_loaders or get_option('loaders').contains('tvg'), all_loaders or get_option('loaders').contains('tvg'),
all_loaders or get_option('loaders').contains('svg'), all_loaders or get_option('loaders').contains('svg'),
all_loaders or get_option('loaders').contains('png'), all_loaders or get_option('loaders').contains('png'),

View file

@ -1,6 +1,6 @@
option('engines', option('engines',
type: 'array', type: 'array',
choices: ['sw', 'gl_beta'], choices: ['sw', 'gl_beta', 'wg_beta'],
value: ['sw'], value: ['sw'],
description: 'Enable Rasterizer Engine in thorvg') description: 'Enable Rasterizer Engine in thorvg')

View file

@ -8,6 +8,10 @@ if get_option('engines').contains('gl_beta') == true
subdir('gl_engine') subdir('gl_engine')
endif endif
if get_option('engines').contains('wg_beta') == true
subdir('wg_engine')
endif
source_file = [ source_file = [
'tvgCanvas.h', 'tvgCanvas.h',
'tvgCommon.h', 'tvgCommon.h',

View file

@ -36,6 +36,10 @@
#include "tvgGlRenderer.h" #include "tvgGlRenderer.h"
#endif #endif
#ifdef THORVG_WG_RASTER_SUPPORT
#include "tvgWgRenderer.h"
#endif
/************************************************************************/ /************************************************************************/
/* Internal Class Implementation */ /* Internal Class Implementation */
@ -102,6 +106,11 @@ Result Initializer::init(CanvasEngine engine, uint32_t threads) noexcept
if (!GlRenderer::init(threads)) return Result::FailedAllocation; if (!GlRenderer::init(threads)) return Result::FailedAllocation;
nonSupport = false; nonSupport = false;
#endif #endif
} else if (engine & CanvasEngine::Wg) {
#ifdef THORVG_WG_RASTER_SUPPORT
if (!WgRenderer::init(threads)) return Result::FailedAllocation;
nonSupport = false;
#endif
} else { } else {
return Result::InvalidArguments; return Result::InvalidArguments;
} }
@ -136,6 +145,11 @@ Result Initializer::term(CanvasEngine engine) noexcept
if (!GlRenderer::term()) return Result::InsufficientCondition; if (!GlRenderer::term()) return Result::InsufficientCondition;
nonSupport = false; nonSupport = false;
#endif #endif
} else if (engine & CanvasEngine::Wg) {
#ifdef THORVG_WG_RASTER_SUPPORT
if (!WgRenderer::term()) return Result::InsufficientCondition;
nonSupport = false;
#endif
} else { } else {
return Result::InvalidArguments; return Result::InvalidArguments;
} }

View file

@ -0,0 +1,78 @@
/*
* Copyright (c) 2023 the ThorVG project. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "tvgCanvas.h"
#ifdef THORVG_WG_RASTER_SUPPORT
#include "tvgWgRenderer.h"
#endif
/************************************************************************/
/* Internal Class Implementation */
/************************************************************************/
struct WgCanvas::Impl
{
};
/************************************************************************/
/* External Class Implementation */
/************************************************************************/
#ifdef THORVG_WG_RASTER_SUPPORT
WgCanvas::WgCanvas() : Canvas(WgRenderer::gen()), pImpl(new Impl)
#else
WgCanvas::WgCanvas() : Canvas(nullptr), pImpl(nullptr)
#endif
{
}
WgCanvas::~WgCanvas()
{
delete pImpl;
}
Result WgCanvas::target(void* window, uint32_t w, uint32_t h) noexcept
{
#ifdef THORVG_WG_RASTER_SUPPORT
//We know renderer type, avoid dynamic_cast for performance.
auto renderer = static_cast<WgRenderer*>(Canvas::pImpl->renderer);
if (!renderer) return Result::MemoryCorruption;
if (!renderer->target(window, w, h)) return Result::Unknown;
//Paints must be updated again with this new target.
Canvas::pImpl->needRefresh();
return Result::Success;
#endif
return Result::NonSupport;
}
unique_ptr<WgCanvas> WgCanvas::gen() noexcept
{
#ifdef THORVG_WG_RASTER_SUPPORT
return unique_ptr<WgCanvas>(new WgCanvas);
#endif
return nullptr;
}

View file

@ -0,0 +1,8 @@
source_file = [
'tvgWgRenderer.cpp',
]
engine_dep += [declare_dependency(
include_directories : include_directories('.'),
sources : source_file
)]

View file

@ -0,0 +1,127 @@
/*
* Copyright (c) 2023 the ThorVG project. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "tvgWgRenderer.h"
WgRenderer::WgRenderer() {
initialize();
}
WgRenderer::~WgRenderer() {
release();
}
void WgRenderer::initialize() {
TVGERR("WG_ENGINE", "TODO: WgRenderer::initialize()");
}
void WgRenderer::release() {
TVGERR("WG_ENGINE", "TODO: WgRenderer::release()");
}
RenderData WgRenderer::prepare(const RenderShape& rshape, RenderData data, const RenderTransform* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) {
return nullptr;
}
RenderData WgRenderer::prepare(const Array<RenderData>& scene, RenderData data, const RenderTransform* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) {
return nullptr;
}
RenderData WgRenderer::prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const RenderTransform* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) {
return nullptr;
}
bool WgRenderer::preRender() {
return true;
}
bool WgRenderer::renderShape(RenderData data) {
return true;
}
bool WgRenderer::renderImage(RenderData data) {
return true;
}
bool WgRenderer::postRender() {
return true;
}
bool WgRenderer::dispose(RenderData data) {
return true;
}
RenderRegion WgRenderer::region(RenderData data) {
return { 0, 0, INT32_MAX, INT32_MAX };
}
RenderRegion WgRenderer::viewport() {
return { 0, 0, INT32_MAX, INT32_MAX };
}
bool WgRenderer::viewport(const RenderRegion& vp) {
return true;
}
bool WgRenderer::blend(BlendMethod method) {
return false;
}
ColorSpace WgRenderer::colorSpace() {
return ColorSpace::Unsupported;
}
bool WgRenderer::clear() {
return true;
}
bool WgRenderer::sync() {
return true;
}
bool WgRenderer::target(void* window, uint32_t w, uint32_t h) {
return true;
}
Compositor* WgRenderer::target(const RenderRegion& region, ColorSpace cs) {
return nullptr;
}
bool WgRenderer::beginComposite(Compositor* cmp, CompositeMethod method, uint8_t opacity) {
return false;
}
bool WgRenderer::endComposite(Compositor* cmp) {
return false;
}
WgRenderer* WgRenderer::gen() {
return new WgRenderer();
}
bool WgRenderer::init(uint32_t threads) {
return true;
}
bool WgRenderer::term() {
return true;
}

View file

@ -0,0 +1,64 @@
/*
* Copyright (c) 2023 the ThorVG project. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef _TVG_WG_RENDERER_H_
#define _TVG_WG_RENDERER_H_
#include "tvgRender.h"
class WgRenderer : public RenderMethod
{
private:
WgRenderer();
~WgRenderer();
private:
void initialize();
void release();
public:
RenderData prepare(const RenderShape& rshape, RenderData data, const RenderTransform* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper);
RenderData prepare(const Array<RenderData>& scene, RenderData data, const RenderTransform* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags);
RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const RenderTransform* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags);
bool preRender();
bool renderShape(RenderData data);
bool renderImage(RenderData data);
bool postRender();
bool dispose(RenderData data);
RenderRegion region(RenderData data);
RenderRegion viewport();
bool viewport(const RenderRegion& vp);
bool blend(BlendMethod method);
ColorSpace colorSpace();
bool clear();
bool sync();
bool target(void* window, uint32_t w, uint32_t h); // temporary solution
Compositor* target(const RenderRegion& region, ColorSpace cs);
bool beginComposite(Compositor* cmp, CompositeMethod method, uint8_t opacity);
bool endComposite(Compositor* cmp);
public:
static WgRenderer* gen();
static bool init(uint32_t threads);
static bool term();
};
#endif /* _TVG_WG_RENDERER_H_ */