Home › Forums › Syphon › Syphon Implementations – User › Frame rate issues in a client with Unity Syphon server › Reply To: Frame rate issues in a client with Unity Syphon server
glFlushRendererApple != CGLFlushRenderer. Its not just for single buffered outputs, but when FBOs and other buffers are rendered to, or when *secondary OpenGL Threads update the contents of buffers*, flushing needs to happen so resources can be synced. IOSurface is one such instance where an additional flush is needed to synchronize a shared resource.
Look at “Using glFlush Effectively” section
The CGLFlushDrawable issue applies only during a single application, on a single window you own. You can totally call CGLFlushDrawable on multiple windows at multiple times, more than once, during a period between refreshes.
You also have to understand that GL profiler “hides” much complexity of the programmable pipeline and “collapses” GLSL shader programs, ARB programs, etc into some calls it lists in the states. So when you see draw call usage for CGLFlushDrawable, or GLFlush go “up”, its most likely due to either fill rate issues, or due to using the programmable pipeline. Notice there is no higher GPU usage or rates for shader calls, even though unity and many apps use them. Much stuff gets “rolled” into other calls, making identifying some of the performance issues more nuanced than relying solely on GL Profiler and trusting its output.
Secondly, IOSurfaceLock/Unlock is never used in Syphon because we never hit the CPU. Those calls are, as you guessed, only for when a surface is changed in main memory, and needs to be synchronized, and re-flushed to the GPU. The locking is so that any GPU based app cannot read into the texture while it is being updated from another app, potentially causing issues, incomplete reads, etc.
I think you are over-thinking this issue to be honest. This sounds suspiciously like a fill rate issue, in that you simply can’t draw that much on screen. What size frames are you sending back and forth? I think its 2400x 600? (triple head 800×600 size no?)
Understand that, because you are using Unity’s render buffer, and syphons “publish frame image” api, and drawing to the screen in unity, and then drawing in another app, you end up drawing 2400×600 a few times.
1) Render Unity Scene to a texture
2) Render resulting unity texture to Syphons IOSurface via publishFrame Image
3) Unity renders the resulting texture in the Unity app.
4) App using Syphon renders the Syphon texture.
Due to the lack of CPU spikes, VRam usage, etc, this seriously looks like a fill rate limitation to me.
You might find that you get better performance if you simple do a glCopyTexSubImage2D on the front buffer and the end of the unity rendering, getting *everything* rendered at that point into a texture. You can also cheat this way, and copy that directly into SyphonServers texture. This eliminates 3 render passes (Rendering the Unity Scene to its own internal texture, Unity Rendering that Texture, and rendering that texture to Syphons internal texture), and adds a gl copy / blit pass, and of course Unity still renders the scene once, rather than rendering it to texture, then rendering that texture (both which use up available fill rate).
This is what we do in the yet to be finalized/fixed for 10.7 Screen Capture app for getting the entire scene, look at :
SyphonScreenCaptureAppDelegate.m line 404 (thats amusing…)