diff --git a/inc/tizenvg.h b/inc/tizenvg.h index 88abfddd..309badd6 100644 --- a/inc/tizenvg.h +++ b/inc/tizenvg.h @@ -50,16 +50,23 @@ protected: \ A() = delete; \ ~A() = delete +#define _TIZENVG_IDENTIFIER(A) \ +protected: \ + unsigned A##_Id + namespace tvg { +class RenderMethod; +class Scene; +class Canvas; + + enum class TIZENVG_EXPORT Result { Success = 0, InvalidArguments, InsufficientCondition, FailedAllocation, MemoryCorruption, Unknown }; enum class TIZENVG_EXPORT PathCommand { Close = 0, MoveTo, LineTo, CubicTo }; enum class TIZENVG_EXPORT StrokeCap { Square = 0, Round, Butt }; enum class TIZENVG_EXPORT StrokeJoin { Bevel = 0, Round, Miter }; -class RenderMethod; -class Scene; struct Point { @@ -85,6 +92,10 @@ public: virtual Result translate(float x, float y) = 0; virtual Result bounds(float* x, float* y, float* w, float* h) const = 0; + + _TIZENVG_IDENTIFIER(Paint); + _TIZENVG_DECLARE_ACCESSOR(Scene); + _TIZENVG_DECLARE_ACCESSOR(Canvas); }; diff --git a/src/lib/gl_engine/tvgGlRenderer.cpp b/src/lib/gl_engine/tvgGlRenderer.cpp index 14bdbaa3..1ca9588b 100644 --- a/src/lib/gl_engine/tvgGlRenderer.cpp +++ b/src/lib/gl_engine/tvgGlRenderer.cpp @@ -109,7 +109,8 @@ uint32_t GlRenderer::ref() GlRenderer* GlRenderer::inst() { - return dynamic_cast(RenderInitializer::inst(renderInit)); + //We know renderer type, avoid dynamic_cast for performance. + return static_cast(RenderInitializer::inst(renderInit)); } diff --git a/src/lib/sw_engine/tvgSwRenderer.cpp b/src/lib/sw_engine/tvgSwRenderer.cpp index d2143fe7..59c49105 100644 --- a/src/lib/sw_engine/tvgSwRenderer.cpp +++ b/src/lib/sw_engine/tvgSwRenderer.cpp @@ -151,7 +151,8 @@ uint32_t SwRenderer::ref() SwRenderer* SwRenderer::inst() { - return dynamic_cast(RenderInitializer::inst(renderInit)); + //We know renderer type, avoid dynamic_cast for performance. + return static_cast(RenderInitializer::inst(renderInit)); } #endif /* _TVG_SW_RENDERER_CPP_ */ diff --git a/src/lib/tvgCanvasImpl.h b/src/lib/tvgCanvasImpl.h index 782dd94a..078385a3 100644 --- a/src/lib/tvgCanvasImpl.h +++ b/src/lib/tvgCanvasImpl.h @@ -53,9 +53,12 @@ struct Canvas::Impl assert(renderer); for (auto paint : paints) { - if (auto scene = dynamic_cast(paint)) { + if (paint->Paint_Id == PAINT_ID_SCENE) { + //We know renderer type, avoid dynamic_cast for performance. + auto scene = static_cast(paint); if (!SCENE_IMPL->clear(*renderer)) return Result::InsufficientCondition; - } else if (auto shape = dynamic_cast(paint)) { + } else { + auto shape = static_cast(paint); if (!SHAPE_IMPL->dispose(*shape, *renderer)) return Result::InsufficientCondition; } delete(paint); @@ -70,9 +73,12 @@ struct Canvas::Impl assert(renderer); for(auto paint: paints) { - if (auto scene = dynamic_cast(paint)) { + if (paint->Paint_Id == PAINT_ID_SCENE) { + //We know renderer type, avoid dynamic_cast for performance. + auto scene = static_cast(paint); if (!SCENE_IMPL->update(*renderer, nullptr)) return Result::InsufficientCondition; - } else if (auto shape = dynamic_cast(paint)) { + } else { + auto shape = static_cast(paint); if (!SHAPE_IMPL->update(*shape, *renderer, nullptr)) return Result::InsufficientCondition; } } @@ -83,9 +89,12 @@ struct Canvas::Impl { assert(renderer); - if (auto scene = dynamic_cast(paint)) { + if (paint->Paint_Id == PAINT_ID_SCENE) { + //We know renderer type, avoid dynamic_cast for performance. + auto scene = static_cast(paint); if (!SCENE_IMPL->update(*renderer)) return Result::InsufficientCondition; - } else if (auto shape = dynamic_cast(paint)) { + } else { + auto shape = static_cast(paint); if (!SHAPE_IMPL->update(*shape, *renderer)) return Result::InsufficientCondition; } return Result::Success; @@ -99,9 +108,12 @@ struct Canvas::Impl if (!renderer->clear()) return Result::InsufficientCondition; for(auto paint: paints) { - if (auto scene = dynamic_cast(paint)) { + if (paint->Paint_Id == PAINT_ID_SCENE) { + //We know renderer type, avoid dynamic_cast for performance. + auto scene = static_cast(paint); if(!SCENE_IMPL->render(*renderer)) return Result::InsufficientCondition; - } else if (auto shape = dynamic_cast(paint)) { + } else { + auto shape = static_cast(paint); if(!SHAPE_IMPL->render(*shape, *renderer)) return Result::InsufficientCondition; } } diff --git a/src/lib/tvgCommon.h b/src/lib/tvgCommon.h index c404f1fa..ca18cca6 100644 --- a/src/lib/tvgCommon.h +++ b/src/lib/tvgCommon.h @@ -31,6 +31,9 @@ using namespace tvg; #define SCENE_IMPL scene->pImpl.get() #define SHAPE_IMPL shape->pImpl.get() +#define PAINT_ID_SHAPE 0 +#define PAINT_ID_SCENE 1 + #include "tvgRenderCommon.h" #include "tvgShapePath.h" #include "tvgShapeImpl.h" diff --git a/src/lib/tvgGlCanvas.cpp b/src/lib/tvgGlCanvas.cpp index 024fed50..7d3903c2 100644 --- a/src/lib/tvgGlCanvas.cpp +++ b/src/lib/tvgGlCanvas.cpp @@ -47,7 +47,8 @@ GlCanvas::~GlCanvas() Result GlCanvas::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h) noexcept { - auto renderer = dynamic_cast(Canvas::pImpl.get()->renderer); + //We know renderer type, avoid dynamic_cast for performance. + auto renderer = static_cast(Canvas::pImpl.get()->renderer); if (!renderer) return Result::MemoryCorruption; if (!renderer->target(buffer, stride, w, h)) return Result::Unknown; diff --git a/src/lib/tvgScene.cpp b/src/lib/tvgScene.cpp index 75e27207..a1c7a7f7 100644 --- a/src/lib/tvgScene.cpp +++ b/src/lib/tvgScene.cpp @@ -25,7 +25,7 @@ Scene::Scene() : pImpl(make_unique()) { - + Paint_Id = PAINT_ID_SCENE; } diff --git a/src/lib/tvgSceneImpl.h b/src/lib/tvgSceneImpl.h index edaa6d8b..1f1fa14e 100644 --- a/src/lib/tvgSceneImpl.h +++ b/src/lib/tvgSceneImpl.h @@ -39,9 +39,12 @@ struct Scene::Impl bool clear(RenderMethod& renderer) { for (auto paint : paints) { - if (auto scene = dynamic_cast(paint)) { + if (paint->Paint_Id == PAINT_ID_SCENE) { + //We know renderer type, avoid dynamic_cast for performance. + auto scene = static_cast(paint); if (!SCENE_IMPL->clear(renderer)) return false; - } else if (auto shape = dynamic_cast(paint)) { + } else { + auto shape = static_cast(paint); if (!SHAPE_IMPL->dispose(*shape, renderer)) return false; } delete(paint); @@ -54,9 +57,12 @@ struct Scene::Impl bool updateInternal(RenderMethod &renderer, const RenderTransform* transform, uint32_t flag) { for(auto paint: paints) { - if (auto scene = dynamic_cast(paint)) { + if (paint->Paint_Id == PAINT_ID_SCENE) { + //We know renderer type, avoid dynamic_cast for performance. + auto scene = static_cast(paint); if (!SCENE_IMPL->update(renderer, transform, flag)) return false; - } else if (auto shape = dynamic_cast(paint)) { + } else { + auto shape = static_cast(paint); if (!SHAPE_IMPL->update(*shape, renderer, transform, flag)) return false; } } @@ -91,9 +97,12 @@ struct Scene::Impl bool render(RenderMethod &renderer) { for(auto paint: paints) { - if (auto scene = dynamic_cast(paint)) { + if (paint->Paint_Id == PAINT_ID_SCENE) { + //We know renderer type, avoid dynamic_cast for performance. + auto scene = static_cast(paint); if(!SCENE_IMPL->render(renderer)) return false; - } else if (auto shape = dynamic_cast(paint)) { + } else { + auto shape = static_cast(paint); if(!SHAPE_IMPL->render(*shape, renderer)) return false; } } @@ -113,9 +122,12 @@ struct Scene::Impl auto w2 = 0.0f; auto h2 = 0.0f; - if (auto scene = dynamic_cast(paint)) { + if (paint->Paint_Id == PAINT_ID_SCENE) { + //We know renderer type, avoid dynamic_cast for performance. + auto scene = static_cast(paint); if (!SCENE_IMPL->bounds(&x2, &y2, &w2, &h2)) return false; - } else if (auto shape = dynamic_cast(paint)) { + } else { + auto shape = static_cast(paint); if (!SHAPE_IMPL->bounds(&x2, &y2, &w2, &h2)) return false; } diff --git a/src/lib/tvgShape.cpp b/src/lib/tvgShape.cpp index ad1736b1..5119ac8e 100644 --- a/src/lib/tvgShape.cpp +++ b/src/lib/tvgShape.cpp @@ -32,6 +32,7 @@ constexpr auto PATH_KAPPA = 0.552284f; Shape :: Shape() : pImpl(make_unique()) { + Paint_Id = PAINT_ID_SHAPE; } diff --git a/src/lib/tvgSwCanvas.cpp b/src/lib/tvgSwCanvas.cpp index 560a975b..780e4636 100644 --- a/src/lib/tvgSwCanvas.cpp +++ b/src/lib/tvgSwCanvas.cpp @@ -47,7 +47,8 @@ SwCanvas::~SwCanvas() Result SwCanvas::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h) noexcept { - auto renderer = dynamic_cast(Canvas::pImpl.get()->renderer); + //We know renderer type, avoid dynamic_cast for performance. + auto renderer = static_cast(Canvas::pImpl.get()->renderer); if (!renderer) return Result::MemoryCorruption; if (!renderer->target(buffer, stride, w, h)) return Result::InvalidArguments;