common shape: refactored interfaces.

hide engine() interface of shape that's not friendly one by users.
instead canvas would access shape internal data to update/draw it.

Now Paint cannot update itself but has to request to Canvas for it.

Change-Id: Ibafd0864a65c3c33238789d1a3e06c49c4378349
This commit is contained in:
Hermet Park 2020-05-04 21:10:04 +09:00
parent f4de03b01a
commit 211dafdaed
8 changed files with 137 additions and 100 deletions

View file

@ -43,6 +43,9 @@ private: \
const A& operator=(const A&) = delete; \
A()
#define _TIZENVG_DECLARE_ACCESSOR(A) \
friend A
#define _TIZENVG_DISABLE_CTOR(A) \
A() = delete; \
~A() = delete
@ -73,8 +76,6 @@ class TIZENVG_EXPORT Paint
public:
virtual ~Paint() {}
virtual int update(RenderMethod*) = 0;
virtual int rotate(float degree) = 0;
virtual int scale(float factor) = 0;
@ -102,6 +103,7 @@ public:
virtual int push(std::unique_ptr<Paint> paint) noexcept;
virtual int clear() noexcept;
virtual int update() noexcept;
virtual int update(Paint* paint) noexcept;
virtual int draw(bool async = true) noexcept;
virtual int sync() = 0;
@ -124,7 +126,6 @@ class TIZENVG_EXPORT Shape final : public Paint
public:
~Shape();
int update(RenderMethod* engine) noexcept override;
int reset() noexcept;
int moveTo(float x, float y) noexcept;
@ -150,10 +151,8 @@ public:
static std::unique_ptr<Shape> gen() noexcept;
//FIXME: Ugly... Better design?
void *engine() noexcept;
_TIZENVG_DECLARE_PRIVATE(Shape);
_TIZENVG_DECLARE_ACCESSOR(Canvas);
};
@ -170,7 +169,6 @@ class TIZENVG_EXPORT Scene final : public Paint
public:
~Scene();
int update(RenderMethod* engine) noexcept override;
int push(std::unique_ptr<Shape> shape) noexcept;
int rotate(float degree) noexcept override;

View file

