Why does SDL_RenderDrawLinesF have this piece of code?

I’m new to SDL and this forum, so not sure if this is the right place to ask, feel free to remove if this is not appropriate. But looking at the source code of SDL_RenderDrawLinesF there is something that is bugging me and I can’t let it go :worried:

There is a line that checks for scaling and uses RenderDrawLinesWithRectsF in that case.

    if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) {
        return RenderDrawLinesWithRectsF(renderer, points, count);
    }

But when there is no scaling it skips to this loop.

for (i = 0; i < count; ++i) {
        fpoints[i].x = points[i].x * renderer->scale.x;
        fpoints[i].y = points[i].y * renderer->scale.y;
}

But if renderer->scale.x != 1.0f || renderer->scale.y != 1.0f is not true, that must mean they are in fact equal to 1.0f, so what’s the point of this loop? Wouldn’t just passing points down or doing a memcpy from points to fpoints be faster? I am just beginning with C and SDL, so I am probably not understanding it well. This same loop is present in the original non-float version, but my guess there it is a method to convert the point coordinates from int to float.

Wouldn’t just passing points down or doing a memcpy from points to fpoints be faster?

This loop converts int values into floats, so you can’t memcpy it.

Even for SDL_RenderDrawLinesF that receives SDL_FPoint, is it needed there?

Also, is there a difference between the implicit conversion by multiplying versus casting explicitly with something likefpoint = (float) point?

An implicit or explicit conversion doesn’t change the underlying code, so for the computer, it’s all the same.

Explicit conversion is much better, though, for a human trying to understanding the code.

In turns of performance, is multiplication more expensive than casting, or is it optimized away since the value is 1.0?

Well, that’s really two different operations, so it can’t really be compared.

For example :

int i = 100;
float f;

f = i * 1.0f;

The last line does exactly the same thing as doing :

f = (float)i * 1.0f;

C++ standard, paragraph 10, section 5 states that if either operand is float, the other shall be converted to float.

So asking if multiplying by 1.0f is faster than casting… well, the answer is no, since casting always happens, no matter what you do.

A compiler MAY optimize (int)var1 *= (const float)1.0f; into (float)var1, but don’t rely on it. Code should be written as to convey intent. You want to multiply, write a multiplication. You want to cast, write a cast. Leave the optimization to the compiler ; he knows much better than you what it’s doing.

2 Likes

Thanks, @MartinVee for the very thoughtful response.

Then probably it’s a copy/paste thing from SDL_RenderDrawLines to SDL_RenderDrawLinesF? I don’t think SDL_RenderDrawLinesF needs to convert to float, since SDL_FPoint is already floating point. Additionally, it would be nicer to use explicit conversion to make the intent clear.