sw_engine: concrete shape rendering sequence.

Succeed first sw backend screen up!

Change-Id: I882fb1726ed1f45e92e73fbc36170e93645dfbd2
This commit is contained in:
Hermet Park 2020-04-19 13:13:27 +09:00
parent 69f2fb4965
commit 37d34eeb19
15 changed files with 193 additions and 76 deletions

View file

@ -56,8 +56,7 @@ class RenderMethod;
struct Point struct Point
{ {
float x; float x, y;
float y;
}; };
@ -73,7 +72,6 @@ class TIZENVG_EXPORT PaintNode
{ {
public: public:
virtual ~PaintNode() {} virtual ~PaintNode() {}
virtual int dispose(RenderMethod* engine) = 0;
virtual int update(RenderMethod* engine) = 0; virtual int update(RenderMethod* engine) = 0;
}; };
@ -91,7 +89,6 @@ class TIZENVG_EXPORT ShapeNode final : public PaintNode
public: public:
~ShapeNode(); ~ShapeNode();
int dispose(RenderMethod* engine) noexcept override;
int update(RenderMethod* engine) noexcept override; int update(RenderMethod* engine) noexcept override;
int clear() noexcept; int clear() noexcept;
@ -106,6 +103,9 @@ public:
static std::unique_ptr<ShapeNode> gen() noexcept; static std::unique_ptr<ShapeNode> gen() noexcept;
//FIXME: Ugly... Better design?
void *engine() noexcept;
_TIZENVG_DECLARE_PRIVATE(ShapeNode); _TIZENVG_DECLARE_PRIVATE(ShapeNode);
}; };
@ -123,7 +123,6 @@ class TIZENVG_EXPORT SceneNode final : public PaintNode
public: public:
~SceneNode(); ~SceneNode();
int dispose(RenderMethod* engine) noexcept override;
int update(RenderMethod* engine) noexcept override; int update(RenderMethod* engine) noexcept override;
int push(std::unique_ptr<ShapeNode> shape) noexcept; int push(std::unique_ptr<ShapeNode> shape) noexcept;
@ -181,7 +180,7 @@ public:
//TODO: Gl Specific methods. Need gl backend configuration methods as well. //TODO: Gl Specific methods. Need gl backend configuration methods as well.
int update() noexcept; int update() noexcept;
int draw(bool async = true) noexcept { return 0; } int draw(bool async = true) noexcept;
int sync() noexcept { return 0; } int sync() noexcept { return 0; }
RenderMethod* engine() noexcept; RenderMethod* engine() noexcept;

View file

@ -35,12 +35,26 @@ struct GlShape
/* External Class Implementation */ /* 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); 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); 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))); sdata = static_cast<GlShape*>(calloc(1, sizeof(GlShape)));
assert(sdata); assert(sdata);
} }
//TODO:
return sdata; return sdata;
} }

View file

@ -24,7 +24,8 @@ class GlRenderer : public RenderMethod
{ {
public: public:
void* prepare(const ShapeNode& shape, void* data, UpdateFlag flags) override; 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 ref() override;
size_t unref() override; size_t unref() override;

View file

@ -4,6 +4,7 @@ source_file = [
'tvgSwRenderer.cpp', 'tvgSwRenderer.cpp',
'tvgSwShape.cpp', 'tvgSwShape.cpp',
'tvgSwRle.cpp', 'tvgSwRle.cpp',
'tvgSwRaster.cpp',
] ]
swraster_dep = declare_dependency( swraster_dep = declare_dependency(

View file

@ -95,4 +95,6 @@ bool shapeTransformOutline(const ShapeNode& shape, SwShape& sdata);
SwRleData* rleRender(const SwShape& sdata); SwRleData* rleRender(const SwShape& sdata);
bool rasterShape(Surface& surface, SwShape& sdata, size_t color);
#endif /* _TVG_SW_COMMON_H_ */ #endif /* _TVG_SW_COMMON_H_ */

View 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_ */

View file

