diff --git a/.gitignore b/.gitignore index a6c4662b..45329ec6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ build .vscode *.swp -test +testShape diff --git a/inc/tizenvg.h b/inc/tizenvg.h index e790ea10..aeea75f2 100644 --- a/inc/tizenvg.h +++ b/inc/tizenvg.h @@ -50,7 +50,7 @@ private: \ namespace tvg { -class SceneNode; +enum class TIZENVG_EXPORT PathCommand { Close, MoveTo, LineTo, CubicTo }; /** @@ -65,7 +65,7 @@ class TIZENVG_EXPORT PaintNode { public: virtual ~PaintNode() {} - virtual int prepare() = 0; + virtual int update() = 0; }; @@ -82,7 +82,12 @@ class TIZENVG_EXPORT ShapeNode final : public PaintNode public: ~ShapeNode(); - int prepare() noexcept override; + int update() noexcept override; + + int appendRect(float x, float y, float w, float h, float radius) noexcept; + int appendCircle(float cx, float cy, float radius) noexcept; + int fill(uint32_t r, uint32_t g, uint32_t b, uint32_t a) noexcept; + int clear() noexcept; static std::unique_ptr gen(); @@ -103,8 +108,9 @@ class TIZENVG_EXPORT SceneNode final : public PaintNode public: ~SceneNode(); + int update() noexcept override; + int push(std::unique_ptr shape) noexcept; - int prepare() noexcept override; static std::unique_ptr gen() noexcept; @@ -128,6 +134,7 @@ public: int push(std::unique_ptr paint) noexcept; int clear() noexcept; + int update(PaintNode* node) noexcept; int draw(bool async = true) noexcept; int sync() noexcept; diff --git a/src/lib/gl_engine/meson.build b/src/lib/gl_engine/meson.build new file mode 100644 index 00000000..2c3fe062 --- /dev/null +++ b/src/lib/gl_engine/meson.build @@ -0,0 +1,9 @@ +source_file = [ + 'tvgGlRaster.h', + 'tvgGlRaster.cpp', +] + +glraster_dep = declare_dependency( + include_directories : include_directories('.'), + sources : source_file +) diff --git a/src/lib/gl_engine/tvgGlRaster.cpp b/src/lib/gl_engine/tvgGlRaster.cpp new file mode 100644 index 00000000..eca8c47c --- /dev/null +++ b/src/lib/gl_engine/tvgGlRaster.cpp @@ -0,0 +1,61 @@ +/* + * 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_GL_RASTER_CPP_ +#define _TVG_GL_RASTER_CPP_ + +#include "tvgCommon.h" +#include "tvgGlRaster.h" + + +static GlRaster* pInst = nullptr; + +int GlRaster::prepare(ShapeNode *shape) +{ + cout << "GlRaster prepare!!" << endl; + + return 0; +} + + +int GlRaster::init() +{ + if (pInst) return -1; + pInst = new GlRaster(); + assert(pInst); + + return 0; +} + + +int GlRaster::term() +{ + if (!pInst) return -1; + cout << "GlRaster(" << pInst << ") destroyed!" << endl; + delete(pInst); + pInst = nullptr; + return 0; +} + + +GlRaster* GlRaster::inst() +{ + assert(pInst); + return pInst; +} + + +#endif /* _TVG_GL_RASTER_CPP_ */ diff --git a/src/lib/gl_engine/tvgGlRaster.h b/src/lib/gl_engine/tvgGlRaster.h new file mode 100644 index 00000000..10c44625 --- /dev/null +++ b/src/lib/gl_engine/tvgGlRaster.h @@ -0,0 +1,38 @@ +/* + * 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_GL_RASTER_H_ +#define _TVG_GL_RASTER_H_ + +namespace tvg +{ + +class GlRaster : public RasterMethod +{ +public: + int prepare(ShapeNode *shape) override; + static GlRaster* inst(); + static int init(); + static int term(); + +private: + GlRaster(){}; + ~GlRaster(){}; +}; + +} + +#endif /* _TVG_GL_RASTER_H_ */ diff --git a/src/lib/meson.build b/src/lib/meson.build index fb856bf0..b2243fe7 100644 --- a/src/lib/meson.build +++ b/src/lib/meson.build @@ -1,7 +1,11 @@ +subdir('sw_engine') +subdir('gl_engine') + source_file = [ 'tvgCommon.h', 'tvgEngine.cpp', 'tvgCanvasBase.h', + 'tvgShapePath.h', 'tvgSwCanvas.cpp', 'tvgGlCanvas.cpp', 'tvgSceneNode.cpp', @@ -12,3 +16,4 @@ src_dep = declare_dependency( include_directories : include_directories('.'), sources : source_file ) + diff --git a/src/lib/sw_engine/meson.build b/src/lib/sw_engine/meson.build new file mode 100644 index 00000000..0a29e22b --- /dev/null +++ b/src/lib/sw_engine/meson.build @@ -0,0 +1,9 @@ +source_file = [ + 'tvgSwRaster.h', + 'tvgSwRaster.cpp', +] + +swraster_dep = declare_dependency( + include_directories : include_directories('.'), + sources : source_file +) diff --git a/src/lib/sw_engine/tvgSwRaster.cpp b/src/lib/sw_engine/tvgSwRaster.cpp new file mode 100644 index 00000000..fa9a8452 --- /dev/null +++ b/src/lib/sw_engine/tvgSwRaster.cpp @@ -0,0 +1,61 @@ +/* + * 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 "tvgCommon.h" +#include "tvgSwRaster.h" + + +static SwRaster* pInst = nullptr; + +int SwRaster::prepare(ShapeNode *shape) +{ + cout << "SWRaster prepare!!" << endl; + + return 0; +} + + +int SwRaster::init() +{ + if (pInst) return -1; + pInst = new SwRaster(); + assert(pInst); + + return 0; +} + + +int SwRaster::term() +{ + if (!pInst) return -1; + cout << "SwRaster(" << pInst << ") destroyed!" << endl; + delete(pInst); + pInst = nullptr; + return 0; +} + + +SwRaster* SwRaster::inst() +{ + assert(pInst); + return pInst; +} + + +#endif /* _TVG_SW_RASTER_CPP_ */ diff --git a/src/lib/sw_engine/tvgSwRaster.h b/src/lib/sw_engine/tvgSwRaster.h new file mode 100644 index 00000000..e79f6280 --- /dev/null +++ b/src/lib/sw_engine/tvgSwRaster.h @@ -0,0 +1,38 @@ +/* + * 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_H_ +#define _TVG_SW_RASTER_H_ + +namespace tvg +{ + +class SwRaster : public RasterMethod +{ +public: + int prepare(ShapeNode *shape) override; + static SwRaster* inst(); + static int init(); + static int term(); + +private: + SwRaster(){}; + ~SwRaster(){}; +}; + +} + +#endif /* _TVG_SW_RASTER_H_ */ diff --git a/src/lib/tvgCanvasBase.h b/src/lib/tvgCanvasBase.h index 83607bf4..2a4632ec 100644 --- a/src/lib/tvgCanvasBase.h +++ b/src/lib/tvgCanvasBase.h @@ -14,8 +14,8 @@ * limitations under the License. * */ -#ifndef _TVG_CANVAS_CPP_ -#define _TVG_CANVAS_CPP_ +#ifndef _TVG_CANVAS_BASE_CPP_ +#define _TVG_CANVAS_BASE_CPP_ #include "tvgCommon.h" @@ -25,17 +25,59 @@ struct CanvasBase { + vector nodes; + RasterMethod* raster; - int push(unique_ptr paint) + CanvasBase(RasterMethod *pRaster):raster(pRaster) { + + } + + ~CanvasBase() + { + clear(); + } + + int reserve(size_t n) + { + nodes.reserve(n); + return 0; } int clear() { + for (auto node : nodes) { + delete(node); + } + nodes.clear(); + return 0; } + int push(unique_ptr paint) + { + PaintNode *node = paint.release(); + assert(node); + + nodes.push_back(node); + + int ret = node->update(); + if (ret) return ret; + + if (SceneNode *scene = dynamic_cast(node)) { + + //TODO: + + } else if (ShapeNode *shape = dynamic_cast(node)) { + return raster->prepare(shape); + } + + cout << "What type of PaintNode? = " << node << endl; + + return -1; + } + }; @@ -43,4 +85,4 @@ struct CanvasBase /* External Class Implementation */ /************************************************************************/ -#endif /* _TVG_CANVAS_CPP_ */ +#endif /* _TVG_CANVAS_BASE_CPP_ */ diff --git a/src/lib/tvgCommon.h b/src/lib/tvgCommon.h index f69af00f..0140cc8e 100644 --- a/src/lib/tvgCommon.h +++ b/src/lib/tvgCommon.h @@ -24,6 +24,24 @@ using namespace std; using namespace tvg; -using var = float; + +namespace tvg +{ + +struct Point +{ + float x, y; +}; + +class RasterMethod +{ +public: + virtual ~RasterMethod() {} + virtual int prepare(ShapeNode *shape) = 0; +}; + + +} + #endif //_TVG_COMMON_H_ diff --git a/src/lib/tvgEngine.cpp b/src/lib/tvgEngine.cpp index 838f4ca8..5f8f533a 100644 --- a/src/lib/tvgEngine.cpp +++ b/src/lib/tvgEngine.cpp @@ -18,6 +18,8 @@ #define _TVG_ENGINE_CPP_ #include "tvgCommon.h" +#include "tvgSwRaster.h" +#include "tvgGlRaster.h" /************************************************************************/ /* Internal Class Implementation */ @@ -30,13 +32,23 @@ int Engine::init() noexcept { - return 0; + //TODO: Initialize Raster engines by configuration. + + int ret = 0; + ret |= SwRaster::init(); + ret |= GlRaster::init(); + + return ret; } int Engine::term() noexcept { - return 0; + int ret = 0; + ret |= SwRaster::term(); + ret |= GlRaster::term(); + + return ret; } #endif /* _TVG_ENGINE_CPP_ */ diff --git a/src/lib/tvgGlCanvas.cpp b/src/lib/tvgGlCanvas.cpp index 573600eb..49828ac4 100644 --- a/src/lib/tvgGlCanvas.cpp +++ b/src/lib/tvgGlCanvas.cpp @@ -19,6 +19,7 @@ #include "tvgCommon.h" #include "tvgCanvasBase.h" +#include "tvgGlRaster.h" /************************************************************************/ /* Internal Class Implementation */ @@ -26,7 +27,7 @@ struct GlCanvas::Impl : CanvasBase { - //... + Impl() : CanvasBase(GlRaster::inst()) {} }; diff --git a/src/lib/tvgSceneNode.cpp b/src/lib/tvgSceneNode.cpp index 8da41fca..68ddbc99 100644 --- a/src/lib/tvgSceneNode.cpp +++ b/src/lib/tvgSceneNode.cpp @@ -57,7 +57,7 @@ int SceneNode :: push(unique_ptr shape) noexcept } -int SceneNode :: prepare() noexcept +int SceneNode :: update() noexcept { return 0; diff --git a/src/lib/tvgShapeNode.cpp b/src/lib/tvgShapeNode.cpp index 4fb4b107..59b40a77 100644 --- a/src/lib/tvgShapeNode.cpp +++ b/src/lib/tvgShapeNode.cpp @@ -18,6 +18,7 @@ #define _TVG_SHAPE_NODE_CPP_ #include "tvgCommon.h" +#include "tvgShapePath.h" /************************************************************************/ /* Internal Class Implementation */ @@ -33,33 +34,25 @@ struct ShapeStroke }; -struct ShapePath -{ -}; - - struct ShapeTransform { - var e[4*4]; -}; - - -struct ShapeChildren -{ - vector> v; + float e[4*4]; }; struct ShapeNode::Impl { - ShapeChildren *children = nullptr; ShapeTransform *transform = nullptr; ShapeFill *fill = nullptr; ShapeStroke *stroke = nullptr; ShapePath *path = nullptr; - uint32_t color = 0; - uint32_t id = 0; + uint8_t color[4] = {0, 0, 0, 0}; //r, g, b, a + + Impl() : path(new ShapePath) + { + + } ~Impl() { @@ -67,9 +60,7 @@ struct ShapeNode::Impl if (stroke) delete(stroke); if (fill) delete(fill); if (transform) delete(transform); - if (children) delete(children); } - }; @@ -95,10 +86,69 @@ unique_ptr ShapeNode::gen() } -int ShapeNode :: prepare() noexcept +int ShapeNode :: update() noexcept +{ + auto impl = pImpl.get(); + assert(impl); + + return 0; +} + + +int ShapeNode :: clear() noexcept +{ + auto impl = pImpl.get(); + assert(impl); + + return impl->path->clear(); +} + + +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 +{ + auto impl = pImpl.get(); + assert(impl); + + //clamping radius by minimum size + auto min = (w < h ? w : h) * 0.5f; + if (radius > min) radius = min; + + //rectangle + if (radius == 0) { + impl->path->reserve(5, 4); + impl->path->moveTo(x, y); + impl->path->lineTo(x + w, y); + impl->path->lineTo(x + w, y + h); + impl->path->lineTo(x, y + h); + impl->path->close(); + //circle + } else if (w == h && radius * 2 == w) { + appendCircle(x + (w * 0.5f), y + (h * 0.5f), radius); + } else { + //... + } + + return 0; +} + + +int ShapeNode :: fill(uint32_t r, uint32_t g, uint32_t b, uint32_t a) noexcept +{ + auto impl = pImpl.get(); + assert(impl); + + impl->color[0] = r; + impl->color[1] = g; + impl->color[2] = b; + impl->color[3] = a; + + return 0; +} + #endif //_TVG_SHAPE_NODE_CPP_ diff --git a/src/lib/tvgShapePath.h b/src/lib/tvgShapePath.h new file mode 100644 index 00000000..eb3849ee --- /dev/null +++ b/src/lib/tvgShapePath.h @@ -0,0 +1,149 @@ +/* + * 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_SHAPE_PATH_CPP_ +#define _TVG_SHAPE_PATH_CPP_ + +#include "tvgCommon.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +struct ShapePath +{ + PathCommand* cmds = nullptr; + uint32_t cmdCnt = 0; + uint32_t reservedCmdCnt = 0; + + Point *pts = nullptr; + uint32_t ptsCnt = 0; + uint32_t reservedPtsCnt = 0; + + + ~ShapePath() + { + if (cmds) delete(cmds); + if (pts) delete(pts); + } + + int reserveCmd(uint32_t cmdCnt) + { + if (cmdCnt > reservedCmdCnt) { + reservedCmdCnt = cmdCnt; + cmds = static_cast(realloc(cmds, sizeof(PathCommand) * reservedCmdCnt)); + assert(cmds); + } + return 0; + } + + int reservePts(uint32_t ptsCnt) + { + if (ptsCnt > reservedPtsCnt) { + reservedPtsCnt = ptsCnt; + pts = static_cast(realloc(pts, sizeof(Point) * reservedPtsCnt)); + assert(pts); + } + return 0; + } + + int reserve(uint32_t cmdCnt, uint32_t ptsCnt) + { + reserveCmd(cmdCnt); + reservePts(ptsCnt); + + return 0; + } + + int clear() + { + cmdCnt = 0; + ptsCnt = 0; + + return 0; + } + + int moveTo(float x, float y) + { + if (cmdCnt + 1 > reservedCmdCnt) reserveCmd((cmdCnt + 1) * 2); + if (ptsCnt + 2 > reservedPtsCnt) reservePts((ptsCnt + 2) * 2); + + cmds[cmdCnt++] = PathCommand::MoveTo; + pts[ptsCnt++] = {x, y}; + + return 0; + } + + int lineTo(float x, float y) + { + if (cmdCnt + 1 > reservedCmdCnt) reserveCmd((cmdCnt + 1) * 2); + if (ptsCnt + 2 > reservedPtsCnt) reservePts((ptsCnt + 2) * 2); + + cmds[cmdCnt++] = PathCommand::LineTo; + pts[ptsCnt++] = {x, y}; + + return 0; + } + + int cubicTo(float cx1, float cy1, float cx2, float cy2, float x, float y) + { + if (cmdCnt + 1 > reservedCmdCnt) reserveCmd((cmdCnt + 1) * 2); + if (ptsCnt + 3 > reservedPtsCnt) reservePts((ptsCnt + 3) * 2); + + cmds[cmdCnt++] = PathCommand::CubicTo; + pts[ptsCnt++] = {cx1, cy1}; + pts[ptsCnt++] = {cx2, cy2}; + pts[ptsCnt++] = {x, y}; + + return 0; + } + + int close() + { + if (cmdCnt + 1 > reservedCmdCnt) reserveCmd((cmdCnt + 1) * 2); + cmds[cmdCnt++] = PathCommand::Close; + + return 0; + } + + int bounds(float& x, float& y, float& w, float& h) + { + if (ptsCnt == 0) return -1; + + Point min = { pts[0].x, pts[0].y }; + Point max = { pts[0].x, pts[0].y }; + + for(uint32_t i = 1; i <= ptsCnt; ++i) { + if (pts[i].x < min.x) min.x = pts[i].x; + if (pts[i].y < min.y) min.y = pts[i].y; + if (pts[i].x > max.x) max.x = pts[i].x; + if (pts[i].y > max.y) max.y = pts[i].y; + } + + x = min.x; + y = min.y; + w = max.x - min.x; + h = max.y - min.y; + + return 0; + } +}; + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +#endif //_TVG_SHAPE_PATH_CPP_ diff --git a/src/lib/tvgSwCanvas.cpp b/src/lib/tvgSwCanvas.cpp index 13e91f34..00338ef1 100644 --- a/src/lib/tvgSwCanvas.cpp +++ b/src/lib/tvgSwCanvas.cpp @@ -19,6 +19,8 @@ #include "tvgCommon.h" #include "tvgCanvasBase.h" +#include "tvgSwRaster.h" + /************************************************************************/ /* Internal Class Implementation */ @@ -29,6 +31,8 @@ struct SwCanvas::Impl : CanvasBase uint32_t* buffer = nullptr; int stride = 0; int height = 0; + + Impl() : CanvasBase(SwRaster::inst()) {} }; @@ -65,6 +69,7 @@ int SwCanvas::push(unique_ptr paint) noexcept { auto impl = pImpl.get(); assert(impl); + return impl->push(move(paint)); } diff --git a/src/meson.build b/src/meson.build index d3fde4d1..495e4c79 100644 --- a/src/meson.build +++ b/src/meson.build @@ -3,7 +3,7 @@ compiler_flags = ['-DTIZENVG_BUILD'] subdir('lib') subdir('examples') -tizenvg_lib_dep = [ src_dep ] +tizenvg_lib_dep = [ src_dep, swraster_dep, glraster_dep ] tizenvg_lib = library( 'tizenvg', diff --git a/test/makefile b/test/makefile index 0f89da04..5fdc45c4 100644 --- a/test/makefile +++ b/test/makefile @@ -1,2 +1,2 @@ all: - gcc -o tvgDrawShape tvgDrawShape.cpp -g -lstdc++ `pkg-config --cflags --libs tizenvg` + gcc -o testShape testShape.cpp -g -lstdc++ `pkg-config --cflags --libs tizenvg` diff --git a/test/tvgComposition.cpp b/test/testComposition.cpp similarity index 100% rename from test/tvgComposition.cpp rename to test/testComposition.cpp diff --git a/test/tvgGradient.cpp b/test/testGradient.cpp similarity index 100% rename from test/tvgGradient.cpp rename to test/testGradient.cpp diff --git a/test/tvgMultipleShapes.cpp b/test/testMultipleShapes.cpp similarity index 100% rename from test/tvgMultipleShapes.cpp rename to test/testMultipleShapes.cpp diff --git a/test/tvgPath.cpp b/test/testPath.cpp similarity index 100% rename from test/tvgPath.cpp rename to test/testPath.cpp diff --git a/test/tvgScene.cpp b/test/testScene.cpp similarity index 100% rename from test/tvgScene.cpp rename to test/testScene.cpp diff --git a/test/tvgDrawShape.cpp b/test/testShape.cpp similarity index 85% rename from test/tvgDrawShape.cpp rename to test/testShape.cpp index 7aaba5be..64603aea 100644 --- a/test/tvgDrawShape.cpp +++ b/test/testShape.cpp @@ -17,8 +17,8 @@ int main(int argc, char **argv) //Prepare a Shape (Rectangle) auto shape1 = tvg::ShapeNode::gen(); -// shape1->rect(0, 0, 400, 400, 0.1); //x, y, w, h, corner_radius -// shape1->fill(0, 255, 0, 255); //r, g, b, a + shape1->appendRect(0, 0, 400, 400, 0); //x, y, w, h, corner_radius + shape1->fill(0, 255, 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 diff --git a/test/tvgStroke.cpp b/test/testStroke.cpp similarity index 100% rename from test/tvgStroke.cpp rename to test/testStroke.cpp diff --git a/test/tvgUpdate.cpp b/test/testUpdate.cpp similarity index 100% rename from test/tvgUpdate.cpp rename to test/testUpdate.cpp