Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@wenjieshen
Copy link
Collaborator

@wenjieshen wenjieshen commented Oct 17, 2025

We've implemented a comprehensive binary shader caching system to significantly improve OpenGL rendering performance on macOS by eliminating redundant shader compilation overhead on subsequent application runs.

This feature introduces the GlShaderCache class that provides persistent storage and retrieval of compiled OpenGL shader binaries. The system automatically caches compiled shader programs to the user's cache directory using a hash-based naming scheme and attempts to load cached binaries before falling back to source compilation.

Key implementation details:

  • Utilizes OpenGL binary shader format support via glGetProgramBinary/glProgramBinary extensions
  • Stores cached binaries in the System cache folder on macOS and Windows; other platforms are testing
  • Integrates with the existing GlProgram compilation pipeline

The caching mechanism works transparently:

  1. When a shader program is first compiled, the binary is automatically cached
  2. On subsequent runs, the system attempts to load the cached binary
  3. If successful, compilation time is virtually eliminated
  4. If cache miss or load failure occurs, falls back to normal source compilation

Performance benefits:

  • Eliminates shader compilation stutters during runtime
  • No API changes required - caching works automatically

issue: #2884

@github-actions github-actions bot added infrastructure Dev infrastructure gl OpenGL/WebGL render backend labels Oct 17, 2025
@wenjieshen wenjieshen force-pushed the exp/binary-shader-support-mac branch from a821049 to 2dcd2cf Compare October 17, 2025 10:23
@github-actions github-actions bot removed the infrastructure Dev infrastructure label Oct 17, 2025
@wenjieshen wenjieshen force-pushed the exp/binary-shader-support-mac branch from 2dcd2cf to 9941559 Compare October 17, 2025 10:26
@wenjieshen wenjieshen changed the title gl_engine/shader: Introduced binary shader caching for Destop gl_engine/shader: Introduced binary shader caching for Desktop [skip ci] Oct 17, 2025
@wenjieshen wenjieshen self-assigned this Oct 17, 2025
@hermet hermet requested a review from Copilot October 17, 2025 13:22
@hermet hermet added the optimization Enhance performance / Reduce memory usage or binary size label Oct 17, 2025
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements a binary shader caching system for the OpenGL renderer to improve performance by eliminating redundant shader compilation on subsequent application runs. The system automatically stores compiled OpenGL shader binaries to disk and attempts to load them before falling back to source compilation.

  • Introduces GlShaderCache class with persistent binary shader storage and retrieval functionality
  • Integrates caching into existing GlProgram compilation pipeline with transparent fallback behavior
  • Adds OpenGL 4.1+ binary shader API support via glGetProgramBinary/glProgramBinary extensions

Reviewed Changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
tvgGlShaderCache.h Defines GlShaderCache class interface for binary shader caching operations
tvgGlShaderCache.cpp Implements shader cache functionality with file I/O and hash-based naming
tvgGlProgram.cpp Integrates shader caching into program compilation with cache-first loading
tvgGl.h Adds OpenGL 4.1 binary shader API constants and function pointer declarations
tvgGl.cpp Implements dynamic loading of binary shader API functions with version checking
meson.build Adds new shader cache source files to build configuration

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@wenjieshen wenjieshen force-pushed the exp/binary-shader-support-mac branch 5 times, most recently from 94fa894 to 95cb9bd Compare October 19, 2025 13:45
@wenjieshen
Copy link
Collaborator Author

wenjieshen commented Oct 20, 2025

@hermet @SergeyLebedkin
Thanks for reviewing. I’d like to confirm two points:

Binary shader support is an OpenGL 4.1+ feature, while our requirement is OpenGL 3. I added a helper function glIsProgramBinarySupportAvailable() in tvgGl.h to check runtime availability. This is the first runtime capability check in the project, so I’m not sure if this approach aligns with our design principles.

Although my MacBook Air supports OpenGL 4.1, it still returns GL_NUM_PROGRAM_BINARY_FORMATS = 0, meaning binary shader support isn’t available. I’m waiting for GPU access on a cloud platform to test the performance improvement in another environment.

While waiting, I’ll continue investigating the stroke rendering issue on the GL engine.

