From 934fc54b8aeb7456f31e8f79fbcce1e93072da5b Mon Sep 17 00:00:00 2001 From: sukibaby <163092272+sukibaby@users.noreply.github.com> Date: Sat, 14 Sep 2024 02:22:16 -0700 Subject: [PATCH] BitmapText::DrawPrimitives noexcept This function indirectly determines the amount of average audio latency, this is why changes to BitmapText can affect global offset significantly. Aim to make the function as fast as possible to minimize latency. 1) make BitmapText::DrawPrimitives noexcept - note: RollingNumbers::DrawPrimitives has to also become noexcept as a consequence 2) Define repeated calculations as constexpr functions defined within an anonymous namespace 3) Fix some formatting stuff --- src/BitmapText.cpp | 108 ++++++++++++++++++++++++++--------------- src/BitmapText.h | 2 +- src/RollingNumbers.cpp | 2 +- src/RollingNumbers.h | 2 +- 4 files changed, 73 insertions(+), 41 deletions(-) diff --git a/src/BitmapText.cpp b/src/BitmapText.cpp index 491edcf860..652ad11fd0 100644 --- a/src/BitmapText.cpp +++ b/src/BitmapText.cpp @@ -672,8 +672,44 @@ bool BitmapText::EarlyAbortDraw() const return m_wTextLines.empty(); } -// draw text at x, y using colorTop blended down to colorBottom, with size multiplied by scale -void BitmapText::DrawPrimitives() +// constexpr functions used for operations on vertices in DrawPrimitives +namespace { + inline void SetVertexColor(std::vector& vertices, size_t i, const RageColor* color) + { + vertices[i + 0].c = color[0]; + vertices[i + 1].c = color[2]; + vertices[i + 2].c = color[3]; + vertices[i + 3].c = color[1]; + } + + inline void ApplyJitter(std::vector& vertices, size_t i, const RageVector3& jitter) + { + vertices[i + 0].p += jitter; + vertices[i + 1].p += jitter; + vertices[i + 2].p += jitter; + vertices[i + 3].p += jitter; + } + + inline void UndoJitter(std::vector& vertices, size_t i, const RageVector3& jitter) + { + vertices[i + 0].p -= jitter; + vertices[i + 1].p -= jitter; + vertices[i + 2].p -= jitter; + vertices[i + 3].p -= jitter; + } + + constexpr size_t ClampToVertexSize(size_t iEnd, size_t verticesSize) + { + return (iEnd < verticesSize) ? iEnd : verticesSize; + } + + constexpr size_t CalculateEndIndex(bool isEnd, size_t verticesSize, size_t iterFirst) + { + return isEnd ? verticesSize : iterFirst * 4; + } +} // namespace + +void BitmapText::DrawPrimitives() noexcept { Actor::SetGlobalRenderStates(); // set Actor-specified render states DISPLAY->SetTextureMode( TextureUnit_1, TextureMode_Modulate ); @@ -689,20 +725,24 @@ void BitmapText::DrawPrimitives() RageColor c = m_ShadowColor; c.a *= m_pTempState->diffuse[0].a; - for( unsigned i=0; iPopMatrix(); } // render the stroke - RageColor stroke_color= GetCurrStrokeColor(); + RageColor stroke_color = GetCurrStrokeColor(); if( stroke_color.a > 0 ) { stroke_color.a *= m_pTempState->diffuse[0].a; - for( unsigned i=0; ifirst*4; - iEnd = std::min( iEnd, m_aVertices.size() ); - for( ; i < iEnd; i += 4 ) + size_t iEnd = CalculateEndIndex(iter == m_mAttributes.end(), m_aVertices.size(), iter->first); + iEnd = ClampToVertexSize(iEnd, m_aVertices.size()); + for (; i < iEnd; i += 4) { - m_aVertices[i+0].c = m_pTempState->diffuse[0]; // top left - m_aVertices[i+1].c = m_pTempState->diffuse[2]; // bottom left - m_aVertices[i+2].c = m_pTempState->diffuse[3]; // bottom right - m_aVertices[i+3].c = m_pTempState->diffuse[1]; // top right + SetVertexColor(m_aVertices, i, m_pTempState->diffuse); } if( iter == m_mAttributes.end() ) break; @@ -741,10 +778,10 @@ void BitmapText::DrawPrimitives() const Attribute &attr = iter->second; ++iter; if( attr.length < 0 ) - iEnd = iter == m_mAttributes.end()? m_aVertices.size():iter->first*4; + iEnd = CalculateEndIndex(iter == m_mAttributes.end(), m_aVertices.size(), iter->first); else iEnd = i + attr.length*4; - iEnd = std::min( iEnd, m_aVertices.size() ); + iEnd = ClampToVertexSize(iEnd, m_aVertices.size()); std::vector temp_attr_diffuse(NUM_DIFFUSE_COLORS, m_internalDiffuse); for(std::size_t c= 0; c < NUM_DIFFUSE_COLORS; ++c) { @@ -756,10 +793,7 @@ void BitmapText::DrawPrimitives() } for( ; i < iEnd; i += 4 ) { - m_aVertices[i+0].c = temp_attr_diffuse[0]; // top left - m_aVertices[i+1].c = temp_attr_diffuse[2]; // bottom left - m_aVertices[i+2].c = temp_attr_diffuse[3]; // bottom right - m_aVertices[i+3].c = temp_attr_diffuse[1]; // top right + SetVertexColor(m_aVertices, i, attr.diffuse); } } } @@ -768,15 +802,12 @@ void BitmapText::DrawPrimitives() std::vector vGlyphJitter; if( m_bJitter ) { - for( unsigned i=0; iSetTextureMode( TextureUnit_1, TextureMode_Glow ); std::size_t i = 0; - std::map::const_iterator iter = m_mAttributes.begin(); + auto iter = m_mAttributes.begin(); while( i < m_aVertices.size() ) { // Set the glow up to the next attribute. - std::size_t iEnd = iter == m_mAttributes.end()? m_aVertices.size():iter->first*4; - iEnd = std::min( iEnd, m_aVertices.size() ); + std::size_t iEnd = CalculateEndIndex(iter == m_mAttributes.end(), m_aVertices.size(), iter->first); + iEnd = ClampToVertexSize(iEnd, m_aVertices.size()); for( ; i < iEnd; ++i ) + { m_aVertices[i].c = m_pTempState->glow; + } if( iter == m_mAttributes.end() ) + { break; + } // Set the glow according to this attribute. const Attribute &attr = iter->second; ++iter; if( attr.length < 0 ) - iEnd = iter == m_mAttributes.end()? m_aVertices.size():iter->first*4; + iEnd = CalculateEndIndex(iter == m_mAttributes.end(), m_aVertices.size(), iter->first); else iEnd = i + attr.length*4; - iEnd = std::min( iEnd, m_aVertices.size() ); + iEnd = ClampToVertexSize(iEnd, m_aVertices.size()); for( ; i < iEnd; ++i ) { if( m_internalGlow.a > 0 ) @@ -875,7 +907,7 @@ void BitmapText::AddAttribute( std::size_t iPos, const Attribute &attr ) { // Fixup position for new lines. Attribute newAttr = attr; - auto lineIter = m_wTextLines.cbegin(); + std::vector::const_iterator lineIter = m_wTextLines.cbegin(); int iLines = 0; std::size_t iAdjustedPos = iPos; diff --git a/src/BitmapText.h b/src/BitmapText.h index 82641428b7..115dd2282c 100644 --- a/src/BitmapText.h +++ b/src/BitmapText.h @@ -70,7 +70,7 @@ public: void CropToWidth(int width); virtual bool EarlyAbortDraw() const override; - virtual void DrawPrimitives() override; + virtual void DrawPrimitives() noexcept override; void SetUppercase( bool b ); void SetRainbowScroll( bool b ) { m_bRainbowScroll = b; } diff --git a/src/RollingNumbers.cpp b/src/RollingNumbers.cpp index 037a3224da..f8507f6240 100644 --- a/src/RollingNumbers.cpp +++ b/src/RollingNumbers.cpp @@ -43,7 +43,7 @@ void RollingNumbers::DrawPart(RageColor const* diffuse, RageColor const& stroke, BitmapText::DrawPrimitives(); } -void RollingNumbers::DrawPrimitives() +void RollingNumbers::DrawPrimitives() noexcept { if(!m_metrics_loaded) { diff --git a/src/RollingNumbers.h b/src/RollingNumbers.h index 6e26cf2068..fc8a8be9c4 100644 --- a/src/RollingNumbers.h +++ b/src/RollingNumbers.h @@ -15,7 +15,7 @@ public: void DrawPart(RageColor const* diffuse, RageColor const& stroke, float crop_left, float crop_right); - virtual void DrawPrimitives(); + virtual void DrawPrimitives() noexcept; virtual void Update( float fDeltaTime ); /**