@ -26,18 +26,49 @@
static RenderInitializer renderInit; 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 */ /* 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); 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); shapeReset(*sdata);
free(sdata); free(sdata);
return nullptr; return true;
} }
void* SwRenderer::prepare(const ShapeNode& shape, void* data, UpdateFlag flags) 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); shape.fill(nullptr, nullptr, nullptr, &alpha);
if (alpha == 0) return sdata; if (alpha == 0) return sdata;
//TODO: Threading
if (flags & UpdateFlag::Path) { if (flags & UpdateFlag::Path) {
shapeReset(*sdata); shapeReset(*sdata);
if (!shapeGenOutline(shape, *sdata)) return sdata; if (!shapeGenOutline(shape, *sdata)) return sdata;
//TODO: From below sequence starts threading?
if (!shapeTransformOutline(shape, *sdata)) return sdata; if (!shapeTransformOutline(shape, *sdata)) return sdata;
if (!shapeGenRle(shape, *sdata)) return sdata; if (!shapeGenRle(shape, *sdata)) return sdata;
} }

View file

@ -20,8 +20,12 @@
class SwRenderer : public RenderMethod class SwRenderer : public RenderMethod
{ {
public: public:
Surface surface;
void* prepare(const ShapeNode& shape, void* data, UpdateFlag flags) override; 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 ref() override;
size_t unref() override; size_t unref() override;

View file

@ -19,9 +19,6 @@
#include "tvgCommon.h" #include "tvgCommon.h"
/************************************************************************/
/* Internal Class Implementation */
/************************************************************************/
struct CanvasBase struct CanvasBase
{ {
@ -48,42 +45,60 @@ struct CanvasBase
int clear() int clear()
{ {
assert(renderer);
auto ret = 0;
for (auto node : nodes) { 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); delete(node);
} }
nodes.clear(); 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) int push(unique_ptr<PaintNode> paint)
{ {
PaintNode *node = paint.release(); PaintNode *node = paint.release();
assert(node); assert(node);
nodes.push_back(node); nodes.push_back(node);
#if 0 return node->update(renderer);
if (SceneNode *scene = dynamic_cast<SceneNode *>(node)) { }
} else if (ShapeNode *shape = dynamic_cast<ShapeNode *>(node)) { int draw()
return shape->update(renderer); {
} assert(renderer);
#else
if (ShapeNode *shape = dynamic_cast<ShapeNode *>(node)) {
return shape->update(renderer);
}
#endif
cout << "What type of PaintNode? = " << node << endl;
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_ */ #endif /* _TVG_CANVAS_BASE_CPP_ */

View file

@ -42,7 +42,6 @@ GlCanvas::GlCanvas() : pImpl(make_unique<Impl>())
GlCanvas::~GlCanvas() GlCanvas::~GlCanvas()
{ {
cout << "GlCanvas(" << this << ") destroyed!" << endl;
} }
@ -72,7 +71,9 @@ int GlCanvas::clear() noexcept
int GlCanvas::update() 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; return impl->renderer;
} }
int GlCanvas::draw(bool async) noexcept
{
auto impl = pImpl.get();
assert(impl);
return impl->draw();
}
#endif /* _TVG_GLCANVAS_CPP_ */ #endif /* _TVG_GLCANVAS_CPP_ */

View file

@ -20,13 +20,22 @@
namespace tvg namespace tvg
{ {
struct Surface
{
//TODO: Union for multiple types
uint32_t* buffer;
size_t stride;
size_t height;
};
class RenderMethod class RenderMethod
{ {
public: public:
enum UpdateFlag { None = 0, Path = 1, Fill = 2, All = 3 }; enum UpdateFlag { None = 0, Path = 1, Fill = 2, All = 3 };
virtual ~RenderMethod() {} virtual ~RenderMethod() {}
virtual void* prepare(const ShapeNode& shape, void* data, UpdateFlag flags) = 0; 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 ref() = 0;
virtual size_t unref() = 0; virtual size_t unref() = 0;
}; };

View file

@ -34,13 +34,13 @@ struct SceneNode::Impl
/* External Class Implementation */ /* External Class Implementation */
/************************************************************************/ /************************************************************************/
SceneNode :: SceneNode() : pImpl(make_unique<Impl>()) SceneNode::SceneNode() : pImpl(make_unique<Impl>())
{ {
} }
SceneNode :: ~SceneNode() SceneNode::~SceneNode()
{ {
cout << "SceneNode(" << this << ") destroyed!" << endl; 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; return 0;
} }
int SceneNode :: dispose(RenderMethod* engine) noexcept int SceneNode::update(RenderMethod* engine) noexcept
{
return 0;
}
int SceneNode :: update(RenderMethod* engine) noexcept
{ {
return 0; return 0;

View file

@ -84,18 +84,15 @@ unique_ptr<ShapeNode> ShapeNode::gen() noexcept
} }
int ShapeNode :: dispose(RenderMethod* engine) noexcept void* ShapeNode::engine() noexcept
{ {
auto impl = pImpl.get(); auto impl = pImpl.get();
assert(impl); assert(impl);
return impl->edata;
impl->edata = engine->dispose(*this, impl->edata);
if (impl->edata) return -1;
return 0;
} }
int ShapeNode :: update(RenderMethod* engine) noexcept int ShapeNode::update(RenderMethod* engine) noexcept
{ {
auto impl = pImpl.get(); auto impl = pImpl.get();
assert(impl); assert(impl);
@ -106,7 +103,7 @@ int ShapeNode :: update(RenderMethod* engine) noexcept
} }
int ShapeNode :: clear() noexcept int ShapeNode::clear() noexcept
{ {
auto impl = pImpl.get(); auto impl = pImpl.get();
assert(impl); 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(); auto impl = pImpl.get();
assert(impl && cmds); 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(); auto impl = pImpl.get();
assert(impl && pts); 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; 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(); auto impl = pImpl.get();
assert(impl); 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(); auto impl = pImpl.get();
assert(impl); 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(); auto impl = pImpl.get();
assert(impl); assert(impl);

View file

@ -28,10 +28,6 @@
struct SwCanvas::Impl : CanvasBase struct SwCanvas::Impl : CanvasBase
{ {
uint32_t* buffer = nullptr;
int stride = 0;
int height = 0;
Impl() : CanvasBase(SwRenderer::inst()) {} 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(); auto impl = pImpl.get();
assert(impl); assert(impl);
impl->buffer = buffer; dynamic_cast<SwRenderer*>(impl->renderer)->target(buffer, stride, height);
impl->stride = stride;
impl->height = height;
return 0; 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 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() 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 int SwCanvas::update() noexcept
{ {
return 0; auto impl = pImpl.get();
assert(impl);
return impl->update();
} }

View file

@ -19,7 +19,7 @@ void tvgtest()
//Prepare a Shape (Rectangle) //Prepare a Shape (Rectangle)
auto shape1 = tvg::ShapeNode::gen(); auto shape1 = tvg::ShapeNode::gen();
shape1->appendRect(0, 0, 400, 400, 0); //x, y, w, h, corner_radius 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 /* Push the shape into the Canvas drawing list
When this shape is into the canvas list, the shape could update & prepare When this shape is into the canvas list, the shape could update & prepare