Skip to content

Commit

Permalink
Performance|Client: Minor optimizations
Browse files Browse the repository at this point in the history
These optimizations are mostly related to avoiding repeated
Surface -> MaterialAnimator lookups.
  • Loading branch information
skyjake committed Nov 2, 2016
1 parent 886547b commit 53a36de
Show file tree
Hide file tree
Showing 14 changed files with 108 additions and 54 deletions.
1 change: 0 additions & 1 deletion doomsday/apps/client/include/render/store.h
Expand Up @@ -47,4 +47,3 @@ struct Store
};

#endif // DENG_CLIENT_RENDER_STORE_H

4 changes: 2 additions & 2 deletions doomsday/apps/client/include/world/bspleaf.h
Expand Up @@ -87,8 +87,8 @@ class BspLeaf : public BspElement
* intended for legacy compatibility logics which don't care if a subspace exists at
* the leaf, or not.
*/
Sector *sectorPtr();
Sector const *sectorPtr() const;
inline Sector *sectorPtr() { return _sector; }
inline Sector const *sectorPtr() const { return _sector; }

/**
* Attribute this BSP leaf to the given world @a sector.
Expand Down
3 changes: 1 addition & 2 deletions doomsday/apps/client/include/world/subsector.h
Expand Up @@ -226,8 +226,7 @@ class SubsectorCirculator

/// Returns the current half-edge of a non-empty sequence.
de::HEdge &operator * () const {
if (!_current)
{
if (!_current) {
/// @throw NullError Attempted to dereference a "null" circulator.
throw NullError("SubsectorCirculator::operator *", "Circulator references an empty sequence");
}
Expand Down
11 changes: 10 additions & 1 deletion doomsday/apps/client/include/world/surface.h
Expand Up @@ -33,6 +33,7 @@

#ifdef __CLIENT__
class Decoration;
class MaterialAnimator;
#endif

/**
Expand Down Expand Up @@ -205,6 +206,14 @@ class Surface : public world::MapElement
de::Uri composeMaterialUri() const;

#ifdef __CLIENT__

MaterialAnimator *materialAnimator() const;

/**
* Resets all lookups that are used for accelerating common operations.
*/
void resetLookups();

//- Origin smoothing --------------------------------------------------------------------

/// Notified when the @em sharp material origin changes.
Expand Down Expand Up @@ -270,4 +279,4 @@ class Surface : public world::MapElement
DENG2_PRIVATE(d)
};

#endif // DENG_WORLD_SURFACE_H
#endif // DENG_WORLD_SURFACE_H
6 changes: 3 additions & 3 deletions doomsday/apps/client/src/client/clientsubsector.cpp
Expand Up @@ -1011,9 +1011,9 @@ DENG2_PIMPL(ClientSubsector)
Vector3d bottomRight, topLeft;
if (prepareGeometry(surface, topLeft, bottomRight, materialOrigin))
{
MaterialAnimator &animator =
surface.material().as<ClientMaterial>()
.getAnimator(Rend_MapSurfaceMaterialSpec());
MaterialAnimator &animator = *surface.materialAnimator();
//surface.material().as<ClientMaterial>()
// .getAnimator(Rend_MapSurfaceMaterialSpec());

projectDecorations(surface, animator, materialOrigin, topLeft, bottomRight);
}
Expand Down
27 changes: 27 additions & 0 deletions doomsday/apps/client/src/render/rend_main.cpp
Expand Up @@ -323,6 +323,33 @@ void Rend_ResetLookups()
{
lookupMapSurfaceMaterialSpec = nullptr;
lookupSpriteMaterialAnimators.clear();

if (ClientApp::world().hasMap())
{
auto &map = ClientApp::world().map();

map.forAllSectors([] (Sector &sector)
{
sector.forAllPlanes([] (Plane &plane)
{
plane.surface().resetLookups();
return LoopContinue;
});
return LoopContinue;
});

map.forAllLines([] (Line &line)
{
auto resetFunc = [] (Surface &surface) {
surface.resetLookups();
return LoopContinue;
};

line.front().forAllSurfaces(resetFunc);
line.back() .forAllSurfaces(resetFunc);
return LoopContinue;
});
}
}

