From 307c4e8e8859e8abb9435f956e9ca10c5248977d Mon Sep 17 00:00:00 2001 From: Filipp Pavlov Date: Mon, 19 Oct 2026 10:17:44 +0000 Subject: [PATCH 1/4] Handle "out of memory" scenario in Tr2CurveLineSet --- trinity/Tr2CurveLineSet.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/trinity/Tr2CurveLineSet.cpp b/trinity/Tr2CurveLineSet.cpp index 827033726..4b39ca4de 100644 --- a/trinity/Tr2CurveLineSet.cpp +++ b/trinity/Tr2CurveLineSet.cpp @@ -371,6 +371,14 @@ bool Tr2CurveLineSet::FillVertexBuffer() // catch zero size, so we don't need to worry about empty arrays if( m_lines.size() ) { + size_t byteSize = m_vertexBufferSize * 6 * sizeof( LineVertex ); + auto buffer = Tr2Renderer::GetPoolAllocator()->Allocate( byteSize ); + if ( !buffer ) + { + m_vertexBuffer = {}; + return false; + } + // can the big vertexbuffer handle this? int currentNumOfLines = GetNumOfLines(); if( !m_vertexBuffer.IsValid() || ( currentNumOfLines > m_vertexBufferSize ) ) @@ -392,8 +400,6 @@ bool Tr2CurveLineSet::FillVertexBuffer() m_vertexBufferSize = currentNumOfLines; } - size_t byteSize = m_vertexBufferSize * 6 * sizeof( LineVertex ); - auto buffer = Tr2Renderer::GetPoolAllocator()->Allocate( byteSize ); LineVertex* vertexBuffer = reinterpret_cast( buffer ); for( unsigned int i = 0; i < m_lines.size(); ++i ) From 4a40ddc0f6f90657c44b4abf9d59199a72778c6e Mon Sep 17 00:00:00 2001 From: Filipp Pavlov Date: Mon, 19 Oct 2026 10:22:25 +0000 Subject: [PATCH 2/4] Handle a case when the buffer is about to grow --- trinity/Tr2CurveLineSet.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/trinity/Tr2CurveLineSet.cpp b/trinity/Tr2CurveLineSet.cpp index 4b39ca4de..98cb7b9e4 100644 --- a/trinity/Tr2CurveLineSet.cpp +++ b/trinity/Tr2CurveLineSet.cpp @@ -371,7 +371,9 @@ bool Tr2CurveLineSet::FillVertexBuffer() // catch zero size, so we don't need to worry about empty arrays if( m_lines.size() ) { - size_t byteSize = m_vertexBufferSize * 6 * sizeof( LineVertex ); + int currentNumOfLines = GetNumOfLines(); + + size_t byteSize = size_t( std::max( currentNumOfLines, m_vertexBufferSize ) ) * 6 * sizeof( LineVertex ); auto buffer = Tr2Renderer::GetPoolAllocator()->Allocate( byteSize ); if ( !buffer ) { @@ -380,7 +382,6 @@ bool Tr2CurveLineSet::FillVertexBuffer() } // can the big vertexbuffer handle this? - int currentNumOfLines = GetNumOfLines(); if( !m_vertexBuffer.IsValid() || ( currentNumOfLines > m_vertexBufferSize ) ) { // release old and create new From 82ce4524c29417e5421dfdc522e1452a3972f1a3 Mon Sep 17 00:00:00 2001 From: Filipp Pavlov Date: Wed, 21 Oct 2026 10:53:45 +0000 Subject: [PATCH 3/4] Address PR comments; formatting --- trinity/Tr2CurveLineSet.cpp | 11 +++++------ trinity/Tr2CurveLineSet.h | 1 - 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/trinity/Tr2CurveLineSet.cpp b/trinity/Tr2CurveLineSet.cpp index 98cb7b9e4..150c57633 100644 --- a/trinity/Tr2CurveLineSet.cpp +++ b/trinity/Tr2CurveLineSet.cpp @@ -23,7 +23,6 @@ Tr2CurveLineSet::Tr2CurveLineSet( IRoot* lockobj ) : m_lineWidthFactor( 1.f ), m_vertexDeclHandle( Tr2EffectStateManager::UNINITIALIZED_DECLARATION ), m_currentSubmittedLineCount( 0 ), - m_vertexBufferSize( 0 ), m_display( true ), m_dynamic( false ), m_boundsDirty( false ), @@ -371,18 +370,19 @@ bool Tr2CurveLineSet::FillVertexBuffer() // catch zero size, so we don't need to worry about empty arrays if( m_lines.size() ) { - int currentNumOfLines = GetNumOfLines(); + auto currentNumOfLines = GetNumOfLines(); - size_t byteSize = size_t( std::max( currentNumOfLines, m_vertexBufferSize ) ) * 6 * sizeof( LineVertex ); + auto vertexBufferSize = m_vertexBuffer.GetDesc().count / 6; + size_t byteSize = std::max( uint32_t( currentNumOfLines ), vertexBufferSize ) * 6 * sizeof( LineVertex ); auto buffer = Tr2Renderer::GetPoolAllocator()->Allocate( byteSize ); - if ( !buffer ) + if( !buffer ) { m_vertexBuffer = {}; return false; } // can the big vertexbuffer handle this? - if( !m_vertexBuffer.IsValid() || ( currentNumOfLines > m_vertexBufferSize ) ) + if( !m_vertexBuffer.IsValid() || ( currentNumOfLines > vertexBufferSize ) ) { // release old and create new USE_MAIN_THREAD_RENDER_CONTEXT(); @@ -398,7 +398,6 @@ bool Tr2CurveLineSet::FillVertexBuffer() nullptr, renderContext ), false ); - m_vertexBufferSize = currentNumOfLines; } LineVertex* vertexBuffer = reinterpret_cast( buffer ); diff --git a/trinity/Tr2CurveLineSet.h b/trinity/Tr2CurveLineSet.h index f73b71ddd..412ecec7d 100644 --- a/trinity/Tr2CurveLineSet.h +++ b/trinity/Tr2CurveLineSet.h @@ -199,7 +199,6 @@ class Tr2CurveLineSet : public ITr2Renderable, // vertex buffer unsigned int m_vertexDeclHandle; Tr2BufferAL m_vertexBuffer; - int m_vertexBufferSize; // all the lines std::vector m_lines; From 33f264509d79e0e3744abe6d3b111ad2d3a62332 Mon Sep 17 00:00:00 2001 From: Filipp Pavlov Date: Wed, 21 Oct 2026 14:43:25 +0000 Subject: [PATCH 4/4] Handle the issue differently --- trinity/Tr2CurveLineSet.cpp | 9 +++++---- trinity/Tr2CurveLineSet.h | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/trinity/Tr2CurveLineSet.cpp b/trinity/Tr2CurveLineSet.cpp index 150c57633..5418062ce 100644 --- a/trinity/Tr2CurveLineSet.cpp +++ b/trinity/Tr2CurveLineSet.cpp @@ -23,6 +23,7 @@ Tr2CurveLineSet::Tr2CurveLineSet( IRoot* lockobj ) : m_lineWidthFactor( 1.f ), m_vertexDeclHandle( Tr2EffectStateManager::UNINITIALIZED_DECLARATION ), m_currentSubmittedLineCount( 0 ), + m_vertexBufferSize( 0 ), m_display( true ), m_dynamic( false ), m_boundsDirty( false ), @@ -370,10 +371,9 @@ bool Tr2CurveLineSet::FillVertexBuffer() // catch zero size, so we don't need to worry about empty arrays if( m_lines.size() ) { - auto currentNumOfLines = GetNumOfLines(); + int currentNumOfLines = GetNumOfLines(); - auto vertexBufferSize = m_vertexBuffer.GetDesc().count / 6; - size_t byteSize = std::max( uint32_t( currentNumOfLines ), vertexBufferSize ) * 6 * sizeof( LineVertex ); + size_t byteSize = size_t( currentNumOfLines ) * 6 * sizeof( LineVertex ); auto buffer = Tr2Renderer::GetPoolAllocator()->Allocate( byteSize ); if( !buffer ) { @@ -382,7 +382,7 @@ bool Tr2CurveLineSet::FillVertexBuffer() } // can the big vertexbuffer handle this? - if( !m_vertexBuffer.IsValid() || ( currentNumOfLines > vertexBufferSize ) ) + if( !m_vertexBuffer.IsValid() || ( currentNumOfLines > m_vertexBufferSize ) ) { // release old and create new USE_MAIN_THREAD_RENDER_CONTEXT(); @@ -398,6 +398,7 @@ bool Tr2CurveLineSet::FillVertexBuffer() nullptr, renderContext ), false ); + m_vertexBufferSize = currentNumOfLines; } LineVertex* vertexBuffer = reinterpret_cast( buffer ); diff --git a/trinity/Tr2CurveLineSet.h b/trinity/Tr2CurveLineSet.h index 412ecec7d..f73b71ddd 100644 --- a/trinity/Tr2CurveLineSet.h +++ b/trinity/Tr2CurveLineSet.h @@ -199,6 +199,7 @@ class Tr2CurveLineSet : public ITr2Renderable, // vertex buffer unsigned int m_vertexDeclHandle; Tr2BufferAL m_vertexBuffer; + int m_vertexBufferSize; // all the lines std::vector m_lines;