@wenjieshen wenjieshen marked this pull request as ready for review October 20, 2025 02:30
@hermet
Copy link
Member

hermet commented Oct 20, 2025

Binary shader support is an OpenGL 4.1+ feature, while our requirement is OpenGL 3. I added a helper function glIsProgramBinarySupportAvailable() in tvgGl.h to check runtime availability. This is the first runtime capability check in the project, so I’m not sure if this approach aligns with our design principles.

@wenjieshen Looks good, if the binary shaders doesn't working, we can fallback to a normal scenario.

@hermet
Copy link
Member

hermet commented Oct 20, 2025

@wenjieshen Could you please double-check this as well? a few systems might use this GL_ARB_get_program_binary for gl3 case. But please hold this, Maybe we can bump up the opengl dependency to v4 as the minimum requirement... If so, we can drop the v3 use-case.

@thorvg thorvg deleted a comment from huming2207 Oct 20, 2025
@thorvg thorvg deleted a comment from huming2207 Oct 20, 2025
@wenjieshen
Copy link
Collaborator Author

@wenjieshen Could you please hold this? I think we can discuss the opengl dependency further. Maybe we can bump up the opengl dependency to v4 as the minimum requirement... If so, we can drop the v3 use-case.

@hermet Understood, I’ll pause the PR.
Agree that we should discuss the OpenGL dependency direction first. If we decide to move to 4.0+, we can remove the v3 fallback logic entirely.

@wenjieshen wenjieshen marked this pull request as draft October 20, 2025 03:29
@hermet hermet removed this from ThorVG Oct 20, 2025
@hermet
Copy link
Member

hermet commented Oct 20, 2025

Understood, I’ll pause the PR.

@wenjieshen I mean we can hold support v3 for binary shaders. I didn't mean hold this PR. Please go proceed. :) Thanks.

@wenjieshen wenjieshen marked this pull request as ready for review October 20, 2025 05:12
@hermet hermet changed the title gl_engine/shader: Introduced binary shader caching for Desktop [skip ci] gl_engine/shader: Introduced binary shader caching Oct 20, 2025
Copy link
Member

@hermet hermet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wenjieshen Please check comments and please respect thorvg coding convention.
Thanks.

@wenjieshen wenjieshen force-pushed the exp/binary-shader-support-mac branch 2 times, most recently from ec10334 to 7dc6139 Compare October 29, 2025 13:13
@wenjieshen wenjieshen marked this pull request as ready for review October 29, 2025 13:28
@wenjieshen
Copy link
Collaborator Author

Thank you for the suggestion. I’ve added a validation header to the binary file.
Screenshot 2025-10-29 at 9 27 25 PM
After corrupting a file (as shown in the screenshot above), the cache successfully detected the issue and removed the file.

However, identifying and removing redundant files is still challenging. At the moment, I don’t have a good way to determine which files are no longer needed. I’d prefer to address this together with the version that stores the mono cache file, so both features can be handled cleanly in the same update.

@wenjieshen Maybe we can consider removing deprecated older shader files...

What do you think if we use like: tvg_glshader_{TVG_VERSION}.bin

The binary format could have three sections - [Tag(2byte) + Hash(4 bytes) + Binary Shader] The tag notify us that file is thorvg gl shader file. We can have a specific value for this. The binary shader is stated with offset 6 bytes.