static void reportWallDrawn(Line &line)
Expand Down
15 changes: 9 additions & 6 deletions doomsday/apps/client/src/render/shadowedge.cpp
Expand Up @@ -93,16 +93,19 @@ static bool middleMaterialCoversOpening(LineSide const &side)
if (!side.hasSector()) return false; // Never.

if (!side.hasSections()) return false;
if (!side.middle().hasMaterial()) return false;
//if (!side.middle().hasMaterial()) return false;

MaterialAnimator &matAnimator = side.middle().material().as<ClientMaterial>()
.getAnimator(Rend_MapSurfaceMaterialSpec());
MaterialAnimator *matAnimator = side.middle().materialAnimator();
/* material().as<ClientMaterial>()
.getAnimator(Rend_MapSurfaceMaterialSpec());*/

if (!matAnimator) return false;

// Ensure we have up to date info about the material.
matAnimator.prepare();
matAnimator->prepare();

// Might the material cover the opening?
if (matAnimator.isOpaque() && !side.middle().blendMode() && side.middle().opacity() >= 1)
if (matAnimator->isOpaque() && !side.middle().blendMode() && side.middle().opacity() >= 1)
{
// Stretched middles always cover the opening.
if (side.isFlagged(SDF_MIDDLE_STRETCH))
Expand Down Expand Up @@ -132,7 +135,7 @@ static bool middleMaterialCoversOpening(LineSide const &side)
openTop = frontSec.ceiling().heightSmoothed();
}

if (matAnimator.dimensions().y >= openTop - openBottom)
if (matAnimator->dimensions().y >= openTop - openBottom)
{
// Possibly; check the placement.
if(side.leftHEdge()) // possibility of degenerate BSP leaf
Expand Down
14 changes: 2 additions & 12 deletions doomsday/apps/client/src/world/base/bspleaf.cpp
Expand Up @@ -38,14 +38,14 @@ bool BspLeaf::hasSubspace() const

ConvexSubspace &BspLeaf::subspace() const
{
if(hasSubspace()) return *_subspace;
if (hasSubspace()) return *_subspace;
/// @throw MissingSubspaceError Attempted with no subspace attributed.
throw MissingSubspaceError("BspLeaf::subspace", "No subspace is attributed");
}

ConvexSubspace *BspLeaf::subspacePtr() const
{
return hasSubspace() ? &subspace() : nullptr;
return _subspace;
}

void BspLeaf::setSubspace(ConvexSubspace *newSubspace)
Expand All @@ -65,16 +65,6 @@ void BspLeaf::setSubspace(ConvexSubspace *newSubspace)
}
}

Sector *BspLeaf::sectorPtr()
{
return _sector;
}

Sector const *BspLeaf::sectorPtr() const
{
return _sector;
}

