struct Point
{
- float x;
- float y;
+ float x, y;
};
{
public:
virtual ~PaintNode() {}
- virtual int dispose(RenderMethod* engine) = 0;
virtual int update(RenderMethod* engine) = 0;
};
public:
~ShapeNode();
- int dispose(RenderMethod* engine) noexcept override;
int update(RenderMethod* engine) noexcept override;
int clear() noexcept;
static std::unique_ptr<ShapeNode> gen() noexcept;
+ //FIXME: Ugly... Better design?
+ void *engine() noexcept;
+
_TIZENVG_DECLARE_PRIVATE(ShapeNode);
};
public:
~SceneNode();
- int dispose(RenderMethod* engine) noexcept override;
int update(RenderMethod* engine) noexcept override;
int push(std::unique_ptr<ShapeNode> shape) noexcept;
//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;
/* 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;
}
sdata = static_cast<GlShape*>(calloc(1, sizeof(GlShape)));
assert(sdata);
}
+
+ //TODO:
+
return sdata;
}
{
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;
'tvgSwRenderer.cpp',
'tvgSwShape.cpp',
'tvgSwRle.cpp',
+ 'tvgSwRaster.cpp',
]
swraster_dep = declare_dependency(
SwRleData* rleRender(const SwShape& sdata);
+bool rasterShape(Surface& surface, SwShape& sdata, size_t color);
+
#endif /* _TVG_SW_COMMON_H_ */
--- /dev/null
+/*
+ * 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
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)
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;
}
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;
#include "tvgCommon.h"
-/************************************************************************/
-/* Internal Class Implementation */
-/************************************************************************/
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_ */
GlCanvas::~GlCanvas()
{
- cout << "GlCanvas(" << this << ") destroyed!" << endl;
}
int GlCanvas::update() noexcept
{
- return 0;
+ auto impl = pImpl.get();
+ assert(impl);
+ return impl->update();
}
return impl->renderer;
}
+
+int GlCanvas::draw(bool async) noexcept
+{
+ auto impl = pImpl.get();
+ assert(impl);
+ return impl->draw();
+}
+
#endif /* _TVG_GLCANVAS_CPP_ */
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;
};
/* External Class Implementation */
/************************************************************************/
-SceneNode :: SceneNode() : pImpl(make_unique<Impl>())
+SceneNode::SceneNode() : pImpl(make_unique<Impl>())
{
}
-SceneNode :: ~SceneNode()
+SceneNode::~SceneNode()
{
cout << "SceneNode(" << this << ") destroyed!" << endl;
}
}
-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;
}
-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);
}
-int ShapeNode :: clear() noexcept
+int ShapeNode::clear() noexcept
{
auto impl = pImpl.get();
assert(impl);
}
-int ShapeNode :: pathCommands(const PathCommand** cmds) const noexcept
+int ShapeNode::pathCommands(const PathCommand** cmds) const noexcept
{
auto impl = pImpl.get();
assert(impl && cmds);
}
-int ShapeNode :: pathCoords(const Point** pts) const noexcept
+int ShapeNode::pathCoords(const Point** pts) const noexcept
{
auto impl = pImpl.get();
assert(impl && pts);
}
-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);
}
-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);
}
-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);
struct SwCanvas::Impl : CanvasBase
{
- uint32_t* buffer = nullptr;
- int stride = 0;
- int height = 0;
-
Impl() : CanvasBase(SwRenderer::inst()) {}
};
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;
}
int SwCanvas::draw(bool async) noexcept
{
- return 0;
+ auto impl = pImpl.get();
+ assert(impl);
+ return impl->draw();
}
SwCanvas::~SwCanvas()
{
- cout << "SwCanvas(" << this << ") destroyed!" << endl;
}
int SwCanvas::update() noexcept
{
- return 0;
+ auto impl = pImpl.get();
+ assert(impl);
+ return impl->update();
}
//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