Merge sbs_render_and_advance into master Diffs= 9945a7d2d Merge sbs_render_and_advance into master (#5181)
diff --git a/.rive_head b/.rive_head index bd6b5f4..47859ae 100644 --- a/.rive_head +++ b/.rive_head
@@ -1 +1 @@ -542e320d21dc6c27dca04bc7c853bd5f1ae6970a +9945a7d2d52d1b8e40c31ec12b541de3c93e3795
diff --git a/build/premake5.lua b/build/premake5.lua index a3a3061..9dc168a 100644 --- a/build/premake5.lua +++ b/build/premake5.lua
@@ -108,6 +108,12 @@ targetdir '%{cfg.system}/arm64/bin/%{cfg.buildcfg}' objdir '%{cfg.system}/arm64/obj/%{cfg.buildcfg}' end + + filter "system:emscripten" + do + buildoptions {"-pthread"} + end + filter 'configurations:debug' do defines {'DEBUG'}
diff --git a/dependencies/premake5_harfbuzz.lua b/dependencies/premake5_harfbuzz.lua index 9140e67..99d4e2a 100644 --- a/dependencies/premake5_harfbuzz.lua +++ b/dependencies/premake5_harfbuzz.lua
@@ -233,6 +233,11 @@ 'HB_NO_WIN1256' } + filter "system:emscripten" + do + buildoptions {"-pthread"} + end + filter 'toolset:clang' do flags {'FatalWarnings'}
diff --git a/dependencies/premake5_sheenbidi.lua b/dependencies/premake5_sheenbidi.lua index 02de111..f3652c8 100644 --- a/dependencies/premake5_sheenbidi.lua +++ b/dependencies/premake5_sheenbidi.lua
@@ -16,6 +16,19 @@ sheenbidi .. '/Headers' } + buildoptions { + '-Wall', + '-ansi', + '-pedantic' + } + + linkoptions {'-r'} + + filter "system:emscripten" + do + buildoptions {"-pthread"} + end + filter 'configurations:debug' do files { @@ -47,14 +60,6 @@ } end - buildoptions { - '-Wall', - '-ansi', - '-pedantic' - } - - linkoptions {'-r'} - filter 'configurations:debug' do defines {'DEBUG'}
diff --git a/include/rive/artboard.hpp b/include/rive/artboard.hpp index 7fe73eb..dd1bf12 100644 --- a/include/rive/artboard.hpp +++ b/include/rive/artboard.hpp
@@ -97,6 +97,7 @@ kHideFG, }; void draw(Renderer* renderer, DrawOption = DrawOption::kNormal); + void addToRenderPath(RenderPath* path, const Mat2D& transform); #ifdef TESTING RenderPath* clipPath() const { return m_ClipPath.get(); } @@ -156,10 +157,47 @@ // provided. int defaultStateMachineIndex() const; - /// Make an instance of this artboard, must be explictly deleted when no - /// longer needed. - // Deprecated... - std::unique_ptr<ArtboardInstance> instance() const; + /// Make an instance of this artboard. + template <typename T = ArtboardInstance> std::unique_ptr<T> instance() const + { + std::unique_ptr<T> artboardClone(new T); + artboardClone->copy(*this); + + artboardClone->m_Factory = m_Factory; + artboardClone->m_FrameOrigin = m_FrameOrigin; + artboardClone->m_IsInstance = true; + + std::vector<Core*>& cloneObjects = artboardClone->m_Objects; + cloneObjects.push_back(artboardClone.get()); + + if (!m_Objects.empty()) + { + // Skip first object (artboard). + auto itr = m_Objects.begin(); + while (++itr != m_Objects.end()) + { + auto object = *itr; + cloneObjects.push_back(object == nullptr ? nullptr : object->clone()); + } + } + + for (auto animation : m_Animations) + { + artboardClone->m_Animations.push_back(animation); + } + for (auto stateMachine : m_StateMachines) + { + artboardClone->m_StateMachines.push_back(stateMachine); + } + + if (artboardClone->initialize() != StatusCode::Ok) + { + artboardClone = nullptr; + } + + assert(artboardClone->isInstance()); + return artboardClone; + } /// Returns true if the artboard is an instance of another bool isInstance() const { return m_IsInstance; }
diff --git a/include/rive/nested_artboard.hpp b/include/rive/nested_artboard.hpp index befffb8..e075c86 100644 --- a/include/rive/nested_artboard.hpp +++ b/include/rive/nested_artboard.hpp
@@ -28,6 +28,8 @@ void nest(Artboard* artboard); + ArtboardInstance* artboard() { return m_Instance.get(); } + StatusCode import(ImportStack& importStack) override; Core* clone() const override; bool advance(float elapsedSeconds);
diff --git a/include/rive/shapes/path.hpp b/include/rive/shapes/path.hpp index 0df5914..437e9ae 100644 --- a/include/rive/shapes/path.hpp +++ b/include/rive/shapes/path.hpp
@@ -38,6 +38,7 @@ Shape* m_Shape = nullptr; std::unique_ptr<CommandPath> m_CommandPath; std::vector<PathVertex*> m_Vertices; + bool m_deferredPathDirt = false; public: Shape* shape() const { return m_Shape; }
diff --git a/include/rive/shapes/shape.hpp b/include/rive/shapes/shape.hpp index 9c236eb..75b9a66 100644 --- a/include/rive/shapes/shape.hpp +++ b/include/rive/shapes/shape.hpp
@@ -26,7 +26,9 @@ Shape(); void buildDependencies() override; bool collapse(bool value) override; + bool canDeferPathUpdate(); void addPath(Path* path); + void addToRenderPath(RenderPath* commandPath, const Mat2D& transform); std::vector<Path*>& paths() { return m_Paths; } bool wantDifferencePath() const { return m_WantDifferencePath; }
diff --git a/skia/renderer/build/macosx/build_skia_renderer.sh b/skia/renderer/build/macosx/build_skia_renderer.sh index d3710a5..fe9a3b4 100755 --- a/skia/renderer/build/macosx/build_skia_renderer.sh +++ b/skia/renderer/build/macosx/build_skia_renderer.sh
@@ -45,8 +45,7 @@ export PREMAKE=$DEPENDENCIES/bin/premake5 pushd .. - -$PREMAKE --file=./premake5.lua gmake2 $OTHER_OPTIONS +$PREMAKE --scripts=../../../build --file=./premake5.lua gmake2 $OTHER_OPTIONS for var in "$@"; do if [[ $var = "clean" ]]; then
diff --git a/src/artboard.cpp b/src/artboard.cpp index 74dc6c0..fa08fd1 100644 --- a/src/artboard.cpp +++ b/src/artboard.cpp
@@ -16,6 +16,7 @@ #include "rive/importers/backboard_importer.hpp" #include "rive/nested_artboard.hpp" #include "rive/animation/state_machine_instance.hpp" +#include "rive/shapes/shape.hpp" #include <stack> #include <unordered_map> @@ -452,9 +453,6 @@ // re-run the update. if (m_DirtDepth < i) { - // We put this in here just to know if we need to - // keep this around... - assert(false); break; } } @@ -556,7 +554,25 @@ renderer->restore(); } -AABB Artboard::bounds() const { return AABB(0.0f, 0.0f, width(), height()); } +void Artboard::addToRenderPath(RenderPath* path, const Mat2D& transform) +{ + for (auto drawable = m_FirstDrawable; drawable != nullptr; drawable = drawable->prev) + { + if (drawable->isHidden() || !drawable->is<Shape>()) + { + continue; + } + Shape* shape = drawable->as<Shape>(); + shape->addToRenderPath(path, transform); + } +} + +AABB Artboard::bounds() const +{ + return m_FrameOrigin + ? AABB(0.0f, 0.0f, width(), height()) + : AABB::fromLTWH(-width() * originX(), -height() * originY(), width(), height()); +} bool Artboard::isTranslucent(const LinearAnimation* anim) const { @@ -656,46 +672,46 @@ return index; } -std::unique_ptr<ArtboardInstance> Artboard::instance() const -{ - std::unique_ptr<ArtboardInstance> artboardClone(new ArtboardInstance); - artboardClone->copy(*this); +// std::unique_ptr<ArtboardInstance> Artboard::instance() const +// { +// std::unique_ptr<ArtboardInstance> artboardClone(new ArtboardInstance); +// artboardClone->copy(*this); - artboardClone->m_Factory = m_Factory; - artboardClone->m_FrameOrigin = m_FrameOrigin; - artboardClone->m_IsInstance = true; +// artboardClone->m_Factory = m_Factory; +// artboardClone->m_FrameOrigin = m_FrameOrigin; +// artboardClone->m_IsInstance = true; - std::vector<Core*>& cloneObjects = artboardClone->m_Objects; - cloneObjects.push_back(artboardClone.get()); +// std::vector<Core*>& cloneObjects = artboardClone->m_Objects; +// cloneObjects.push_back(artboardClone.get()); - if (!m_Objects.empty()) - { - // Skip first object (artboard). - auto itr = m_Objects.begin(); - while (++itr != m_Objects.end()) - { - auto object = *itr; - cloneObjects.push_back(object == nullptr ? nullptr : object->clone()); - } - } +// if (!m_Objects.empty()) +// { +// // Skip first object (artboard). +// auto itr = m_Objects.begin(); +// while (++itr != m_Objects.end()) +// { +// auto object = *itr; +// cloneObjects.push_back(object == nullptr ? nullptr : object->clone()); +// } +// } - for (auto animation : m_Animations) - { - artboardClone->m_Animations.push_back(animation); - } - for (auto stateMachine : m_StateMachines) - { - artboardClone->m_StateMachines.push_back(stateMachine); - } +// for (auto animation : m_Animations) +// { +// artboardClone->m_Animations.push_back(animation); +// } +// for (auto stateMachine : m_StateMachines) +// { +// artboardClone->m_StateMachines.push_back(stateMachine); +// } - if (artboardClone->initialize() != StatusCode::Ok) - { - artboardClone = nullptr; - } +// if (artboardClone->initialize() != StatusCode::Ok) +// { +// artboardClone = nullptr; +// } - assert(artboardClone->isInstance()); - return artboardClone; -} +// assert(artboardClone->isInstance()); +// return artboardClone; +// } void Artboard::frameOrigin(bool value) {
diff --git a/src/shapes/path.cpp b/src/shapes/path.cpp index 3732d07..5d17027 100644 --- a/src/shapes/path.cpp +++ b/src/shapes/path.cpp
@@ -232,6 +232,10 @@ { m_Shape->pathChanged(); } + if (m_deferredPathDirt) + { + addDirt(ComponentDirt::Path); + } } void Path::update(ComponentDirt value) @@ -241,6 +245,12 @@ assert(m_CommandPath != nullptr); if (hasDirt(value, ComponentDirt::Path)) { + if (m_Shape->canDeferPathUpdate()) + { + m_deferredPathDirt = true; + return; + } + m_deferredPathDirt = false; // Build path doesn't explicitly rewind because we use it to concatenate // multiple built paths into a single command path (like the hit // tester).
diff --git a/src/shapes/path_composer.cpp b/src/shapes/path_composer.cpp index a9c93d0..30905fc 100644 --- a/src/shapes/path_composer.cpp +++ b/src/shapes/path_composer.cpp
@@ -32,14 +32,15 @@ { if (hasDirt(value, ComponentDirt::Path)) { - auto space = m_Shape->pathSpace(); - if (m_Shape->renderOpacity() == 0 && (space & PathSpace::Clipping) != PathSpace::Clipping) + if (m_Shape->canDeferPathUpdate()) { m_deferredPathDirt = true; return; } m_deferredPathDirt = false; + auto space = m_Shape->pathSpace(); + if ((space & PathSpace::Local) == PathSpace::Local) { if (m_LocalPath == nullptr)
diff --git a/src/shapes/points_path.cpp b/src/shapes/points_path.cpp index 1d20b03..a6d70d6 100644 --- a/src/shapes/points_path.cpp +++ b/src/shapes/points_path.cpp
@@ -1,6 +1,7 @@ #include "rive/shapes/points_path.hpp" #include "rive/shapes/vertex.hpp" #include "rive/shapes/path_vertex.hpp" +#include "rive/shapes/shape.hpp" #include "rive/bones/skin.hpp" #include "rive/span.hpp" @@ -27,8 +28,10 @@ void PointsPath::update(ComponentDirt value) { - if (hasDirt(value, ComponentDirt::Path) && skin() != nullptr) + if (hasDirt(value, ComponentDirt::Path) && skin() != nullptr && !m_Shape->canDeferPathUpdate()) { + // Path tracks re-adding ComponentDirt::Path if we deferred due to to + // shape being invisible. skin()->deform(Span<Vertex*>((Vertex**)m_Vertices.data(), m_Vertices.size())); } Super::update(value);
diff --git a/src/shapes/shape.cpp b/src/shapes/shape.cpp index 9e4e8b1..2695410 100644 --- a/src/shapes/shape.cpp +++ b/src/shapes/shape.cpp
@@ -18,6 +18,11 @@ m_Paths.push_back(path); } +bool Shape::canDeferPathUpdate() +{ + return renderOpacity() == 0 && (pathSpace() & PathSpace::Clipping) != PathSpace::Clipping; +} + void Shape::update(ComponentDirt value) { Super::update(value); @@ -44,6 +49,19 @@ invalidateStrokeEffects(); } +void Shape::addToRenderPath(RenderPath* path, const Mat2D& transform) +{ + auto space = pathSpace(); + if ((space & PathSpace::Local) == PathSpace::Local) + { + path->addPath(m_PathComposer.localPath(), transform * worldTransform()); + } + else + { + path->addPath(m_PathComposer.worldPath(), transform); + } +} + void Shape::draw(Renderer* renderer) { if (renderOpacity() == 0.0f)