Skip to content

Parser and texture improvement bvets - #1389

Open
adfriz wants to merge 20 commits into
leezer3:masterfrom
adfriz:parser-and-texture-improvement-BVETS
Open

Parser and texture improvement bvets#1389
adfriz wants to merge 20 commits into
leezer3:masterfrom
adfriz:parser-and-texture-improvement-BVETS

Conversation

@adfriz

@adfriz adfriz commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

based on #1381. branched from commit be2ae7a

This one focused on BVE5/6 route loading.

Currently on my personal test can make the first load in route viewer to 11s and reload to 5s.

Tested with BVE6 uchibo v2.00 route

As usual, the speed is depends on the system specs and system load.

More focused on NewXparser but i tried to make it to affect assimpXparser too.

only tested on windows 11, test always use release build for better performance.

Also still has logging code.

adfriz added 20 commits August 10, 2026 12:32
- Pre-seed the texture cache with the decoded texture (not the handle) at
  register time, preventing a null reference when transparency is queried.
- Add a registered texture lookup table to avoid scanning every registered
  texture for each new registration.
- Preserve unchanged textures on route reload to avoid re-uploading them.
- Use HashSet for missing files / failed objects / failed textures lookups.
- Replace Thread.Sleep(1) with Thread.Yield in the CSV route parser.
- Measure route parse, post-parse setup, texture registration and texture
  decoding time, and report them in a summary message after loading.
- Fix TextureOrigin.Equals() inverted logic (all branches were wrong)
- Add GetHashCode() to PathOrigin for proper dictionary lookups
- Fix ByteArrayOrigin.NumberOfFrames (was byte count instead of 1)
- Fix InvertLightness loop bound (MyBytes.Length -> MyBytes[frame].Length)
- Fix GrayscaleAlpha stride bug (i+=4 -> i+=2, stride calculation, TexImage2D moved outside loop)
- Add thread-safety locks for textureCache modifications
- Replace ContainsKey+indexer with TryGetValue in ObjectLibrary.ShowObject
- Consolidate 3 lock acquisitions into 2 in RegisterTexture
- Skip GC.Collect on route reload (only on full unload)
- Add per-material alpha cache in ShowObject to avoid repeated textureCache lookups
- Replace ~20 ElementAt() calls with foreach in ApplyRouteData.cs and RouteData.cs (O(n^2) -> O(n))
- Cache brightness lookup index in GetBrightness() to avoid full blocks scan per call
- Replace Regex.Matches per-line with IndexOf loop in Preprocess.cs
- Replace .ToLowerInvariant() == with string.Equals(OrdinalIgnoreCase) for 'with' command
- Remove duplicate ObjectDictionary initialization
- Add Stopwatch timing around ParseRouteForData and ApplyRouteData in CsvRwRouteParser
- Add PluginParseTime and PluginApplyTime fields to HostInterface
- Update log format: parser: X ms (parse: X ms, apply: X ms) | textures: X ms (decode: X ms)
Host.RegisterTexture (RouteViewer + main game) and TextureManager.RegisterTexture
all checked File.Exists before passing to Host.LoadTexture, which has its own
File.Exists check. Removed redundant checks from Host.cs wrappers.
…dificationTime)

File.GetLastWriteTime() and FileInfo.Length were called in PathOrigin constructor
for every texture registration. These are only needed during route reload
(TextureFileUnchanged), so deferring them avoids 2 FS syscalls per texture
during initial load.
…erations

TextureManager.RegisterTexture had a backwards loop calling Array.Resize for
every trailing null entry — O(n) per registration on a large route. Removed
entirely; GetNextFreeTexture already handles growth via power-of-2 doubling.

Also removed redundant File.Exists check in TextureManager, flattened
textureCache pre-seed into single if-condition, and replaced ContainsKey+Add
with indexer assignment in ObjectLibrary.ShowObject cache miss path.
- NewXParser: move key-based material definitions from a process-wide static
  dictionary into the per-parse state, preventing concurrently parsed .x files
  from overwriting each other's material labels (caused wrong/missing textures)
- TextureManager: serialise GDI+ texture decode during parallel route loading
  and use thread-safe caches for registered texture lookup
- ObjectLibrary: double-checked locking around cached texture origin decode
- PathOrigin/TextureParameters/ClipRegion: include parameters in equality and
  hash code so distinct texture variations are keyed correctly
- Route.Bve5: group track statements by rail key to avoid re-scanning
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant