sw_engine: concrete shape rendering sequence. 70/231170/6
authorHermet Park <chuneon.park@samsung.com>
Sun, 19 Apr 2020 04:13:27 +0000 (13:13 +0900)
committerHermet Park <chuneon.park@samsung.com>
Sun, 19 Apr 2020 09:28:01 +0000 (18:28 +0900)
Succeed first sw backend screen up!

Change-Id: I882fb1726ed1f45e92e73fbc36170e93645dfbd2

15 files changed:
inc/tizenvg.h
src/lib/gl_engine/tvgGlRenderer.cpp
src/lib/gl_engine/tvgGlRenderer.h
src/lib/sw_engine/meson.build
src/lib/sw_engine/tvgSwCommon.h
src/lib/sw_engine/tvgSwRaster.cpp [new file with mode: 0644]
src/lib/sw_engine/tvgSwRenderer.cpp
src/lib/sw_engine/tvgSwRenderer.h
src/lib/tvgCanvasBase.h
src/lib/tvgGlCanvas.cpp
src/lib/tvgRenderCommon.h
src/lib/tvgSceneNode.cpp
src/lib/tvgShapeNode.cpp
src/lib/tvgSwCanvas.cpp
test/testShape.cpp

index dd125b5..24f2d3f 100644 (file)
@@ -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;
 
index 2357539..38fb4de 100644 (file)
@@ -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;
 }
 
index 534969a..881d1ef 100644 (file)
@@ -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;
 
index 4edd489..a33059d 100644 (file)
@@ -4,6 +4,7 @@ source_file = [
    'tvgSwRenderer.cpp',
    'tvgSwShape.cpp',
    'tvgSwRle.cpp',
+   'tvgSwRaster.cpp',
 ]
 
 swraster_dep = declare_dependency(
index 4e75e3c..4b6f820 100644 (file)
@@ -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_ */
diff --git a/src/lib/sw_engine/tvgSwRaster.cpp b/src/lib/sw_engine/tvgSwRaster.cpp
new file mode 100644 (file)
index 0000000..2e43a44
--- /dev/null
@@ -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_ */
\ No newline at end of file
index 0e09da6..425afab 100644 (file)
 
 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 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 nullptr;
+    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;
     }
index 13f4f27..f8ce1d4 100644 (file)
 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;
 
index 89476ad..a2ed34b 100644 (file)
@@ -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_ */
index 619ea4b..386778d 100644 (file)
@@ -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_ */
index e06f1ac..acdfc2f 100644 (file)
 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;
 };
index 9c7d11f..db3ae1d 100644 (file)
@@ -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;
index 74dae23..2c15b1b 100644 (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();
     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);
index 4d930a7..442b0d7 100644 (file)
 
 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();
 }
 
 
index 4ee2ad7..e42cba8 100644 (file)
@@ -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