void BspLeaf::setSector(Sector *newSector)
{
_sector = newSector;
Expand Down
27 changes: 15 additions & 12 deletions doomsday/apps/client/src/world/base/maputil.cpp
Expand Up @@ -153,15 +153,17 @@ bool R_SideBackClosed(LineSide const &side, bool ignoreOpacity)
if(backSec.floor().heightSmoothed() >= frontSec.ceiling().heightSmoothed()) return true;

// Perhaps a middle material completely covers the opening?
if(side.middle().hasMaterial())
//if(side.middle().hasMaterial())

if (MaterialAnimator *matAnimator = side.middle().materialAnimator())
{
MaterialAnimator &matAnimator = static_cast<ClientMaterial &>(side.middle().material())
.getAnimator(Rend_MapSurfaceMaterialSpec());
//MaterialAnimator &matAnimator = static_cast<ClientMaterial &>(side.middle().material())
// .getAnimator(Rend_MapSurfaceMaterialSpec());

// Ensure we have up to date info about the material.
matAnimator.prepare();
matAnimator->prepare();

if(ignoreOpacity || (matAnimator.isOpaque() && !side.middle().blendMode() && side.middle().opacity() >= 1))
if(ignoreOpacity || (matAnimator->isOpaque() && !side.middle().blendMode() && side.middle().opacity() >= 1))
{
// Stretched middles always cover the opening.
if(side.isFlagged(SDF_MIDDLE_STRETCH))
Expand All @@ -171,7 +173,7 @@ bool R_SideBackClosed(LineSide const &side, bool ignoreOpacity)
{
coord_t openRange, openBottom, openTop;
openRange = visOpenRange(side, &openBottom, &openTop);
if(matAnimator.dimensions().y >= openRange)
if(matAnimator->dimensions().y >= openRange)
{
// Possibly; check the placement.
WallEdge edge(WallSpec::fromMapSide(side, LineSide::Middle),
Expand Down Expand Up @@ -233,25 +235,26 @@ static bool middleMaterialCoversOpening(LineSide const &side)
if(!side.hasSector()) return false; // Never.

if(!side.hasSections()) return false;
if(!side.middle().hasMaterial()) return false;
//if(!side.middle().hasMaterial()) return false;

// Stretched middles always cover the opening.
if(side.isFlagged(SDF_MIDDLE_STRETCH))
return true;

MaterialAnimator &matAnimator = side.middle().material()
.as<ClientMaterial>().getAnimator(Rend_MapSurfaceMaterialSpec());
MaterialAnimator *matAnimator = side.middle().materialAnimator();
//.as<ClientMaterial>().getAnimator(Rend_MapSurfaceMaterialSpec());
if (!matAnimator) return false;

// Ensure we have up to date info about the material.
matAnimator.prepare();
matAnimator->prepare();

if(matAnimator.isOpaque() && !side.middle().blendMode() && side.middle().opacity() >= 1)
if(matAnimator->isOpaque() && !side.middle().blendMode() && side.middle().opacity() >= 1)
{
if(side.leftHEdge()) // possibility of degenerate BSP leaf.
{
coord_t openRange, openBottom, openTop;
openRange = visOpenRange(side, &openBottom, &openTop);
if(matAnimator.dimensions().y >= openRange)
if(matAnimator->dimensions().y >= openRange)
{
// Possibly; check the placement.
WallEdge edge(WallSpec::fromMapSide(side, LineSide::Middle), *side.leftHEdge(), Line::From);
Expand Down
13 changes: 5 additions & 8 deletions doomsday/apps/client/src/world/base/plane.cpp
Expand Up @@ -424,18 +424,15 @@ void Plane::removeMover(ClPlaneMover &mover)

bool Plane::castsShadow() const
{
if(surface().hasMaterial())
if (auto *matAnim = d->surface.materialAnimator())
{
MaterialAnimator &matAnimator = surface().material().as<ClientMaterial>()
.getAnimator(Rend_MapSurfaceMaterialSpec());

// Ensure we have up to date info about the material.
matAnimator.prepare();
matAnim->prepare();

if(!matAnimator.material().isDrawable()) return false;
if(matAnimator.material().isSkyMasked()) return false;
if (!matAnim->material().isDrawable()) return false;
if (matAnim->material().isSkyMasked()) return false;

return de::fequal(matAnimator.glowStrength(), 0);
return de::fequal(matAnim->glowStrength(), 0);
}
return false;
}
Expand Down
9 changes: 7 additions & 2 deletions doomsday/apps/client/src/world/base/subsector.cpp
Expand Up @@ -115,7 +115,12 @@ Sector &Subsector::sector()

Sector const &Subsector::sector() const
{
return const_cast<Subsector *>(this)->sector();
if (!d->sector)
{
d->sector = firstSubspace().bspLeaf().sectorPtr();
DENG2_ASSERT(d->sector);
}
return *d->sector;
}

dint Subsector::subspaceCount() const
Expand All @@ -126,7 +131,7 @@ dint Subsector::subspaceCount() const
ConvexSubspace &Subsector::firstSubspace() const
{
DENG2_ASSERT(!d->subspaces.isEmpty());
return *d->subspaces.first();
return *d->subspaces.constFirst();
}

LoopResult Subsector::forAllSubspaces(std::function<LoopResult (ConvexSubspace &)> func) const
Expand Down
24 changes: 23 additions & 1 deletion doomsday/apps/client/src/world/base/surface.cpp
Expand Up @@ -80,6 +80,7 @@ DENG2_PIMPL(Surface)
Vector2f oldOrigin[2]; ///< Old @em sharp surface space material origins, for smoothing.
Vector2f originSmoothed; ///< @em smoothed surface space material origin.
Vector2f originSmoothedDelta; ///< Delta between @em sharp and @em smoothed.
MaterialAnimator *matAnimator = nullptr;
#endif

Impl(Public *i) : Base(i)
Expand Down Expand Up @@ -261,6 +262,10 @@ Surface &Surface::setMaterial(Material *newMaterial, bool isMissingFix)
}
}

#ifdef __CLIENT__
d->matAnimator = nullptr;
#endif

// Notify interested parties.
DENG2_FOR_AUDIENCE2(MaterialChange, i) i->surfaceMaterialChanged(*this);

Expand Down Expand Up @@ -563,6 +568,23 @@ dint Surface::setProperty(DmuArgs const &args)

#ifdef __CLIENT__

MaterialAnimator *Surface::materialAnimator() const
{
if (!d->material) return nullptr;

if (!d->matAnimator)
{
d->matAnimator = &d->material->as<ClientMaterial>()
.getAnimator(Rend_MapSurfaceMaterialSpec());
}
return d->matAnimator;
}

void Surface::resetLookups()
{
d->matAnimator = nullptr;
}

Vector2f const &Surface::originSmoothed() const
{
return d->originSmoothed;
Expand Down Expand Up @@ -620,7 +642,7 @@ dfloat Surface::glow(Vector3f &color) const
return 0;
}

MaterialAnimator &matAnimator = material().as<ClientMaterial>().getAnimator(Rend_MapSurfaceMaterialSpec());
MaterialAnimator &matAnimator = *materialAnimator(); //material().as<ClientMaterial>().getAnimator(Rend_MapSurfaceMaterialSpec());

// Ensure we've up to date info about the material.
matAnimator.prepare();
Expand Down
4 changes: 2 additions & 2 deletions doomsday/apps/client/src/world/contactspreader.cpp
Expand Up @@ -222,8 +222,8 @@ struct ContactSpreader
openTop = fromSubsec.visCeiling().heightSmoothed();
}

MaterialAnimator &matAnimator = facingLineSide.middle().material()
.as<ClientMaterial>().getAnimator(Rend_MapSurfaceMaterialSpec());
MaterialAnimator &matAnimator = *facingLineSide.middle().materialAnimator();
//.as<ClientMaterial>().getAnimator(Rend_MapSurfaceMaterialSpec());

// Ensure we have up to date info about the material.
matAnimator.prepare();
Expand Down
4 changes: 2 additions & 2 deletions doomsday/sdk/libcore/include/de/data/binarytree.h
Expand Up @@ -144,7 +144,7 @@ class BinaryTree
*/
inline BinaryTree *parentPtr() const
{
return hasParent()? &parent() : 0;
return _parent;
}

/**
Expand Down Expand Up @@ -284,7 +284,7 @@ class BinaryTree
*/
inline BinaryTree *childPtr(ChildId which) const
{
return hasChild(which)? &child(which) : 0;
return which == Left? _leftChild : _rightChild;
}

/**
Expand Down

0 comments on commit 53a36de

Please sign in to comment.