RenderPath work Start of a larger effort to migrate RenderPath to be immutable. If this can be done ... - all 'stretchy' operations to incrementally build the path will be local to the runtime, reducing cross-talk with host - output of Renderer will all be immutable, and therefore ready to be 'recorded' and replayed (in another thread) Migration steps: - stop calling makeEmptyRenderPath(), since this implies subsequent edits - then RenderPath need not inherit from CommandPath - then (optional) can make RenderPath reference-counted (like RenderImage) Also in this PR - remove unused Difference option from PathSpace enum Diffs= 19578d209 Try using rawpath
diff --git a/.rive_head b/.rive_head index 75ce8b6..900be39 100644 --- a/.rive_head +++ b/.rive_head
@@ -1 +1 @@ -b8ca8ded5ae71e0b4519d90e87a56bcb711e0576 +19578d2097615090bbda3f214549bc41bbc391f9
diff --git a/include/rive/artboard.hpp b/include/rive/artboard.hpp index df5ce4b..e3a5962 100644 --- a/include/rive/artboard.hpp +++ b/include/rive/artboard.hpp
@@ -41,8 +41,8 @@ std::vector<NestedArtboard*> m_NestedArtboards; unsigned int m_DirtDepth = 0; - std::unique_ptr<CommandPath> m_BackgroundPath; - std::unique_ptr<CommandPath> m_ClipPath; + std::unique_ptr<RenderPath> m_BackgroundPath; + std::unique_ptr<RenderPath> m_ClipPath; Factory* m_Factory = nullptr; Drawable* m_FirstDrawable = nullptr; bool m_IsInstance = false; @@ -95,8 +95,9 @@ }; void draw(Renderer* renderer, DrawOption = DrawOption::kNormal); - CommandPath* clipPath() const { return m_ClipPath.get(); } - CommandPath* backgroundPath() const { return m_BackgroundPath.get(); } + // TODO: can we remove these getters? Who is calling them? + RenderPath* clipPath() const { return m_ClipPath.get(); } + RenderPath* backgroundPath() const { return m_BackgroundPath.get(); } const std::vector<Core*>& objects() const { return m_Objects; } const std::vector<NestedArtboard*> nestedArtboards() const { return m_NestedArtboards; }
diff --git a/include/rive/factory.hpp b/include/rive/factory.hpp index 7389869..3ee59a8 100644 --- a/include/rive/factory.hpp +++ b/include/rive/factory.hpp
@@ -47,6 +47,7 @@ Span<const PathVerb> verbs, FillRule) = 0; + // Deprecated -- working to make RenderPath's immutable virtual std::unique_ptr<RenderPath> makeEmptyRenderPath() = 0; virtual std::unique_ptr<RenderPaint> makeRenderPaint() = 0; @@ -54,6 +55,11 @@ virtual std::unique_ptr<RenderImage> decodeImage(Span<const uint8_t>) = 0; virtual rcp<RenderFont> decodeFont(Span<const uint8_t>) { return nullptr; } + + // Non-virtual helpers + + std::unique_ptr<RenderPath> makeRenderPath(const AABB&); + std::unique_ptr<RenderPath> makeRenderPath(const RawPath&, FillRule); }; } // namespace rive
diff --git a/include/rive/shapes/path_space.hpp b/include/rive/shapes/path_space.hpp index 76bbf21..8e93a0a 100644 --- a/include/rive/shapes/path_space.hpp +++ b/include/rive/shapes/path_space.hpp
@@ -8,8 +8,7 @@ Neither = 0, Local = 1 << 1, World = 1 << 2, - Difference = 1 << 3, - Clipping = 1 << 4 + Clipping = 1 << 3 }; inline constexpr PathSpace operator&(PathSpace lhs, PathSpace rhs) {
diff --git a/src/artboard.cpp b/src/artboard.cpp index e9458d8..94026da 100644 --- a/src/artboard.cpp +++ b/src/artboard.cpp
@@ -8,6 +8,7 @@ #include "rive/draw_target_placement.hpp" #include "rive/drawable.hpp" #include "rive/animation/keyed_object.hpp" +#include "rive/factory.hpp" #include "rive/node.hpp" #include "rive/renderer.hpp" #include "rive/shapes/paint/shape_paint.hpp" @@ -52,8 +53,9 @@ StatusCode Artboard::initialize() { StatusCode code; - m_BackgroundPath = makeCommandPath(PathSpace::Neither); - m_ClipPath = makeCommandPath(PathSpace::Neither); + // these will be re-built in update() -- are they needed here? + m_BackgroundPath = factory()->makeEmptyRenderPath(); + m_ClipPath = factory()->makeEmptyRenderPath(); // onAddedDirty guarantees that all objects are now available so they can be // looked up by index/id. This is where nodes find their parents, but they @@ -326,13 +328,15 @@ sortDrawOrder(); } if (hasDirt(value, ComponentDirt::Path)) { - m_ClipPath->reset(); + AABB bg = {-width() * originX(), -height() * originY(), width(), height()}; + AABB clip; if (m_FrameOrigin) { - m_ClipPath->addRect(0.0f, 0.0f, width(), height()); + clip = {0.0f, 0.0f, width(), height()}; } else { - m_ClipPath->addRect(-width() * originX(), -height() * originY(), width(), height()); + clip = bg; } - m_BackgroundPath->addRect(-width() * originX(), -height() * originY(), width(), height()); + m_ClipPath = factory()->makeRenderPath(clip); + m_BackgroundPath = factory()->makeRenderPath(bg); } } @@ -414,7 +418,7 @@ void Artboard::draw(Renderer* renderer, DrawOption option) { renderer->save(); if (clip()) { - renderer->clipPath(m_ClipPath->renderPath()); + renderer->clipPath(m_ClipPath.get()); } if (m_FrameOrigin) { @@ -426,7 +430,7 @@ if (option != DrawOption::kHideBG) { for (auto shapePaint : m_ShapePaints) { - shapePaint->draw(renderer, backgroundPath()); + shapePaint->draw(renderer, m_BackgroundPath.get()); } } @@ -623,4 +627,4 @@ scene = this->animationAt(0); } return scene; -} \ No newline at end of file +}
diff --git a/src/factory.cpp b/src/factory.cpp new file mode 100644 index 0000000..693a287 --- /dev/null +++ b/src/factory.cpp
@@ -0,0 +1,30 @@ +/* + * Copyright 2022 Rive + */ + +#include "rive/factory.hpp" +#include "rive/math/aabb.hpp" +#include "rive/math/raw_path.hpp" + +using namespace rive; + +std::unique_ptr<RenderPath> Factory::makeRenderPath(const AABB& r) { + const Vec2D pts[] = { + {r.left(), r.top()}, + {r.right(), r.top()}, + {r.right(), r.bottom()}, + {r.left(), r.bottom()}, + }; + const PathVerb verbs[] = { + PathVerb::move, + PathVerb::line, + PathVerb::line, + PathVerb::line, + PathVerb::close, + }; + return this->makeRenderPath(pts, verbs, FillRule::nonZero); +} + +std::unique_ptr<RenderPath> Factory::makeRenderPath(const RawPath& rp, FillRule fill) { + return this->makeRenderPath(rp.points(), rp.verbs(), fill); +}
diff --git a/viewer/src/viewer_content/text_content.cpp b/viewer/src/viewer_content/text_content.cpp index 01190a9..2d97a0d 100644 --- a/viewer/src/viewer_content/text_content.cpp +++ b/viewer/src/viewer_content/text_content.cpp
@@ -52,8 +52,7 @@ auto trans = rive::Mat2D::fromTranslate(origin.x + run.xpos[i], origin.y); auto rawpath = font->getPath(run.glyphs[i]); rawpath.transformInPlace(trans * scale); - auto path = - factory->makeRenderPath(rawpath.points(), rawpath.verbs(), rive::FillRule::nonZero); + auto path = factory->makeRenderPath(rawpath, rive::FillRule::nonZero); renderer->drawPath(path.get(), paint.get()); } } @@ -114,14 +113,20 @@ } #endif +static std::unique_ptr<rive::RenderPath> make_line(rive::Factory* factory, + rive::Vec2D a, + rive::Vec2D b) { + rive::Vec2D pts[] = {a, b}; + rive::PathVerb vbs[] = {rive::PathVerb::move, rive::PathVerb::line}; + return factory->makeRenderPath(pts, vbs, rive::FillRule::nonZero); +} + static void draw_line(rive::Factory* factory, rive::Renderer* renderer, float x) { auto paint = factory->makeRenderPaint(); paint->style(rive::RenderPaintStyle::stroke); paint->thickness(1); paint->color(0xFFFFFFFF); - auto path = factory->makeEmptyRenderPath(); - path->move({x, 0}); - path->line({x, 1000}); + auto path = make_line(factory, {x, 0}, {x, 1000}); renderer->drawPath(path.get(), paint.get()); }
diff --git a/viewer/src/viewer_content/textpath_content.cpp b/viewer/src/viewer_content/textpath_content.cpp index 80856d8..83b1051 100644 --- a/viewer/src/viewer_content/textpath_content.cpp +++ b/viewer/src/viewer_content/textpath_content.cpp
@@ -60,9 +60,7 @@ //////////////////////////////////////////////////////////////////////////////////// static std::unique_ptr<RenderPath> make_rpath(const RawPath& path) { - return ViewerContent::RiveFactory()->makeRenderPath(path.points(), - path.verbs(), - FillRule::nonZero); + return ViewerContent::RiveFactory()->makeRenderPath(path, FillRule::nonZero); } static void stroke_path(Renderer* renderer, const RawPath& path, float size, ColorInt color) {
diff --git a/viewer/src/viewer_content/trimpath_content.cpp b/viewer/src/viewer_content/trimpath_content.cpp index 89c9bb9..f5f321c 100644 --- a/viewer/src/viewer_content/trimpath_content.cpp +++ b/viewer/src/viewer_content/trimpath_content.cpp
@@ -33,9 +33,7 @@ //////////////////////////////////////////////////////////////////////////////////// static std::unique_ptr<RenderPath> make_rpath(const RawPath& path) { - return ViewerContent::RiveFactory()->makeRenderPath(path.points(), - path.verbs(), - FillRule::nonZero); + return ViewerContent::RiveFactory()->makeRenderPath(path, FillRule::nonZero); } static void stroke_path(Renderer* renderer, const RawPath& path, float size, ColorInt color) {