Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: CopyToImage performance hurdle  (Read 4077 times)

0 Members and 1 Guest are viewing this topic.

Elessar

  • Newbie
  • *
  • Posts: 2
    • View Profile
CopyToImage performance hurdle
« 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

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: CopyToImage performance hurdle
« Reply #1 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.
« Last Edit: January 21, 2015, 01:31:04 pm by Laurent »
Laurent Gomila - SFML developer

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: CopyToImage performance hurdle
« Reply #2 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 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?
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

Elessar

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: CopyToImage performance hurdle
« Reply #3 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.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: CopyToImage performance hurdle
« Reply #4 on: January 21, 2015, 06:43:57 pm »
Quote
What you meant were PBOs right?
Oops, yes of course :P
Laurent Gomila - SFML developer