Is it safe/acceptable to call SDL_SetTextureColorM

2020-07-18 10:30发布

问题:

As a simple way to render multiple textures that are the same other than color I load a plain white circle in to an SDL_Texture then just call SDL_SetTextureColorMod() giving it the color I want to make the circle.

This all works fine if the textures are individual (Example 1) but if I am sharing the SDL_Texture so that mutiple objects all reference it, it means that SDL_SetTextureColorMod() must be called every render frame before the object renders the texture since the color it gave last time may have been changed by another object (Example 2).

Is calling SDL_SetTextureColorMod() every render frame, for potentially quite a lot of objects sharing a texture, going to cause major performance issues?

The reason it is required is the system is designed using a shared texture functionality with basic reference counting (I understand that there are probably better ways to do this using smart pointers but that is not the topic for discussion here). Is it going to be better to just let each object have it's own copy of the SDL_Texture so it only has to set the color once (or whenever it needs to change) rather than every render frame?

Example 1:

SDL_Texture* tex1;
SDL_Texture* tex2;
SDL_Texture* tex3;
...
// All 3 instances have their own SDL_Texture
MyObject A(tex1);
MyObject B(tex2);
MyObject C(tex3);
...
// A call to set the color of the texture is only required once for each class

Example 2:

SDL_Texture* tex;
...
// All 3 instances share the SDL_Texture
MyObject A(tex);
MyObject B(tex);
MyObject C(tex);
...
// A call to set the color of the texture must be made before rendering 
// each object to ensure that any other object has not set a different color.
// E.g if the draw order was A, B, C and the color was set to be different
// for each object then before rendering B, each frame it would need to set 
// the color again otherwise it would have the color of A and the same 
// for the others    

Edit: This would also extend to SDL_SetTextureAlphaMod() and SDL_SetTextureBlendMode() or other similar functions

For reference I'm using SDL2.

Update: Originally it was thought that the call to the function is only updating a color blending flag. I have done some more investigation and this is partially correct which can be seen in the function in - http://pastebin.com/pMjgVkmM

However, if the renderer has a function assigned for SetTextureColorMod() which appears to be the case in most parts, then it mapped to a function 'SW_SetTextureColorMod()' - http://pastebin.com/qYtxD0TH

This in turn calls SDL_SetSurfaceColorMod() - http://pastebin.com/GrsVibAz

My concern here is at this point there is a potential call of SDL_InvalidateMap which I think can cause deallocation although I am not sure - http://pastebin.com/r0HGJYHT

回答1:

SDL_SetTextureColorMod doesn't update texture texels - it saves multiplier colour and raises SDL_MODTEXTURE_COLOR flag. Subsequent RenderCopy on that texture will multiply texels with fixed colour.

Since it don't modify texture, and just a little constant within texture header, it is completely ok to set it many times in render frame for the same texture. Cloning textures would be counterproductive (a lot more memory usage, and potentially lower framerate due to higher memory bandwidth pressure).



标签: sdl sdl-2