mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-07 21:23:32 +00:00
sw_engine: concrete shape rendering sequence.
Succeed first sw backend screen up! Change-Id: I882fb1726ed1f45e92e73fbc36170e93645dfbd2
This commit is contained in:
parent
69f2fb4965
commit
37d34eeb19
15 changed files with 193 additions and 76 deletions
|
@ -56,8 +56,7 @@ class RenderMethod;
|
|||
|
||||
struct Point
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float x, y;
|
||||
};
|
||||
|
||||
|
||||
|
@ -73,7 +72,6 @@ class TIZENVG_EXPORT PaintNode
|
|||
{
|
||||
public:
|
||||
virtual ~PaintNode() {}
|
||||
virtual int dispose(RenderMethod* engine) = 0;
|
||||
virtual int update(RenderMethod* engine) = 0;
|
||||
};
|
||||
|
||||
|
@ -91,7 +89,6 @@ class TIZENVG_EXPORT ShapeNode final : public PaintNode
|
|||
public:
|
||||
~ShapeNode();
|
||||
|
||||
int dispose(RenderMethod* engine) noexcept override;
|
||||
int update(RenderMethod* engine) noexcept override;
|
||||
int clear() noexcept;
|
||||
|
||||
|
@ -106,6 +103,9 @@ public:
|
|||
|
||||
static std::unique_ptr<ShapeNode> gen() noexcept;
|
||||
|
||||
//FIXME: Ugly... Better design?
|
||||
void *engine() noexcept;
|
||||
|
||||
_TIZENVG_DECLARE_PRIVATE(ShapeNode);
|
||||
};
|
||||
|
||||
|
@ -123,7 +123,6 @@ class TIZENVG_EXPORT SceneNode final : public PaintNode
|
|||
public:
|
||||
~SceneNode();
|
||||
|
||||
int dispose(RenderMethod* engine) noexcept override;
|
||||
int update(RenderMethod* engine) noexcept override;
|
||||
|
||||
int push(std::unique_ptr<ShapeNode> shape) noexcept;
|
||||
|
@ -181,7 +180,7 @@ public:
|
|||
|
||||
//TODO: Gl Specific methods. Need gl backend configuration methods as well.
|
||||
int update() noexcept;
|
||||
int draw(bool async = true) noexcept { return 0; }
|
||||
int draw(bool async = true) noexcept;
|
||||
int sync() noexcept { return 0; }
|
||||
RenderMethod* engine() noexcept;
|
||||
|
||||
|
|
|
@ -35,12 +35,26 @@ struct GlShape
|
|||
/* External Class Implementation */
|
||||
/************************************************************************/
|
||||
|
||||
void* GlRenderer::dispose(const ShapeNode& shape, void *data)
|
||||
bool GlRenderer::render(const ShapeNode& shape, void *data)
|
||||
{
|
||||
GlShape* sdata = static_cast<GlShape*>(data);
|
||||
if (!sdata) return nullptr;
|
||||
if (!sdata) return false;
|
||||
|
||||
//TODO:
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool GlRenderer::dispose(const ShapeNode& shape, void *data)
|
||||
{
|
||||
GlShape* sdata = static_cast<GlShape*>(data);
|
||||
if (!sdata) return false;
|
||||
|
||||
//TODO:
|
||||
|
||||
free(sdata);
|
||||
return nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -52,6 +66,9 @@ void* GlRenderer::prepare(const ShapeNode& shape, void* data, UpdateFlag flags)
|
|||
sdata = static_cast<GlShape*>(calloc(1, sizeof(GlShape)));
|
||||
assert(sdata);
|
||||
}
|
||||
|
||||
//TODO:
|
||||
|
||||
return sdata;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,8 @@ class GlRenderer : public RenderMethod
|
|||
{
|
||||
public:
|
||||
void* prepare(const ShapeNode& shape, void* data, UpdateFlag flags) override;
|
||||
void* dispose(const ShapeNode& shape, void *data) override;
|
||||
bool dispose(const ShapeNode& shape, void *data) override;
|
||||
bool render(const ShapeNode& shape, void *data) override;
|
||||
size_t ref() override;
|
||||
size_t unref() override;
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ source_file = [
|
|||
'tvgSwRenderer.cpp',
|
||||
'tvgSwShape.cpp',
|
||||
'tvgSwRle.cpp',
|
||||
'tvgSwRaster.cpp',
|
||||
]
|
||||
|
||||
swraster_dep = declare_dependency(
|
||||
|
|
|
@ -95,4 +95,6 @@ bool shapeTransformOutline(const ShapeNode& shape, SwShape& sdata);
|
|||
|
||||
SwRleData* rleRender(const SwShape& sdata);
|
||||
|
||||
bool rasterShape(Surface& surface, SwShape& sdata, size_t color);
|
||||
|
||||
#endif /* _TVG_SW_COMMON_H_ */
|
||||
|
|
42
src/lib/sw_engine/tvgSwRaster.cpp
Normal file
42
src/lib/sw_engine/tvgSwRaster.cpp
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
#ifndef _TVG_SW_RASTER_CPP_
|
||||
#define _TVG_SW_RASTER_CPP_
|
||||
|
||||
#include "tvgSwCommon.h"
|
||||
|
||||
|
||||
bool rasterShape(Surface& surface, SwShape& sdata, size_t color)
|
||||
{
|
||||
SwRleData* rle = sdata.rle;
|
||||
assert(rle);
|
||||
|
||||
auto stride = surface.stride;
|
||||
auto span = rle->spans;
|
||||
|
||||
for (size_t i = 0; i < rle->size; ++i) {
|
||||
assert(span);
|
||||
for (auto j = 0; j < span->len; ++j) {
|
||||
surface.buffer[span->y * stride + span->x + j] = color;
|
||||
}
|
||||
++span;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* _TVG_SW_RASTER_CPP_ */
|
|
@ -26,18 +26,49 @@
|
|||
|
||||
static RenderInitializer renderInit;
|
||||
|
||||
static inline size_t COLOR(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
|
||||
{
|
||||
return (a << 24 | r << 16 | g << 8 | b);
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* External Class Implementation */
|
||||
/************************************************************************/
|
||||
|
||||
void* SwRenderer::dispose(const ShapeNode& shape, void *data)
|
||||
bool SwRenderer::target(uint32_t* buffer, size_t stride, size_t height)
|
||||
{
|
||||
assert(buffer && stride > 0 && height > 0);
|
||||
|
||||
surface.buffer = buffer;
|
||||
surface.stride = stride;
|
||||
surface.height = height;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool SwRenderer::render(const ShapeNode& shape, void *data)
|
||||
{
|
||||
SwShape* sdata = static_cast<SwShape*>(data);
|
||||
if (!sdata) return nullptr;
|
||||
if (!sdata) return false;
|
||||
|
||||
//invisible?
|
||||
size_t r, g, b, a;
|
||||
shape.fill(&r, &g, &b, &a);
|
||||
if (a == 0) return true;
|
||||
|
||||
//TODO: Threading
|
||||
return rasterShape(surface, *sdata, COLOR(r, g, b, a));
|
||||
}
|
||||
|
||||
|
||||
bool SwRenderer::dispose(const ShapeNode& shape, void *data)
|
||||
{
|
||||
SwShape* sdata = static_cast<SwShape*>(data);
|
||||
if (!sdata) return false;
|
||||
shapeReset(*sdata);
|
||||
free(sdata);
|
||||
return nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
void* SwRenderer::prepare(const ShapeNode& shape, void* data, UpdateFlag flags)
|
||||
|
@ -56,10 +87,10 @@ void* SwRenderer::prepare(const ShapeNode& shape, void* data, UpdateFlag flags)
|
|||
shape.fill(nullptr, nullptr, nullptr, &alpha);
|
||||
if (alpha == 0) return sdata;
|
||||
|
||||
//TODO: Threading
|
||||
if (flags & UpdateFlag::Path) {
|
||||
shapeReset(*sdata);
|
||||
if (!shapeGenOutline(shape, *sdata)) return sdata;
|
||||
//TODO: From below sequence starts threading?
|
||||
if (!shapeTransformOutline(shape, *sdata)) return sdata;
|
||||
if (!shapeGenRle(shape, *sdata)) return sdata;
|
||||
}
|
||||
|
|
|
@ -20,8 +20,12 @@
|
|||
class SwRenderer : public RenderMethod
|
||||
{
|
||||
public:
|
||||
Surface surface;
|
||||
|
||||
void* prepare(const ShapeNode& shape, void* data, UpdateFlag flags) override;
|
||||
void* dispose(const ShapeNode& shape, void *data) override;
|
||||
bool dispose(const ShapeNode& shape, void *data) override;
|
||||
bool render(const ShapeNode& shape, void *data) override;
|
||||
bool target(uint32_t* buffer, size_t stride, size_t height);
|
||||
size_t ref() override;
|
||||
size_t unref() override;
|
||||
|
||||
|
|
|
@ -19,9 +19,6 @@
|
|||
|
||||
#include "tvgCommon.h"
|
||||
|
||||
/************************************************************************/
|
||||
/* Internal Class Implementation */
|
||||
/************************************************************************/
|
||||
|
||||
struct CanvasBase
|
||||
{
|
||||
|
@ -48,42 +45,60 @@ struct CanvasBase
|
|||
|
||||
int clear()
|
||||
{
|
||||
assert(renderer);
|
||||
|
||||
auto ret = 0;
|
||||
|
||||
for (auto node : nodes) {
|
||||
node->dispose(renderer);
|
||||
if (SceneNode *scene = dynamic_cast<SceneNode *>(node)) {
|
||||
cout << "TODO: " << scene << endl;
|
||||
} else if (ShapeNode *shape = dynamic_cast<ShapeNode *>(node)) {
|
||||
ret |= renderer->dispose(*shape, shape->engine());
|
||||
}
|
||||
delete(node);
|
||||
}
|
||||
nodes.clear();
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int update()
|
||||
{
|
||||
assert(renderer);
|
||||
|
||||
auto ret = 0;
|
||||
|
||||
for(auto node: nodes) {
|
||||
ret |= node->update(renderer);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int push(unique_ptr<PaintNode> paint)
|
||||
{
|
||||
PaintNode *node = paint.release();
|
||||
assert(node);
|
||||
|
||||
nodes.push_back(node);
|
||||
#if 0
|
||||
if (SceneNode *scene = dynamic_cast<SceneNode *>(node)) {
|
||||
return node->update(renderer);
|
||||
}
|
||||
|
||||
} else if (ShapeNode *shape = dynamic_cast<ShapeNode *>(node)) {
|
||||
return shape->update(renderer);
|
||||
}
|
||||
#else
|
||||
if (ShapeNode *shape = dynamic_cast<ShapeNode *>(node)) {
|
||||
return shape->update(renderer);
|
||||
}
|
||||
#endif
|
||||
cout << "What type of PaintNode? = " << node << endl;
|
||||
int draw()
|
||||
{
|
||||
assert(renderer);
|
||||
|
||||
return -1;
|
||||
auto ret = 0;
|
||||
|
||||
for(auto node: nodes) {
|
||||
if (SceneNode *scene = dynamic_cast<SceneNode *>(node)) {
|
||||
cout << "TODO: " << scene << endl;
|
||||
} else if (ShapeNode *shape = dynamic_cast<ShapeNode *>(node)) {
|
||||
ret |= renderer->render(*shape, shape->engine());
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* External Class Implementation */
|
||||
/************************************************************************/
|
||||
|
||||
#endif /* _TVG_CANVAS_BASE_CPP_ */
|
||||
|
|
|
@ -42,7 +42,6 @@ GlCanvas::GlCanvas() : pImpl(make_unique<Impl>())
|
|||
|
||||
GlCanvas::~GlCanvas()
|
||||
{
|
||||
cout << "GlCanvas(" << this << ") destroyed!" << endl;
|
||||
}
|
||||
|
||||
|
||||
|
@ -72,7 +71,9 @@ int GlCanvas::clear() noexcept
|
|||
|
||||
int GlCanvas::update() noexcept
|
||||
{
|
||||
return 0;
|
||||
auto impl = pImpl.get();
|
||||
assert(impl);
|
||||
return impl->update();
|
||||
}
|
||||
|
||||
|
||||
|
@ -83,4 +84,12 @@ RenderMethod* GlCanvas::engine() noexcept
|
|||
return impl->renderer;
|
||||
}
|
||||
|
||||
|
||||
int GlCanvas::draw(bool async) noexcept
|
||||
{
|
||||
auto impl = pImpl.get();
|
||||
assert(impl);
|
||||
return impl->draw();
|
||||
}
|
||||
|
||||
#endif /* _TVG_GLCANVAS_CPP_ */
|
||||
|
|
|
@ -20,13 +20,22 @@
|
|||
namespace tvg
|
||||
{
|
||||
|
||||
struct Surface
|
||||
{
|
||||
//TODO: Union for multiple types
|
||||
uint32_t* buffer;
|
||||
size_t stride;
|
||||
size_t height;
|
||||
};
|
||||
|
||||
class RenderMethod
|
||||
{
|
||||
public:
|
||||
enum UpdateFlag { None = 0, Path = 1, Fill = 2, All = 3 };
|
||||
virtual ~RenderMethod() {}
|
||||
virtual void* prepare(const ShapeNode& shape, void* data, UpdateFlag flags) = 0;
|
||||
virtual void* dispose(const ShapeNode& shape, void *data) = 0;
|
||||
virtual bool dispose(const ShapeNode& shape, void *data) = 0;
|
||||
virtual bool render(const ShapeNode& shape, void *data) = 0;
|
||||
virtual size_t ref() = 0;
|
||||
virtual size_t unref() = 0;
|
||||
};
|
||||
|
|
|
@ -34,13 +34,13 @@ struct SceneNode::Impl
|
|||
/* External Class Implementation */
|
||||
/************************************************************************/
|
||||
|
||||
SceneNode :: SceneNode() : pImpl(make_unique<Impl>())
|
||||
SceneNode::SceneNode() : pImpl(make_unique<Impl>())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
SceneNode :: ~SceneNode()
|
||||
SceneNode::~SceneNode()
|
||||
{
|
||||
cout << "SceneNode(" << this << ") destroyed!" << endl;
|
||||
}
|
||||
|
@ -52,20 +52,13 @@ unique_ptr<SceneNode> SceneNode::gen() noexcept
|
|||
}
|
||||
|
||||
|
||||
int SceneNode :: push(unique_ptr<ShapeNode> shape) noexcept
|
||||
int SceneNode::push(unique_ptr<ShapeNode> shape) noexcept
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int SceneNode :: dispose(RenderMethod* engine) noexcept
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int SceneNode :: update(RenderMethod* engine) noexcept
|
||||
int SceneNode::update(RenderMethod* engine) noexcept
|
||||
{
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -84,18 +84,15 @@ unique_ptr<ShapeNode> ShapeNode::gen() noexcept
|
|||
}
|
||||
|
||||
|
||||
int ShapeNode :: dispose(RenderMethod* engine) noexcept
|
||||
void* ShapeNode::engine() noexcept
|
||||
{
|
||||
auto impl = pImpl.get();
|
||||
assert(impl);
|
||||
|
||||
impl->edata = engine->dispose(*this, impl->edata);
|
||||
if (impl->edata) return -1;
|
||||
return 0;
|
||||
return impl->edata;
|
||||
}
|
||||
|
||||
|
||||
int ShapeNode :: update(RenderMethod* engine) noexcept
|
||||
int ShapeNode::update(RenderMethod* engine) noexcept
|
||||
{
|
||||
auto impl = pImpl.get();
|
||||
assert(impl);
|
||||
|
@ -106,7 +103,7 @@ int ShapeNode :: update(RenderMethod* engine) noexcept
|
|||
}
|
||||
|
||||
|
||||
int ShapeNode :: clear() noexcept
|
||||
int ShapeNode::clear() noexcept
|
||||
{
|
||||
auto impl = pImpl.get();
|
||||
assert(impl);
|
||||
|
@ -115,7 +112,7 @@ int ShapeNode :: clear() noexcept
|
|||
}
|
||||
|
||||
|
||||
int ShapeNode :: pathCommands(const PathCommand** cmds) const noexcept
|
||||
int ShapeNode::pathCommands(const PathCommand** cmds) const noexcept
|
||||
{
|
||||
auto impl = pImpl.get();
|
||||
assert(impl && cmds);
|
||||
|
@ -126,7 +123,7 @@ int ShapeNode :: pathCommands(const PathCommand** cmds) const noexcept
|
|||
}
|
||||
|
||||
|
||||
int ShapeNode :: pathCoords(const Point** pts) const noexcept
|
||||
int ShapeNode::pathCoords(const Point** pts) const noexcept
|
||||
{
|
||||
auto impl = pImpl.get();
|
||||
assert(impl && pts);
|
||||
|
@ -137,13 +134,13 @@ int ShapeNode :: pathCoords(const Point** pts) const noexcept
|
|||
}
|
||||
|
||||
|
||||
int ShapeNode :: appendCircle(float cx, float cy, float radius) noexcept
|
||||
int ShapeNode::appendCircle(float cx, float cy, float radius) noexcept
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ShapeNode :: appendRect(float x, float y, float w, float h, float radius) noexcept
|
||||
int ShapeNode::appendRect(float x, float y, float w, float h, float radius) noexcept
|
||||
{
|
||||
auto impl = pImpl.get();
|
||||
assert(impl);
|
||||
|
@ -171,7 +168,7 @@ int ShapeNode :: appendRect(float x, float y, float w, float h, float radius) no
|
|||
}
|
||||
|
||||
|
||||
int ShapeNode :: fill(size_t r, size_t g, size_t b, size_t a) noexcept
|
||||
int ShapeNode::fill(size_t r, size_t g, size_t b, size_t a) noexcept
|
||||
{
|
||||
auto impl = pImpl.get();
|
||||
assert(impl);
|
||||
|
@ -185,7 +182,7 @@ int ShapeNode :: fill(size_t r, size_t g, size_t b, size_t a) noexcept
|
|||
}
|
||||
|
||||
|
||||
int ShapeNode :: fill(size_t* r, size_t* g, size_t* b, size_t* a) const noexcept
|
||||
int ShapeNode::fill(size_t* r, size_t* g, size_t* b, size_t* a) const noexcept
|
||||
{
|
||||
auto impl = pImpl.get();
|
||||
assert(impl);
|
||||
|
|
|
@ -28,10 +28,6 @@
|
|||
|
||||
struct SwCanvas::Impl : CanvasBase
|
||||
{
|
||||
uint32_t* buffer = nullptr;
|
||||
int stride = 0;
|
||||
int height = 0;
|
||||
|
||||
Impl() : CanvasBase(SwRenderer::inst()) {}
|
||||
};
|
||||
|
||||
|
@ -45,9 +41,7 @@ int SwCanvas::target(uint32_t* buffer, size_t stride, size_t height) noexcept
|
|||
auto impl = pImpl.get();
|
||||
assert(impl);
|
||||
|
||||
impl->buffer = buffer;
|
||||
impl->stride = stride;
|
||||
impl->height = height;
|
||||
dynamic_cast<SwRenderer*>(impl->renderer)->target(buffer, stride, height);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -55,7 +49,9 @@ int SwCanvas::target(uint32_t* buffer, size_t stride, size_t height) noexcept
|
|||
|
||||
int SwCanvas::draw(bool async) noexcept
|
||||
{
|
||||
return 0;
|
||||
auto impl = pImpl.get();
|
||||
assert(impl);
|
||||
return impl->draw();
|
||||
}
|
||||
|
||||
|
||||
|
@ -89,7 +85,6 @@ SwCanvas::SwCanvas() : pImpl(make_unique<Impl>())
|
|||
|
||||
SwCanvas::~SwCanvas()
|
||||
{
|
||||
cout << "SwCanvas(" << this << ") destroyed!" << endl;
|
||||
}
|
||||
|
||||
|
||||
|
@ -107,7 +102,9 @@ unique_ptr<SwCanvas> SwCanvas::gen(uint32_t* buffer, size_t stride, size_t heigh
|
|||
|
||||
int SwCanvas::update() noexcept
|
||||
{
|
||||
return 0;
|
||||
auto impl = pImpl.get();
|
||||
assert(impl);
|
||||
return impl->update();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ void tvgtest()
|
|||
//Prepare a Shape (Rectangle)
|
||||
auto shape1 = tvg::ShapeNode::gen();
|
||||
shape1->appendRect(0, 0, 400, 400, 0); //x, y, w, h, corner_radius
|
||||
shape1->fill(0, 255, 0, 255); //r, g, b, a
|
||||
shape1->fill(255, 0, 0, 255); //r, g, b, a
|
||||
|
||||
/* Push the shape into the Canvas drawing list
|
||||
When this shape is into the canvas list, the shape could update & prepare
|
||||
|
|
Loading…
Add table
Reference in a new issue