godot: Surface tool is exponentially slower when threaded
Godot version
3.4.2.stable
System information
Windows 10, GLES3, Radeon 5700xt, R7 5800
Issue description
Fast performance with no threading:
Slow performance with threading:
Steps to reproduce
I am aware of https://github.com/godotengine/godot/issues/51311 but the difference here is that SurfaceTool.append_from()
is not being invoked.
Here is how the code is laid out
var surf = SurfaceTool.new()
var mesh = Mesh.new()
surf.begin(Mesh.PRIMITIVE_TRIANGLES)
surf.set_material(mat)
surf.add_normal(normal)
surf.add_uv(Vector2(startUVx,startUVy))
surf.add_vertex(TL)
surf.add_normal(normal)
surf.add_uv((Vector2(endUVx,startUVy)))
surf.add_vertex(TR)
surf.add_normal(normal)
surf.add_uv(Vector2(endUVx,endUVy))
surf.add_vertex(BR)
surf.add_normal(normal)
surf.add_uv(Vector2(startUVx,startUVy))
surf.add_vertex(TL)
surf.add_normal(normal)
surf.add_uv(Vector2(endUVx,endUVy))
surf.add_vertex(BR)
surf.add_normal(normal)
surf.add_uv(Vector2(startUVx,endUVy))
surf.add_vertex(BL)
surf.commit(mesh)
Minimal reproduction project
No response
About this issue
- Original URL
- State: open
- Created 2 years ago
- Reactions: 2
- Comments: 17 (12 by maintainers)
I hope https://github.com/godotengine/godot/pull/69723 will improve the performance of that class
It may be an engine limitation that can’t be lifted, and can only be documented, especially in 3.x. OpenGL has a lot of limitations around threading, as it’s not thread-safe by design.
@DataPlusProgram you can see my comment regarding slowdown coming from synchronization on
VisualServer
level: https://github.com/godotengine/godot/issues/51311#issuecomment-1024966544For your case, creating mesh
var mesh = Mesh.new()
(and adding it to the scene tree), handling that mesh, and altering meshsurf.commit(mesh)
takes a lot of time when done on thread.IMO, you should limit implementation running on the thread to creating
SurfaceTool
instances (withSurfaceTool.new()
), filling them (usingsurf.add_
functions), and storingSurfaceTool
instances in the array.Once this is done, you should do the remaining stuff in the main thread (without extra thread). So you’d just have to iterate over that stored
SurfaceTool
instances in the array and for each of those create a new Mesh instance and commit the surface tool’s calculated surface to it.