From b0dad9d01d1f45d9174feefec4eda787450d9b37 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Fri, 17 Jun 2022 14:56:17 -0400 Subject: [PATCH] save a few more cycles by just using raw pointers. it's a bit uglier, but this is hard to represent with shared_ptr and I think it was the wrong choice anyways since the ownership chain is difficult to represent in a shared_ptr here. --- include/common/polylib.hh | 11 +++++- include/vis/vis.hh | 52 +++++++++++++------------- vis/flow.cc | 77 ++++++++++++++++++++------------------- vis/vis.cc | 77 +++++++++++++++++---------------------- 4 files changed, 110 insertions(+), 107 deletions(-) diff --git a/include/common/polylib.hh b/include/common/polylib.hh index fe43c13d..3572b478 100644 --- a/include/common/polylib.hh +++ b/include/common/polylib.hh @@ -784,11 +784,20 @@ public: return w; } + void flip_to(winding_base_t &winding_out) const + { + if (winding_out.size() < size()) { + winding_out.resize(size()); + } + + std::reverse_copy(begin(), end(), winding_out.begin()); + } + winding_base_t flip() const { winding_base_t result(count); - std::reverse_copy(begin(), end(), result.begin()); + flip_to(result); return result; } diff --git a/include/vis/vis.hh b/include/vis/vis.hh index 676ee195..7cd317d4 100644 --- a/include/vis/vis.hh +++ b/include/vis/vis.hh @@ -39,17 +39,6 @@ enum pstatus_t pstat_done }; -struct portal_t -{ - qplane3d plane; // normal pointing into neighbor - int leaf; // neighbor - std::shared_ptr winding; - pstatus_t status; - leafbits_t visbits, mightsee; - int nummightsee; - int numcansee; -}; - struct winding_t : polylib::winding_base_t { qvec3d origin; // Bounding sphere for fast clipping tests @@ -106,18 +95,31 @@ struct winding_t : polylib::winding_base_t Used for visdist to get the distance from a winding to a portal ============================================================================ */ - float distFromPortal(portal_t *p) - { - vec_t mindist = 1e20; - - for (size_t i = 0; i < size(); ++i) { - mindist = std::min(mindist, fabs(p->plane.distance_to(at(i)))); - } - - return mindist; - } + inline float distFromPortal(struct portal_t *p); }; +struct portal_t +{ + qplane3d plane; // normal pointing into neighbor + int leaf; // neighbor + winding_t winding; + pstatus_t status; + leafbits_t visbits, mightsee; + int nummightsee; + int numcansee; +}; + +inline float winding_t::distFromPortal(struct portal_t *p) +{ + vec_t mindist = 1e20; + + for (size_t i = 0; i < size(); ++i) { + mindist = std::min(mindist, fabs(p->plane.distance_to(at(i)))); + } + + return mindist; +} + struct sep_t { sep_t *next; @@ -149,7 +151,7 @@ struct pstack_t pstack_t *next; leaf_t *leaf; portal_t *portal; // portal exiting - std::shared_ptr source, pass; + winding_t *source, *pass; winding_t windings[STACK_WINDINGS]; // Fixed size windings bool windings_used[STACK_WINDINGS]; // whether the winding is used currently qplane3d portalplane; @@ -158,9 +160,9 @@ struct pstack_t int numseparators[2]; }; -std::shared_ptr AllocStackWinding(pstack_t *stack); -void FreeStackWinding(std::shared_ptr &w, pstack_t *stack); -std::shared_ptr ClipStackWinding(std::shared_ptr &in, pstack_t *stack, qplane3d *split); +winding_t *AllocStackWinding(pstack_t &stack); +void FreeStackWinding(winding_t *&w, pstack_t &stack); +winding_t *ClipStackWinding(winding_t *&in, pstack_t &stack, const qplane3d &split); struct threaddata_t { diff --git a/vis/flow.cc b/vis/flow.cc index 071e00dc..3634f745 100644 --- a/vis/flow.cc +++ b/vis/flow.cc @@ -29,8 +29,8 @@ static int c_leafskip; pointer, was measurably faster ============== */ -static void ClipToSeparators(const std::shared_ptr &source, const qplane3d src_pl, - const std::shared_ptr &pass, std::shared_ptr &target, unsigned int test, pstack_t *stack) +static void ClipToSeparators(winding_t *const &source, const qplane3d src_pl, + winding_t *const &pass, winding_t *&target, unsigned int test, pstack_t &stack) { int i, j, k, l; qplane3d sep; @@ -107,13 +107,13 @@ static void ClipToSeparators(const std::shared_ptr &source, const qpl /* Cache separating planes for tests 0, 1 */ if (test < 2) { - if (stack->numseparators[test] == MAX_SEPARATORS) + if (stack.numseparators[test] == MAX_SEPARATORS) FError("MAX_SEPARATORS"); - stack->separators[test][stack->numseparators[test]] = sep; - stack->numseparators[test]++; + stack.separators[test][stack.numseparators[test]] = sep; + stack.numseparators[test]++; } - target = ClipStackWinding(target, stack, &sep); + target = ClipStackWinding(target, stack, sep); if (!target) return; // target is not visible @@ -141,7 +141,7 @@ static int CheckStack(leaf_t *leaf, threaddata_t *thread) If src_portal is NULL, this is the originating leaf ================== */ -static void RecursiveLeafFlow(int leafnum, threaddata_t *thread, pstack_t *prevstack) +static void RecursiveLeafFlow(int leafnum, threaddata_t *thread, pstack_t &prevstack) { pstack_t stack; portal_t *p; @@ -170,7 +170,7 @@ static void RecursiveLeafFlow(int leafnum, threaddata_t *thread, pstack_t *prevs thread->base->numcansee++; } - prevstack->next = &stack; + prevstack.next = &stack; stack.next = NULL; stack.leaf = leaf; @@ -191,7 +191,7 @@ static void RecursiveLeafFlow(int leafnum, threaddata_t *thread, pstack_t *prevs for (i = 0; i < leaf->numportals; i++) { p = leaf->portals[i]; - if (!(*prevstack->mightsee)[p->leaf]) { + if (!(*prevstack.mightsee)[p->leaf]) { c_leafskip++; continue; // can't possibly see it } @@ -210,7 +210,7 @@ static void RecursiveLeafFlow(int leafnum, threaddata_t *thread, pstack_t *prevs uint32_t more = 0; numblocks = (portalleafs + leafbits_t::mask) >> leafbits_t::shift; for (j = 0; j < numblocks; j++) { - might[j] = prevstack->mightsee->data()[j] & test[j]; + might[j] = prevstack.mightsee->data()[j] & test[j]; more |= (might[j] & ~vis[j]); } @@ -223,7 +223,7 @@ static void RecursiveLeafFlow(int leafnum, threaddata_t *thread, pstack_t *prevs stack.portalplane = p->plane; backplane = -p->plane; - if (qv::epsilonEqual(prevstack->portalplane.normal, backplane.normal, EQUAL_EPSILON)) + if (qv::epsilonEqual(prevstack.portalplane.normal, backplane.normal, EQUAL_EPSILON)) continue; // can't go out a coplanar face c_portalcheck++; @@ -243,27 +243,28 @@ static void RecursiveLeafFlow(int leafnum, threaddata_t *thread, pstack_t *prevs */ /* Clip any part of the target portal behind the source portal */ - stack.pass = ClipStackWinding(p->winding, &stack, &thread->pstack_head.portalplane); + stack.pass = &p->winding; + stack.pass = ClipStackWinding(stack.pass, stack, thread->pstack_head.portalplane); if (!stack.pass) continue; - if (!prevstack->pass) { + if (!prevstack.pass) { // the second leaf can only be blocked if coplanar - stack.source = prevstack->source; - RecursiveLeafFlow(p->leaf, thread, &stack); - FreeStackWinding(stack.pass, &stack); + stack.source = prevstack.source; + RecursiveLeafFlow(p->leaf, thread, stack); + FreeStackWinding(stack.pass, stack); continue; } /* Clip any part of the target portal behind the pass portal */ - stack.pass = ClipStackWinding(stack.pass, &stack, &prevstack->portalplane); + stack.pass = ClipStackWinding(stack.pass, stack, prevstack.portalplane); if (!stack.pass) continue; /* Clip any part of the source portal in front of the target portal */ - stack.source = ClipStackWinding(prevstack->source, &stack, &backplane); + stack.source = ClipStackWinding(prevstack.source, stack, backplane); if (!stack.source) { - FreeStackWinding(stack.pass, &stack); + FreeStackWinding(stack.pass, stack); continue; } @@ -273,17 +274,17 @@ static void RecursiveLeafFlow(int leafnum, threaddata_t *thread, pstack_t *prevs if (options.level.value() > 0) { if (stack.numseparators[0]) { for (j = 0; j < stack.numseparators[0]; j++) { - stack.pass = ClipStackWinding(stack.pass, &stack, &stack.separators[0][j]); + stack.pass = ClipStackWinding(stack.pass, stack, stack.separators[0][j]); if (!stack.pass) break; } } else { /* Using prevstack source for separator cache correctness */ ClipToSeparators( - prevstack->source, thread->pstack_head.portalplane, prevstack->pass, stack.pass, 0, &stack); + prevstack.source, thread->pstack_head.portalplane, prevstack.pass, stack.pass, 0, stack); } if (!stack.pass) { - FreeStackWinding(stack.source, &stack); + FreeStackWinding(stack.source, stack); continue; } } @@ -292,34 +293,34 @@ static void RecursiveLeafFlow(int leafnum, threaddata_t *thread, pstack_t *prevs if (options.level.value() > 1) { if (stack.numseparators[1]) { for (j = 0; j < stack.numseparators[1]; j++) { - stack.pass = ClipStackWinding(stack.pass, &stack, &stack.separators[1][j]); + stack.pass = ClipStackWinding(stack.pass, stack, stack.separators[1][j]); if (!stack.pass) break; } } else { /* Using prevstack source for separator cache correctness */ - ClipToSeparators(prevstack->pass, prevstack->portalplane, prevstack->source, stack.pass, 1, &stack); + ClipToSeparators(prevstack.pass, prevstack.portalplane, prevstack.source, stack.pass, 1, stack); } if (!stack.pass) { - FreeStackWinding(stack.source, &stack); + FreeStackWinding(stack.source, stack); continue; } } /* TEST 2 :: target -> pass -> source */ if (options.level.value() > 2) { - ClipToSeparators(stack.pass, stack.portalplane, prevstack->pass, stack.source, 2, &stack); + ClipToSeparators(stack.pass, stack.portalplane, prevstack.pass, stack.source, 2, stack); if (!stack.source) { - FreeStackWinding(stack.pass, &stack); + FreeStackWinding(stack.pass, stack); continue; } } /* TEST 3 :: pass -> target -> source */ if (options.level.value() > 3) { - ClipToSeparators(prevstack->pass, prevstack->portalplane, stack.pass, stack.source, 3, &stack); + ClipToSeparators(prevstack.pass, prevstack.portalplane, stack.pass, stack.source, 3, stack); if (!stack.source) { - FreeStackWinding(stack.pass, &stack); + FreeStackWinding(stack.pass, stack); continue; } } @@ -327,10 +328,10 @@ static void RecursiveLeafFlow(int leafnum, threaddata_t *thread, pstack_t *prevs c_portalpass++; // flow through it for real - RecursiveLeafFlow(p->leaf, thread, &stack); + RecursiveLeafFlow(p->leaf, thread, stack); - FreeStackWinding(stack.source, &stack); - FreeStackWinding(stack.pass, &stack); + FreeStackWinding(stack.source, stack); + FreeStackWinding(stack.pass, stack); } } @@ -351,11 +352,11 @@ void PortalFlow(portal_t *p) data.base = p; data.pstack_head.portal = p; - data.pstack_head.source = p->winding; + data.pstack_head.source = &p->winding; data.pstack_head.portalplane = p->plane; data.pstack_head.mightsee = &p->mightsee; - RecursiveLeafFlow(p->leaf, &data, &data.pstack_head); + RecursiveLeafFlow(p->leaf, &data, data.pstack_head); } /* @@ -399,7 +400,7 @@ static void BasePortalThread(size_t portalnum) leafbits_t portalsee(numportals * 2); p = portals + portalnum; - winding_t &w = *p->winding; + winding_t &w = p->winding; p->mightsee.resize(portalleafs); @@ -407,7 +408,7 @@ static void BasePortalThread(size_t portalnum) if (tp == p) continue; - winding_t &tw = *tp->winding; + winding_t &tw = tp->winding; // Quick test - completely at the back? d = p->plane.distance_to(tw.origin); @@ -438,8 +439,8 @@ static void BasePortalThread(size_t portalnum) continue; // no points on back if (options.visdist.value() > 0) { - if (tp->winding->distFromPortal(p) > options.visdist.value() || - p->winding->distFromPortal(tp) > options.visdist.value()) + if (tp->winding.distFromPortal(p) > options.visdist.value() || + p->winding.distFromPortal(tp) > options.visdist.value()) continue; } diff --git a/vis/vis.cc b/vis/vis.cc index 1391b30f..1d154d89 100644 --- a/vis/vis.cc +++ b/vis/vis.cc @@ -63,10 +63,6 @@ void vis_settings::initialize(int argc, const char **argv) settings::vis_settings options; fs::path portalfile, statefile, statetmpfile; - -struct noop_delete { - void operator()(winding_t *p) const { } -}; /* ================== @@ -75,14 +71,12 @@ struct noop_delete { Return a pointer to a free fixed winding on the stack ================== */ -std::shared_ptr AllocStackWinding(pstack_t *stack) +winding_t *AllocStackWinding(pstack_t &stack) { for (size_t i = 0; i < STACK_WINDINGS; i++) { - if (!stack->windings_used[i]) { - stack->windings_used[i] = true; - return std::shared_ptr(&stack->windings[i], [stack, i]([[maybe_unused]] winding_t *) { - stack->windings_used[i] = false; - }); + if (!stack.windings_used[i]) { + stack.windings_used[i] = true; + return &stack.windings[i]; } } @@ -101,11 +95,12 @@ std::shared_ptr AllocStackWinding(pstack_t *stack) for stack windings is safe ================== */ -void FreeStackWinding(std::shared_ptr &w, pstack_t *stack) +void FreeStackWinding(winding_t *&w, pstack_t &stack) { for (size_t i = 0; i < STACK_WINDINGS; i++) { - if (stack->windings_used[i] && &stack->windings[i] == w.get()) { - w.reset(); + if (stack.windings_used[i] && &stack.windings[i] == w) { + stack.windings_used[i] = false; + w = nullptr; return; } } @@ -121,7 +116,7 @@ void FreeStackWinding(std::shared_ptr &w, pstack_t *stack) is returned. ================== */ -std::shared_ptr ClipStackWinding(std::shared_ptr &in, pstack_t *stack, qplane3d *split) +winding_t *ClipStackWinding(winding_t *&in, pstack_t &stack, const qplane3d &split) { vec_t *dists = (vec_t *)alloca(sizeof(vec_t) * (in->size() + 1)); int *sides = (int *)alloca(sizeof(int) * (in->size() + 1)); @@ -129,10 +124,10 @@ std::shared_ptr ClipStackWinding(std::shared_ptr &in, psta int i, j; /* Fast test first */ - vec_t dot = split->distance_to(in->origin); + vec_t dot = split.distance_to(in->origin); if (dot < -in->radius) { FreeStackWinding(in, stack); - return NULL; + return nullptr; } else if (dot > in->radius) { return in; } @@ -144,7 +139,7 @@ std::shared_ptr ClipStackWinding(std::shared_ptr &in, psta /* determine sides for each point */ for (i = 0; i < in->size(); i++) { - dot = split->distance_to((*in)[i]); + dot = split.distance_to((*in)[i]); dists[i] = dot; if (dot > ON_EPSILON) sides[i] = SIDE_FRONT; @@ -167,7 +162,7 @@ std::shared_ptr ClipStackWinding(std::shared_ptr &in, psta if (!counts[0]) { FreeStackWinding(in, stack); - return NULL; + return nullptr; } if (!counts[1]) return in; @@ -201,10 +196,10 @@ std::shared_ptr ClipStackWinding(std::shared_ptr &in, psta vec_t fraction = dists[i] / (dists[i] - dists[i + 1]); for (j = 0; j < 3; j++) { /* avoid round off error when possible */ - if (split->normal[j] == 1) - mid[j] = split->dist; - else if (split->normal[j] == -1) - mid[j] = -split->dist; + if (split.normal[j] == 1) + mid[j] = split.dist; + else if (split.normal[j] == -1) + mid[j] = -split.dist; else mid[j] = p1[j] + fraction * (p2[j] - p1[j]); } @@ -279,16 +274,14 @@ portal_t *GetNextPortal(void) Called with the lock held. ============= */ -static void UpdateMightsee(const leaf_t *source, const leaf_t *dest) +static void UpdateMightsee(const leaf_t &source, const leaf_t &dest) { - int i, leafnum; - portal_t *p; - - leafnum = dest - leafs; - for (i = 0; i < source->numportals; i++) { - p = source->portals[i]; - if (p->status != pstat_none) + size_t leafnum = &dest - leafs; + for (size_t i = 0; i < source.numportals; i++) { + portal_t *p = source.portals[i]; + if (p->status != pstat_none) { continue; + } if (p->mightsee[leafnum]) { p->mightsee[leafnum] = false; p->nummightsee--; @@ -312,7 +305,6 @@ static void PortalCompleted(portal_t *completed) int i, j, k, bit, numblocks; int leafnum; const portal_t *p, *p2; - const leaf_t *myleaf; const uint32_t *might, *vis; uint32_t changed; @@ -324,9 +316,9 @@ static void PortalCompleted(portal_t *completed) * For each portal on the leaf, check the leafs we eliminated from * mightsee during the full vis so far. */ - myleaf = &leafs[completed->leaf]; - for (i = 0; i < myleaf->numportals; i++) { - p = myleaf->portals[i]; + const leaf_t &myleaf = leafs[completed->leaf]; + for (i = 0; i < myleaf.numportals; i++) { + p = myleaf.portals[i]; if (p->status != pstat_done) continue; @@ -342,10 +334,10 @@ static void PortalCompleted(portal_t *completed) * If any of these changed bits are still visible from another * portal, we can't update yet. */ - for (k = 0; k < myleaf->numportals; k++) { + for (k = 0; k < myleaf.numportals; k++) { if (k == i) continue; - p2 = myleaf->portals[k]; + p2 = myleaf.portals[k]; if (p2->status == pstat_done) changed &= ~p2->visbits.data()[j]; else @@ -361,7 +353,7 @@ static void PortalCompleted(portal_t *completed) bit = ffsl(changed) - 1; changed &= ~nth_bit(bit); leafnum = (j << leafbits_t::shift) + bit; - UpdateMightsee(leafs + leafnum, myleaf); + UpdateMightsee(leafs[leafnum], myleaf); } } } @@ -660,10 +652,11 @@ static void LoadPortals(const fs::path &name, mbsp_t *bsp) for (i = 0, p = portals; i < numportals; i++) { const auto &sourceportal = prtfile.portals[i]; - p->winding = std::make_shared(sourceportal.winding.begin(), sourceportal.winding.end()); + p->winding = { sourceportal.winding.begin(), sourceportal.winding.end() }; + p->winding.SetWindingSphere(); // calc plane - plane = p->winding->plane(); + plane = p->winding.plane(); // create forward portal l = &leafs[sourceportal.leafnums[0]]; @@ -674,7 +667,6 @@ static void LoadPortals(const fs::path &name, mbsp_t *bsp) p->plane = -plane; p->leaf = sourceportal.leafnums[1]; - p->winding->SetWindingSphere(); p++; // create backwards portal @@ -685,11 +677,10 @@ static void LoadPortals(const fs::path &name, mbsp_t *bsp) l->numportals++; // Create a reverse winding - const auto flipped = sourceportal.winding.flip(); - p->winding = std::make_shared(flipped.begin(), flipped.end()); + sourceportal.winding.flip_to(p->winding); + p->winding.SetWindingSphere(); p->plane = plane; p->leaf = sourceportal.leafnums[0]; - p->winding->SetWindingSphere(); p++; }