@ -4,8 +4,9 @@ subdir('gl_engine')
source_file = [
'tvgCommon.h',
'tvgRenderCommon.h',
'tvgEngine.cpp',
'tvgShapePath.h',
'tvgShapeImpl.h',
'tvgEngine.cpp',
'tvgCanvas.cpp',
'tvgSwCanvas.cpp',
'tvgGlCanvas.cpp',

View file

@ -18,7 +18,7 @@
#define _TVG_CANVAS_CPP_
#include "tvgCommon.h"
#include "tvgShapeImpl.h"
/************************************************************************/
/* Internal Class Implementation */
@ -26,8 +26,8 @@
struct Canvas::Impl
{
vector<Paint*> nodes;
RenderMethod* renderer;
vector<Paint*> paints;
RenderMethod* renderer;
Impl(RenderMethod* pRenderer):renderer(pRenderer)
{
@ -40,34 +40,30 @@ struct Canvas::Impl
renderer->unref();
}
int reserve(size_t n)
{
nodes.reserve(n);
return 0;
}
int push(unique_ptr<Paint> paint)
{
Paint* node = paint.release();
assert(node);
nodes.push_back(node);
return node->update(renderer);
Paint* pPaint = paint.release();
assert(pPaint);
paints.push_back(pPaint);
return update(pPaint);
}
int clear()
{
assert(renderer);
for (auto node : nodes) {
if (Scene* scene = dynamic_cast<Scene*>(node)) {
for (auto paint : paints) {
if (auto scene = dynamic_cast<Scene*>(paint)) {
cout << "TODO: " << scene << endl;
} else if (Shape *shape = dynamic_cast<Shape*>(node)) {
if (!renderer->dispose(*shape, shape->engine())) return -1;
} else if (auto shape = dynamic_cast<Shape*>(paint)) {
auto p = shape->pImpl.get();
assert(p);
if (!p->dispose(*shape, *renderer)) return -1;
}
delete(node);
delete(paint);
}
nodes.clear();
paints.clear();
return 0;
}
@ -76,8 +72,29 @@ struct Canvas::Impl
{
assert(renderer);
for(auto node: nodes) {
if (!node->update(renderer)) return -1;
for(auto paint: paints) {
if (auto scene = dynamic_cast<Scene*>(paint)) {
cout << "TODO: " << scene << endl;
} else if (auto shape = dynamic_cast<Shape*>(paint)) {
auto p = shape->pImpl.get();
assert(p);
if (!p->update(*shape, *renderer)) return -1;
}
}
return 0;
}
int update(Paint* paint)
{
assert(renderer);
if (auto scene = dynamic_cast<Scene*>(paint)) {
cout << "TODO: " << scene << endl;
} else if (auto shape = dynamic_cast<Shape*>(paint)) {
auto p = shape->pImpl.get();
assert(p);
if (!p->update(*shape, *renderer)) return -1;
}
return 0;
@ -90,11 +107,13 @@ struct Canvas::Impl
//Clear render target before drawing
if (!renderer->clear()) return -1;
for(auto node: nodes) {
if (Scene* scene = dynamic_cast<Scene*>(node)) {
for(auto paint: paints) {
if (auto scene = dynamic_cast<Scene*>(paint)) {
cout << "TODO: " << scene << endl;
} else if (Shape *shape = dynamic_cast<Shape*>(node)) {
if (!renderer->render(*shape, shape->engine())) return -1;
} else if (auto shape = dynamic_cast<Shape*>(paint)) {
auto p = shape->pImpl.get();
assert(p);
if(!p->render(*shape, *renderer)) return -1;
}
}
return 0;
@ -121,7 +140,8 @@ int Canvas::reserve(size_t n) noexcept
{
auto impl = pImpl.get();
assert(impl);
return impl->reserve(n);
impl->paints.reserve(n);
return 0;
}
@ -158,11 +178,11 @@ int Canvas::update() noexcept
}
RenderMethod* Canvas::engine() noexcept
int Canvas::update(Paint* paint) noexcept
{
auto impl = pImpl.get();
assert(impl);
return impl->renderer;
return impl->update(paint);
}
#endif /* _TVG_CANVAS_CPP_ */

View file

@ -58,13 +58,6 @@ int Scene::push(unique_ptr<Shape> shape) noexcept
}
int Scene::update(RenderMethod* engine) noexcept
{
return 0;
}
int Scene::scale(float scaleFacator) noexcept
{
return 0;

View file

@ -18,46 +18,13 @@
#define _TVG_SHAPE_CPP_
#include "tvgCommon.h"
#include "tvgShapePath.h"
#include "tvgShapeImpl.h"
/************************************************************************/
/* Internal Class Implementation */
/************************************************************************/
constexpr auto PATH_KAPPA = 0.552284f;
struct ShapeFill
{
};
struct ShapeStroke
{
};
struct Shape::Impl
{
ShapeFill *fill = nullptr;
ShapeStroke *stroke = nullptr;
ShapePath *path = nullptr;
uint8_t color[4] = {0, 0, 0, 0}; //r, g, b, a
float scale = 1;
float rotate = 0;
void *edata = nullptr; //engine data
size_t flag = RenderUpdateFlag::None;
Impl() : path(new ShapePath)
{
}
~Impl()
{
if (path) delete(path);
if (stroke) delete(stroke);
if (fill) delete(fill);
}
};
/************************************************************************/
/* External Class Implementation */
@ -79,26 +46,6 @@ unique_ptr<Shape> Shape::gen() noexcept
}
void* Shape::engine() noexcept
{
auto impl = pImpl.get();
assert(impl);
return impl->edata;
}
int Shape::update(RenderMethod* engine) noexcept
{
auto impl = pImpl.get();
assert(impl);
impl->edata = engine->prepare(*this, impl->edata, static_cast<RenderUpdateFlag>(impl->flag));
impl->flag = RenderUpdateFlag::None;
if (impl->edata) return 0;
return -1;
}
int Shape::reset() noexcept
{
auto impl = pImpl.get();

78
src/lib/tvgShapeImpl.h Normal file
View file

@ -0,0 +1,78 @@
/*
* 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_IMPL_H_
#define _TVG_SHAPE_IMPL_H_
#include "tvgCommon.h"
#include "tvgShapePath.h"
/************************************************************************/
/* Internal Class Implementation */
/************************************************************************/
struct ShapeFill
{
};
struct ShapeStroke
{
};
struct Shape::Impl
{
ShapeFill *fill = nullptr;
ShapeStroke *stroke = nullptr;
ShapePath *path = nullptr;
uint8_t color[4] = {0, 0, 0, 0}; //r, g, b, a
float scale = 1;
float rotate = 0;
void *edata = nullptr; //engine data
size_t flag = RenderUpdateFlag::None;
Impl() : path(new ShapePath)
{
}
~Impl()
{
if (path) delete(path);
if (stroke) delete(stroke);
if (fill) delete(fill);
}
bool dispose(Shape& shape, RenderMethod& renderer)
{
return renderer.dispose(shape, edata);
}
bool render(Shape& shape, RenderMethod& renderer)
{
return renderer.render(shape, edata);
}
bool update(Shape& shape, RenderMethod& renderer)
{
edata = renderer.prepare(shape, edata, static_cast<RenderUpdateFlag>(flag));
flag = RenderUpdateFlag::None;
if (edata) return true;
return false;
}
};
#endif //_TVG_SHAPE_IMPL_H_

View file

@ -46,7 +46,7 @@ void transit_cb(Elm_Transit_Effect *effect, Elm_Transit* transit, double progres
pShape->appendRect(-100 + (800 * progress), -100 + (800 * progress), 200, 200, (100 * progress));
//Update shape for drawing (this may work asynchronously)
pShape->update(canvas->engine());
canvas->update(pShape);
//Draw Next frames
canvas->draw();

View file

@ -46,7 +46,7 @@ void transit_cb(Elm_Transit_Effect *effect, Elm_Transit* transit, double progres
pShape->rotate(360 * progress);
//Update shape for drawing (this may work asynchronously)
pShape->update(canvas->engine());
canvas->update(pShape);
//Draw Next frames
canvas->draw();