cache = load(tvg_glshader_{TVG_VERSION}  //see: THORVG_VERSION_NUMBER()
verify cache file is valid with the tag. 
use shader if the cache hash value equals current shader hash

If the current version shader binary is existed but the hash is different, we can remove the old and update with the latest.

@wenjieshen wenjieshen force-pushed the exp/binary-shader-support-mac branch from 7dc6139 to cd6c12d Compare October 29, 2025 18:18
@wenjieshen wenjieshen requested a review from hermet October 30, 2025 02:30
Copy link
Member

@SergeyLebedkin SergeyLebedkin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅windows 11: OK
✅ubuntu (wsl2): OK
✅ubuntu (h/w): OK
✅macos (intel): OK (there are no supported binary formats)

@hermet hermet force-pushed the main branch 8 times, most recently from 1971b85 to db355dd Compare November 4, 2025 06:53
@wenjieshen wenjieshen force-pushed the exp/binary-shader-support-mac branch from cd6c12d to a5acce0 Compare November 5, 2025 13:38
@hermet
Copy link
Member

hermet commented Nov 5, 2025

The file IO is expensive relatively. Current shaders are more than 10, it needs a consideration before pushing this. That would be the best if we can introduce the one single binary form....

@hermet
Copy link
Member

hermet commented Nov 6, 2025

1. Verifying Shaders

  • Current: Use a Hash & ThorVG version
  • After: Use the ThorVG version only. ie) CACHE_FOLDER/thorvg/gl_shaders_VERSION_INFO.bin
  • Later we can introduce a binary shader feature toggle option.
    • On dev, we can disable the binary shader, but we can enable it manually when necessary.
    • Enable the binary shader feature with the official release binary.

2. Lazy Loading or Immediate Loading

  • Lazy Loading needs to hold the binary shader memory, We need to confirm the total size of the memory first.

@wenjieshen wenjieshen marked this pull request as draft November 6, 2025 13:00
@hermet hermet force-pushed the main branch 7 times, most recently from 1b33069 to 9ebd273 Compare November 9, 2025 03:44
Implement binary shader caching system to improve OpenGL performance by:
- Add GlShaderCache class with read/write functionality for compiled shaders
- Support OpenGL binary shader format
- Add proper OpenGL ARB extension loading for glGetProgramBinary/glProgramBinary
- Integrate caching into GlProgram compilation pipeline

This reduces shader compilation overhead on subsequent application runs,
significantly improving startup performance for OpenGL-based rendering.

Related issue: thorvg#2884
@wenjieshen wenjieshen force-pushed the exp/binary-shader-support-mac branch from 5066488 to 99e7369 Compare November 10, 2025 11:59
@wenjieshen
Copy link
Collaborator Author

1. Verifying Shaders

  • Current: Use a Hash & ThorVG version
  • After: Use the ThorVG version only. ie) CACHE_FOLDER/thorvg/gl_shaders_VERSION_INFO.bin
  • Later we can introduce a binary shader feature toggle option.
    • On dev, we can disable the binary shader, but we can enable it manually when necessary.
    • Enable the binary shader feature with the official release binary.

2. Lazy Loading or Immediate Loading

  • Lazy Loading needs to hold the binary shader memory, We need to confirm the total size of the memory first.

@hermet
I understand. Thanks for the suggestion.
We can roll back this version if the loading efficiency gain doesn’t justify the additional memory overhead. On average, loading a single discrete shader takes 0.59 ms, while loading the combined binary file (containing all shaders) takes 0.87 ms. Since each example may require between 17 and 89 shaders, the unified loading approach can improve total loading performance by roughly 11× to 60×, depending on how many shaders are needed.

Memory Usage

After combining the binary shader files, the maximum additional memory usage observed across all examples is 857.21 KB.

Shader Loading Time (per example)

  • Mean (Average): 0.867 ms
  • Median (50th Percentile): 0.877 ms
  • Standard Deviation: 0.175 ms
  • Variance: 0.031
  • Minimum: 0.183 ms (Fastest load time — Animation.exe)
  • Maximum: 1.322 ms (Slowest load time — StrokeLine.exe)

Accumulated Write Time(per example)

  • Blending.exe: $10.897$ ms
  • Accessor.exe: $4.334$ ms
  • SceneEffects.exe: $1.415$ ms
  • Duplicate.exe: $0.455$ ms
  • EffectDropShadow.exe: $0.343$ ms

Shader Writing Time (per shader)

  • Mean (Average): 0.203 ms
  • Median (50th Percentile): 0.174 ms
  • Standard Deviation: 0.090 ms
  • Variance: 0.008
  • Minimum: 0.126 ms (Fastest write time)
  • Maximum: 0.670 ms (Slowest write time)

@wenjieshen wenjieshen marked this pull request as ready for review November 10, 2025 12:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gl OpenGL/WebGL render backend optimization Enhance performance / Reduce memory usage or binary size renderer Core rendering

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants