Safe/acceptable to call SDL_SetTextureColorMod a lot? |
Safe/acceptable to call SDL_SetTextureColorMod a lot? |
Robotic-Brain
Guest
|
Looking at the code SDL_SetTextureColorMod() seems to alter the state of
the SDL_COPY_MODULATE_COLOR flag, which in turn might cause a texture reallocation (if I understand the meaning of SDL_InvalidateMap() right) so the worst case boils down to this code sequence: SDL_SetTextureColorMod(tex, 255, 255, 255); SDL_SetTextureColorMod(tex, anyR, anyG, anyB); SDL_SetTextureColorMod(tex, 255, 255, 255); so if you make sure never to call it with 100% white you should be fine (I would do some benchmarks though) the same seems to be true for those other functions just with other value combinations _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||
|
Safe/acceptable to call SDL_SetTextureColorMod a lot? |
Jonny D
|
If SDL_gpu would work for you and you have actual performance needs, then I would recommend that. Â It has GPU_CreateAliasImage() which you can use for shallow copies of textures (same texture data, different render settings - like color). Â It also uses sprite batching to minimize the overhead of multiple GL calls.
Jonny D On Sat, Jul 26, 2014 at 7:42 AM, Robotic-Brain wrote:
|
|||||||||||||
|
Zammalad
|
Hello, thank you for responding. If it is only changing the value of the SDL_COPY_MODULATE_COLOR flag (through bitwise operations) why would there be a texture reallocation? I'm also not quite sure what you mean regarding the worst case code sequence especially why I shouldn't set to 100% white?
|
|||||||||||||||
|
Safe/acceptable to call SDL_SetTextureColorMod a lot? |
Robotic-Brain
Guest
|
Am 26.07.2014 14:45, schrieb Zammalad:
as you can see in line 615 it just forwards the call to some renderer defined function As far as I could see directFB is the only implementation, which actually maps this to a no-op therefore all other renderers seem to use the implementation from SW_SetTextureColorMod which redirects to SDL_SetSurfaceColorMod the 100% white restriction comes from the if statements in line 324 and line 329 http://hg.libsdl.org/SDL/file/6d059ed9b6ca/src/video/SDL_surface.c#l310 Code: 310 int 311 SDL_SetSurfaceColorMod(SDL_Surface * surface, Uint8 r, Uint8 g, Uint8 b) 312 { 313 int flags; 314 315 if (!surface) { 316 return -1; 317 } 318 319 surface->map->info.r = r; 320 surface->map->info.g = g; 321 surface->map->info.b = b; 322 323 flags = surface->map->info.flags; 324 if (r != 0xFF || g != 0xFF || b != 0xFF) { 325 surface->map->info.flags |= SDL_COPY_MODULATE_COLOR; 326 } else { 327 surface->map->info.flags &= ~SDL_COPY_MODULATE_COLOR; 328 } 329 if (surface->map->info.flags != flags) { 330 SDL_InvalidateMap(surface->map); 331 } 332 return 0; 333 } _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||
|
Safe/acceptable to call SDL_SetTextureColorMod a lot? |
Sik
|
I had to look up to make sure.
Neither the OpenGL nor the Direct3D renderers seem to define a texture color modulation function... WTF? This is a really simple function for the GPU (even for immediate mode OpenGL, jeez), why isn't this supported directly by those renderers in the first place? Or am I misunderstanding the code? _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||
|
Safe/acceptable to call SDL_SetTextureColorMod a lot? |
Alex Szpakowski
Guest
|
The color modulation happens at draw time (inside GL_RenderCopy etc.), via GL_SetColor in the OpenGL backend of SDL_Render.
It is very cheap. On Jul 26, 2014, at 3:44 PM, Sik the hedgehog wrote:
_______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||
|
Safe/acceptable to call SDL_SetTextureColorMod a lot? |
Sik
|
OK that makes a lot more of sense I suppose.
2014-07-26 15:46 GMT-03:00, Alex Szpakowski:
SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||||
|
Safe/acceptable to call SDL_SetTextureColorMod a lot? |
Jonny D
|
It is cheap unless you are rendering thousands of sprites... Â then you need to batch them to avoid the glColor calls which certainly add up.
Jonny D On Saturday, July 26, 2014, Sik the hedgehog wrote:
|
|||||||||||||||||
|
Safe/acceptable to call SDL_SetTextureColorMod a lot? |
Alex Szpakowski
Guest
|
The actual draw calls will be the bottleneck in that case, not the glColor calls (again, they’re very cheap, plus they don’t cause the draw calls to do much more state validation.)
On Jul 26, 2014, at 4:37 PM, Jonathan Dearborn wrote:
_______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||
|
Zammalad
|
So... overall what would be the answer to my question - Can I safely call SDL_SetTextureColorMod and similar functions potentially many many times a render frame? Think for example if I was using particles all sharing the same texture but being drawn different colors?
The only alternative I can see is to have individual instances of the texture which would surely be a large overhead itself. |
|||||||||||
|
Safe/acceptable to call SDL_SetTextureColorMod a lot? |
Robotic-Brain
Guest
|
For something like particles - which, I assume, are rarely 100% white -
it is totally save. If you often have to alternate between 100% white and any other color, only a benchmark test can give you an answer Pseudo code: loop: SDL_SetTextureColorMod(tex, 255, 255, 255); Render SDL_SetTextureColorMod(tex, 0, 125, 255); Render end loop you could also look into what Jonathan Dearborn suggested If you need more speed Am 26.07.2014 23:26, schrieb Zammalad:
SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||
|
Zammalad
|
The thing I don't get about this though is why is it not safe to set to 100% white. Why would that be any different to setting it to a different color? I'm obviously missing something but I can't see what that is. I know you mentioned specific lines in the code, but why is that a limitation? |
|||||||||||||
|
Safe/acceptable to call SDL_SetTextureColorMod a lot? |
Robotic-Brain
Guest
|
Look closely at the if statement I quoted [1]
here with some comments: // store the flag state 323 flags = surface->map->info.flags; // 0xFF equals 255... // if you invert every boolean expression and flip AND / OR this becomes clearer: // if red == 255 AND green == 255 AND blue == 255 jump to else block // -> aka "if 100% white reset flag, else set it (remember: if and else are flipped)" 324 if (r != 0xFF || g != 0xFF || b != 0xFF) { // this sets the flag 325 surface->map->info.flags |= SDL_COPY_MODULATE_COLOR; 326 } else { // this resets it 327 surface->map->info.flags &= ~SDL_COPY_MODULATE_COLOR; 328 } // compare new flag state to stored state... 329 if (surface->map->info.flags != flags) { // ...if they differ InvalidateMap 330 SDL_InvalidateMap(surface->map); 331 } now I don't exactly know what SDL_InvalidateMap() does... But to me it looks like it stores the pixel data in a native and a user defined version. If the requested format changes, it deallocates the native version. (it also seems to do some reference counting) Now if you are deallocating stuff in there, it must be allocated somewhere else to keep a balance. (or else you would release more than you allocated) So I assume the drawing functions check the texture and re-create it if necessary. As you should know any kind of heap alloc/dealloc is potentially expensive. (unless SDL uses it's own optimized allocator, which I highly doubt since this is highly application specific) The overall structure seems to be the same for the other functions you asked about, just the values are different [1] http://hg.libsdl.org/SDL/file/6d059ed9b6ca/src/video/SDL_surface.c#l310 Am 27.07.2014 01:13, schrieb Zammalad:
_______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||
|
Safe/acceptable to call SDL_SetTextureColorMod a lot? |
Sam Lantinga
|
Most of the time you'll be using a hardware renderer and changing colors will be very very cheap. If you're concerned about performance, try rendering with all the colors and then render with all of them white and see if you see any performance difference.
Cheers! On Sat, Jul 26, 2014 at 6:06 PM, Robotic-Brain wrote:
|
|||||||||||||||
|
Re: Safe/acceptable to call SDL_SetTextureColorMod a lot? |
Zammalad
|
I can see what you are saying but unless I am mistaken (highly possible) surely the flag will change whatever color you set it to UNLESS you are setting it to the same color? So the 100% white limitation isn't actually an issue it is just used in that if statement for a different optimised way to set the flag. If the flag was white and you set it to pure blue then SDL_InvalidateMap would be called in the same way if you had set it from blue to pure white.
|
|||||||||||||||
|
Safe/acceptable to call SDL_SetTextureColorMod a lot? |
Robotic-Brain
Guest
|
I think you got it...
The issue is not setting it to white per se. The issue is changing it TO or FROM white But as I said only an actual benchmark can tell you if this is really significant... Am 27.07.2014 12:13, schrieb Zammalad:
_______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
|||||||||||||
|
Re: Safe/acceptable to call SDL_SetTextureColorMod a lot? |
Zammalad
|
Ah right I think I understand now, thanks. From what Sam said though it should be safe to do but yes I will do some benchmarking when the codebase is in a position to.
|
|||||||||||||||
|
Zammalad
|
I did some digging and also compiled SDL with debugging symbols so I could walk through the code. Seems that it is completely safe to do this as pretty much for most HW implementations (except directfb) renderer->SetTextureColorMod is NULL meaning the color and flag are set.
|
|||||||||||
|