From 17170b81b51dfd7a99d1f3ef7f7d9038bf3502c0 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 27 Aug 2020 12:14:49 +0200 Subject: [PATCH] Clean-up of Shiny profiler integration, so that the intrusiver profiling can be controlled per module. --- src/clipper/clipper.cpp | 58 ++++++++++++++++++++-------------- src/libslic3r/ClipperUtils.cpp | 25 ++++++++++----- src/slic3r/CMakeLists.txt | 1 + src/slic3r/Utils/Profile.hpp | 19 +++++++++++ 4 files changed, 71 insertions(+), 32 deletions(-) create mode 100644 src/slic3r/Utils/Profile.hpp diff --git a/src/clipper/clipper.cpp b/src/clipper/clipper.cpp index b85cf9025..be4cb4a6a 100644 --- a/src/clipper/clipper.cpp +++ b/src/clipper/clipper.cpp @@ -48,9 +48,19 @@ #include #include #include -#include #include +// Profiling support using the Shiny intrusive profiler +//#define CLIPPERLIB_PROFILE +#if defined(SLIC3R_PROFILE) && defined(CLIPPERLIB_PROFILE) + #include + #define CLIPPERLIB_PROFILE_FUNC() PROFILE_FUNC() + #define CLIPPERLIB_PROFILE_BLOCK(name) PROFILE_BLOCK(name) +#else + #define CLIPPERLIB_PROFILE_FUNC() + #define CLIPPERLIB_PROFILE_BLOCK(name) +#endif + #ifdef use_xyz namespace ClipperLib_Z { #else /* use_xyz */ @@ -263,7 +273,7 @@ int PointInPolygon (const IntPoint &pt, OutPt *op) // This is potentially very expensive! O(n^2)! bool Poly2ContainsPoly1(OutPt *OutPt1, OutPt *OutPt2) { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); OutPt* op = OutPt1; do { @@ -714,7 +724,7 @@ TEdge* ClipperBase::ProcessBound(TEdge* E, bool NextIsForward) bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed) { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); // Remove duplicate end point from a closed input path. // Remove duplicate points from the end of the input path. int highI = (int)pg.size() -1; @@ -738,7 +748,7 @@ bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed) bool ClipperBase::AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed) { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); std::vector num_edges(ppg.size(), 0); int num_edges_total = 0; for (size_t i = 0; i < ppg.size(); ++ i) { @@ -780,7 +790,7 @@ bool ClipperBase::AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed) bool ClipperBase::AddPathInternal(const Path &pg, int highI, PolyType PolyTyp, bool Closed, TEdge* edges) { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); #ifdef use_lines if (!Closed && PolyTyp == ptClip) throw clipperException("AddPath: Open paths must be subject."); @@ -954,7 +964,7 @@ bool ClipperBase::AddPathInternal(const Path &pg, int highI, PolyType PolyTyp, b void ClipperBase::Clear() { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); m_MinimaList.clear(); m_edges.clear(); m_UseFullRange = false; @@ -966,7 +976,7 @@ void ClipperBase::Clear() // Sort the LML entries, initialize the left / right bound edges of each Local Minima. void ClipperBase::Reset() { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); if (m_MinimaList.empty()) return; //ie nothing to process std::sort(m_MinimaList.begin(), m_MinimaList.end(), [](const LocalMinimum& lm1, const LocalMinimum& lm2){ return lm1.Y < lm2.Y; }); @@ -995,7 +1005,7 @@ void ClipperBase::Reset() // Returns (0,0,0,0) for an empty rectangle. IntRect ClipperBase::GetBounds() { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); IntRect result; auto lm = m_MinimaList.begin(); if (lm == m_MinimaList.end()) @@ -1056,7 +1066,7 @@ Clipper::Clipper(int initOptions) : void Clipper::Reset() { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); ClipperBase::Reset(); m_Scanbeam = std::priority_queue(); m_Maxima.clear(); @@ -1071,7 +1081,7 @@ void Clipper::Reset() bool Clipper::Execute(ClipType clipType, Paths &solution, PolyFillType subjFillType, PolyFillType clipFillType) { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); if (m_HasOpenPaths) throw clipperException("Error: PolyTree struct is needed for open path clipping."); solution.resize(0); @@ -1089,7 +1099,7 @@ bool Clipper::Execute(ClipType clipType, Paths &solution, bool Clipper::Execute(ClipType clipType, PolyTree& polytree, PolyFillType subjFillType, PolyFillType clipFillType) { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); m_SubjFillType = subjFillType; m_ClipFillType = clipFillType; m_ClipType = clipType; @@ -1103,10 +1113,10 @@ bool Clipper::Execute(ClipType clipType, PolyTree& polytree, bool Clipper::ExecuteInternal() { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); bool succeeded = true; try { - PROFILE_BLOCK(Clipper_ExecuteInternal_Process); + CLIPPERLIB_PROFILE_BLOCK(Clipper_ExecuteInternal_Process); Reset(); if (m_MinimaList.empty()) return true; cInt botY = m_Scanbeam.top(); @@ -1131,13 +1141,13 @@ bool Clipper::ExecuteInternal() if (succeeded) { - PROFILE_BLOCK(Clipper_ExecuteInternal_Fix); + CLIPPERLIB_PROFILE_BLOCK(Clipper_ExecuteInternal_Fix); //fix orientations ... //FIXME Vojtech: Does it not invalidate the loop hierarchy maintained as OutRec::FirstLeft pointers? //FIXME Vojtech: The area is calculated with floats, it may not be numerically stable! { - PROFILE_BLOCK(Clipper_ExecuteInternal_Fix_orientations); + CLIPPERLIB_PROFILE_BLOCK(Clipper_ExecuteInternal_Fix_orientations); for (OutRec *outRec : m_PolyOuts) if (outRec->Pts && !outRec->IsOpen && (outRec->IsHole ^ m_ReverseOutput) == (Area(*outRec) > 0)) ReversePolyPtLinks(outRec->Pts); @@ -1147,7 +1157,7 @@ bool Clipper::ExecuteInternal() //unfortunately FixupOutPolygon() must be done after JoinCommonEdges() { - PROFILE_BLOCK(Clipper_ExecuteInternal_Fix_fixup); + CLIPPERLIB_PROFILE_BLOCK(Clipper_ExecuteInternal_Fix_fixup); for (OutRec *outRec : m_PolyOuts) if (outRec->Pts) { if (outRec->IsOpen) @@ -1401,7 +1411,7 @@ bool Clipper::IsContributing(const TEdge& edge) const // Called from Clipper::InsertLocalMinimaIntoAEL() and Clipper::IntersectEdges(). OutPt* Clipper::AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &Pt) { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); OutPt* result; TEdge *e, *prevE; if (IsHorizontal(*e2) || ( e1->Dx > e2->Dx )) @@ -1493,7 +1503,7 @@ void Clipper::CopyAELToSEL() // Called from Clipper::ExecuteInternal() void Clipper::InsertLocalMinimaIntoAEL(const cInt botY) { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); while (!m_MinimaList.empty() && m_MinimaList.back().Y == botY) { TEdge* lb = m_MinimaList.back().LeftBound; @@ -2043,7 +2053,7 @@ OutPt* Clipper::GetLastOutPt(TEdge *e) void Clipper::ProcessHorizontals() { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); TEdge* horzEdge = m_SortedEdges; while(horzEdge) { @@ -2414,7 +2424,7 @@ void Clipper::UpdateEdgeIntoAEL(TEdge *&e) bool Clipper::ProcessIntersections(const cInt topY) { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); if( !m_ActiveEdges ) return true; try { BuildIntersectList(topY); @@ -2569,7 +2579,7 @@ void Clipper::DoMaxima(TEdge *e) void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY) { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); TEdge* e = m_ActiveEdges; while( e ) { @@ -3177,7 +3187,7 @@ bool Clipper::JoinPoints(Join *j, OutRec* outRec1, OutRec* outRec2) // This is potentially very expensive! O(n^3)! void Clipper::FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec) const { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); //tests if NewOutRec contains the polygon before reassigning FirstLeft for (OutRec *outRec : m_PolyOuts) { @@ -3201,7 +3211,7 @@ void Clipper::FixupFirstLefts2(OutRec* OldOutRec, OutRec* NewOutRec) const void Clipper::JoinCommonEdges() { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); for (Join &join : m_Joins) { OutRec *outRec1 = GetOutRec(join.OutPt1->Idx); @@ -3771,7 +3781,7 @@ void ClipperOffset::DoRound(int j, int k) // http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Classes/Clipper/Properties/StrictlySimple.htm void Clipper::DoSimplePolygons() { - PROFILE_FUNC(); + CLIPPERLIB_PROFILE_FUNC(); size_t i = 0; while (i < m_PolyOuts.size()) { diff --git a/src/libslic3r/ClipperUtils.cpp b/src/libslic3r/ClipperUtils.cpp index d40d79b3d..16d985e9c 100644 --- a/src/libslic3r/ClipperUtils.cpp +++ b/src/libslic3r/ClipperUtils.cpp @@ -8,7 +8,16 @@ #include "SVG.hpp" #endif /* CLIPPER_UTILS_DEBUG */ -#include +// Profiling support using the Shiny intrusive profiler +//#define CLIPPER_UTILS_PROFILE +#if defined(SLIC3R_PROFILE) && defined(CLIPPER_UTILS_PROFILE) + #include + #define CLIPPERUTILS_PROFILE_FUNC() PROFILE_FUNC() + #define CLIPPERUTILS_PROFILE_BLOCK(name) PROFILE_BLOCK(name) +#else + #define CLIPPERUTILS_PROFILE_FUNC() + #define CLIPPERUTILS_PROFILE_BLOCK(name) +#endif #define CLIPPER_OFFSET_SHORTEST_EDGE_FACTOR (0.005f) @@ -50,7 +59,7 @@ err: void scaleClipperPolygon(ClipperLib::Path &polygon) { - PROFILE_FUNC(); + CLIPPERUTILS_PROFILE_FUNC(); for (ClipperLib::Path::iterator pit = polygon.begin(); pit != polygon.end(); ++pit) { pit->X <<= CLIPPER_OFFSET_POWER_OF_2; pit->Y <<= CLIPPER_OFFSET_POWER_OF_2; @@ -59,7 +68,7 @@ void scaleClipperPolygon(ClipperLib::Path &polygon) void scaleClipperPolygons(ClipperLib::Paths &polygons) { - PROFILE_FUNC(); + CLIPPERUTILS_PROFILE_FUNC(); for (ClipperLib::Paths::iterator it = polygons.begin(); it != polygons.end(); ++it) for (ClipperLib::Path::iterator pit = (*it).begin(); pit != (*it).end(); ++pit) { pit->X <<= CLIPPER_OFFSET_POWER_OF_2; @@ -69,7 +78,7 @@ void scaleClipperPolygons(ClipperLib::Paths &polygons) void unscaleClipperPolygon(ClipperLib::Path &polygon) { - PROFILE_FUNC(); + CLIPPERUTILS_PROFILE_FUNC(); for (ClipperLib::Path::iterator pit = polygon.begin(); pit != polygon.end(); ++pit) { pit->X += CLIPPER_OFFSET_SCALE_ROUNDING_DELTA; pit->Y += CLIPPER_OFFSET_SCALE_ROUNDING_DELTA; @@ -80,7 +89,7 @@ void unscaleClipperPolygon(ClipperLib::Path &polygon) void unscaleClipperPolygons(ClipperLib::Paths &polygons) { - PROFILE_FUNC(); + CLIPPERUTILS_PROFILE_FUNC(); for (ClipperLib::Paths::iterator it = polygons.begin(); it != polygons.end(); ++it) for (ClipperLib::Path::iterator pit = (*it).begin(); pit != (*it).end(); ++pit) { pit->X += CLIPPER_OFFSET_SCALE_ROUNDING_DELTA; @@ -790,7 +799,7 @@ ExPolygons simplify_polygons_ex(const Polygons &subject, bool preserve_collinear void safety_offset(ClipperLib::Paths* paths) { - PROFILE_FUNC(); + CLIPPERUTILS_PROFILE_FUNC(); // scale input scaleClipperPolygons(*paths); @@ -812,11 +821,11 @@ void safety_offset(ClipperLib::Paths* paths) if (! ccw) std::reverse(path.begin(), path.end()); { - PROFILE_BLOCK(safety_offset_AddPaths); + CLIPPERUTILS_PROFILE_BLOCK(safety_offset_AddPaths); co.AddPath((*paths)[i], ClipperLib::jtMiter, ClipperLib::etClosedPolygon); } { - PROFILE_BLOCK(safety_offset_Execute); + CLIPPERUTILS_PROFILE_BLOCK(safety_offset_Execute); // offset outside by 10um ClipperLib::Paths out_this; co.Execute(out_this, ccw ? 10.f * float(CLIPPER_OFFSET_SCALE) : -10.f * float(CLIPPER_OFFSET_SCALE)); diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index f8598cea0..8a2672c77 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -181,6 +181,7 @@ set(SLIC3R_GUI_SOURCES Utils/Bonjour.hpp Utils/PresetUpdater.cpp Utils/PresetUpdater.hpp + Utils/Profile.hpp Utils/UndoRedo.cpp Utils/UndoRedo.hpp Utils/HexFile.cpp diff --git a/src/slic3r/Utils/Profile.hpp b/src/slic3r/Utils/Profile.hpp new file mode 100644 index 000000000..5fb1e3116 --- /dev/null +++ b/src/slic3r/Utils/Profile.hpp @@ -0,0 +1,19 @@ +#ifndef slic3r_GUI_Profile_hpp_ +#define slic3r_GUI_Profile_hpp_ + +// Profiling support using the Shiny intrusive profiler +//#define SLIC3R_PROFILE_GUI +#if defined(SLIC3R_PROFILE) && defined(SLIC3R_PROFILE_GUI) + #include + #define SLIC3R_GUI_PROFILE_FUNC() PROFILE_FUNC() + #define SLIC3R_GUI_PROFILE_BLOCK(name) PROFILE_BLOCK(name) + #define SLIC3R_GUI_PROFILE_UPDATE() PROFILE_UPDATE() + #define SLIC3R_GUI_PROFILE_OUTPUT(x) PROFILE_OUTPUT(x) +#else + #define SLIC3R_GUI_PROFILE_FUNC() + #define SLIC3R_GUI_PROFILE_BLOCK(name) + #define SLIC3R_GUI_PROFILE_UPDATE() + #define SLIC3R_GUI_PROFILE_OUTPUT(x) +#endif + +#endif // slic3r_GUI_Profile_hpp_