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

Author Topic: Why RenderStates is passed by value in draw function?  (Read 8498 times)

0 Members and 1 Guest are viewing this topic.

Neil

  • Newbie
  • *
  • Posts: 27
    • View Profile
Why RenderStates is passed by value in draw function?
« on: December 26, 2014, 06:13:07 pm »
http://www.sfml-dev.org/documentation/2.0/classsf_1_1Drawable.php

In this function

virtual void    draw (RenderTarget &target, RenderStates states) const

Why is RenderStates passed by value and not (const) reference? On my compiler it is 76 bytes, which is quite big.

I know sometimes draw function may want to alter it. In that case, it can make its own copy from the const reference if required.

Wouldn't this be faster?

Thank you.

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: Why RenderStates is passed by value in draw function?
« Reply #1 on: December 26, 2014, 06:39:12 pm »
I doubt you'd be able to measure a difference. And anyway, you'd then slow down the "wants to make a copy" case.
But I really doubt that it actually matters either way, performance wise.

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Re: Why RenderStates is passed by value in draw function?
« Reply #2 on: December 26, 2014, 06:41:55 pm »
Measure it, with compiler optimisation turned on, of course. The copy is probably elided when not needed so you'll probably see no difference. But that's just a guess... The key is to always measure.
SFML / OS X developer

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Why RenderStates is passed by value in draw function?
« Reply #3 on: December 26, 2014, 06:56:22 pm »
It will be copied once per drawing, since the calls usually go:
1. RenderTarget::draw //constructed default or passed here as const&
2. Drawable::draw //copy here
3. RenderTarget::draw //the vertex overload, also takes by const&

Also almost all sf::Drawable classes that come with SFML modify it, I think just VertexArray doesn't. It's also 100% trivial to copy.


In theory and for the sake of C++ trivia: yes, it might be faster or it might be slower, but either way it doesn't matter.
It's not performance issue and will probably never be.
The actual OpenGL draw calls (which are some pretty old/legacy functions of GL) time inside RenderTarget::draw is dominating so heavily that it will completely dwarf this in any profiler.

It just doesn't matter. It's impossible to write a real life program which would be impacted by this change in any way.
Back to C++ gamedev with SFML in May 2023

Gambit

  • Sr. Member
  • ****
  • Posts: 283
    • View Profile
Re: Why RenderStates is passed by value in draw function?
« Reply #4 on: December 26, 2014, 07:22:35 pm »
I know sometimes draw function may want to alter it. In that case, it can make its own copy from the const reference if required.

This is stupid for a lot of reasons. As it is stated, a lot of drawables modify the states which means you are making senseless copies which could be avoided if the states were passed by value (Sound familiar?).

Neil

  • Newbie
  • *
  • Posts: 27
    • View Profile
Re: Why RenderStates is passed by value in draw function?
« Reply #5 on: December 26, 2014, 08:02:03 pm »
Ok thanks. I understand now it probably doesn't matter and I shouldn't worry about it.

However I don't understand Gambit's post. Why would passing by const reference result in more copies than passing by value?

Gambit

  • Sr. Member
  • ****
  • Posts: 283
    • View Profile
Re: Why RenderStates is passed by value in draw function?
« Reply #6 on: December 26, 2014, 08:15:12 pm »
If RenderState is passed by const ref, you cannot alter the state so you have to copy it if you need to modify it.
« Last Edit: December 26, 2014, 08:21:46 pm by Gambit »

Neil

  • Newbie
  • *
  • Posts: 27
    • View Profile
Re: Why RenderStates is passed by value in draw function?
« Reply #7 on: December 26, 2014, 08:32:20 pm »
Yes. How is that worse than pass by value, which results in a copy even if it's not modified?

Gambit

  • Sr. Member
  • ****
  • Posts: 283
    • View Profile
Re: Why RenderStates is passed by value in draw function?
« Reply #8 on: December 26, 2014, 08:38:19 pm »
Pass by value is a copy even if it is modified. There is no point in passing by reference. Each draw call has the option to change the state if it wants without affecting other draw calls. Most draw calls (Text, Sprite, etc) change the transformation of the state which you cannot do with a const ref. Passing by non-const ref means that changing the state will affect other draw calls as well. As stated earlier, its trivial to pass by value (If 76 bytes is a lot I suggest getting more RAM). From a performance stand point, the overhead is negligible.

Neil

  • Newbie
  • *
  • Posts: 27
    • View Profile
Re: Why RenderStates is passed by value in draw function?
« Reply #9 on: December 26, 2014, 08:53:47 pm »
Passing by const reference and only making a copy if it needs to be modified results in less copies.
I wouldn't pass by non-const reference. That would cause too many issues about the re-usability of the original state object.
Copying 76 bytes on the stack is nothing to do with the amount of ram. It depends mainly on CPU.

I inherit my classes from sf::Drawable and implement the draw function. Objects may contain subojects that need drawing. Not all objects are interested in changing the render state. This is the motivation of my asking. Is this not a good design?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Why RenderStates is passed by value in draw function?
« Reply #10 on: December 26, 2014, 08:58:33 pm »
Quote
Is this not a good design?
It is. Passing the render states by value is also a good design. The thing is, nobody cares because the difference will never be noticeable. There's really nothing else to say about it ;)
Laurent Gomila - SFML developer

Neil

  • Newbie
  • *
  • Posts: 27
    • View Profile
Re: Why RenderStates is passed by value in draw function?
« Reply #11 on: December 26, 2014, 09:09:13 pm »
Could you explain why passing render states by value is good design?
I'm just curious because it's different to the way I was taught to program* and would like to learn more.
Thanks

(Pass basics by value, pass big things by reference, I know it's only a rule of thumb)

Gambit

  • Sr. Member
  • ****
  • Posts: 283
    • View Profile
Re: Why RenderStates is passed by value in draw function?
« Reply #12 on: December 26, 2014, 09:28:36 pm »
Read a C++ book/pdf or something, I'm sure it outlines the ups and downs for using both. This is not a C++ tutorial forum.

Neil

  • Newbie
  • *
  • Posts: 27
    • View Profile
Re: Why RenderStates is passed by value in draw function?
« Reply #13 on: December 26, 2014, 09:33:17 pm »
Hey I've been coding C++ for years so cut the attitude please. If you're going to be flippant, you at least need to be right, which you haven't been in your previous posts.

Gambit

  • Sr. Member
  • ****
  • Posts: 283
    • View Profile
Re: Why RenderStates is passed by value in draw function?
« Reply #14 on: December 26, 2014, 09:53:00 pm »
Theres no need to be rude. This is not a C++ help and support forum. If you have been coding C++ for years, I'm sure you would know this by now or at least have the ability to source the information yourself.

Passing by value, reference or pointer is not just about size, but about utility as well. The one you chose depends on what is going to happen to the variable that is being passed.

Say I want to share a web page with you.

If I tell you the URL, I'm passing by reference. You can use that URL to see the same web page I can see. If that page is changed, we both see the changes. If you delete the URL, all you're doing is destroying your reference to that page - you're not deleting the actual page itself.

If I print out the page and give you the printout, I'm passing by value. Your page is a disconnected copy of the original. You won't see any subsequent changes, and any changes that you make (e.g. scribbling on your printout) will not show up on the original page. If you destroy the printout, you have actually destroyed your copy of the object - but the original web page remains intact.