SFML community forums

Bindings - other languages => DotNet => Topic started by: Elessar on January 21, 2015, 01:05:04 pm

Title: CopyToImage performance hurdle
Post by: Elessar on January 21, 2015, 01:05:04 pm
Hey guys

I have been using SFML to write some custom CG software and I'm hoping someone may be able to help me with a performance issue. Each frame of my render loop must be captured into a BGRA bitmap which is then sent across the network. My issue is, the act of copying the image from the render texture is so slow that my frames drop from almost one million(when unlimited) to around 20. I realise that transferring large amounts of data from the GPU memory to RAM is a slow process and I'm likely stuck, but I thought I would try and get some outside perspective before I return to the drawing board.

Here is my main render loop.

while (true)
            {
                //Re/Start watch
                watch.Restart();

                //Lock render texture for thread safety
                lock (m_RenderTexture)
                {
                    // clear the render texture with full transparency
                    m_RenderTexture.Clear(SFML.Graphics.Color.Transparent);

                    //Lock layers collection for thread safety
                    lock (m_Layers)
                    {
                        //Update layers
                        foreach (ILayer layer in m_Layers)
                        {
                            layer.Update(m_FrameTime);
                        }

                        //Draw layers
                        foreach (ILayer layer in m_Layers)
                        {
                            m_RenderTexture.Draw(layer);
                        }
                    }

                    //Display what has been drawn
                    m_RenderTexture.Display();

                    //Get frame from graphics card
                    Image frame = m_RenderTexture.Texture.CopyToImage();

                    //Send frame to tricaster
                    m_TriCaster.SendFrame(frame);

                    //Dispose frame
                    frame.Dispose();
                }

                //Limit loop to specified max framerate
                while (watch.ElapsedMilliseconds < ((1.0 / m_MaxFrameRate) * 1000.0))
                {
                    //Sleep thread for required time to match requested framerate
                    waittime = (int)(((1.0 / m_MaxFrameRate) * 1000.0) - watch.ElapsedMilliseconds);
                    Thread.Sleep(Math.Max(waittime, 0));
                }

                //Stop watch and store frame time
                watch.Stop();
                m_FrameTime = watch.Elapsed;
            }

Any assistance would be greatly appreciated.

Thanks
Title: Re: CopyToImage performance hurdle
Post by: Laurent on January 21, 2015, 01:11:28 pm
I doubt you can find something faster, even in professional solutions. What you do is heavy, no matter how you do it.

With OpenGL, I think the best you can do is to use FBOs, so that transfers can happen asynchronously and avoid blocking the drawing commands. But SFML doesn't provide an API for using FBOs.

You can also find a compromise: capture only a frame very N rendered frames.
Title: Re: CopyToImage performance hurdle
Post by: binary1248 on January 21, 2015, 02:09:19 pm
With OpenGL, I think the best you can do is to use FBOs, so that transfers can happen asynchronously and avoid blocking the drawing commands. But SFML doesn't provide an API for using FBOs.
What you meant were PBOs (https://www.opengl.org/wiki/Pixel_Buffer_Object) right? ;D

I'm curious, what kind of an application is this? If you have to transfer the image back into host memory anyway and even over the network (which is an even bigger bottleneck), why not replicate the input data on each host and generate the images at their destinations?
Title: Re: CopyToImage performance hurdle
Post by: Elessar on January 21, 2015, 02:34:15 pm
Thanks for the replies.

The application is generating overlay graphics for a live sports broadcast(sprintcars). By sending the frames over the network to the switcher, I am able to maintain the alpha channel without tying up an addition video input for the key. Everything is working perfectly, except I need another 10ish fps to smooth out my graphics transitions.
I am currently running performance tests on rendering without hardware-acceleration. The main graphics machine is running an over-clocked 5960X, so I'm hoping there will be enough wiggle room. I really didn't want to take this route, but I'm running low on ideas at the moment.
Title: Re: CopyToImage performance hurdle
Post by: Laurent on January 21, 2015, 06:43:57 pm
Quote
What you meant were PBOs right?
Oops, yes of course :P