Re: [hatari-devel] use of SDL_RenderClear with SDL2

[ Thread Index | Date Index | More lists.tuxfamily.org/hatari-devel Archives ]


Le 22/02/2017 à 21:14, Eero Tamminen a écrit :
Hi,

On 02/22/2017 08:09 PM, Nicolas Pomarède wrote:
in the wrapper functions SDL_UpdateRects used only for SDL2, I see :

SDL_UpdateTexture(sdlTexture, NULL, screen->pixels, screen->pitch);
SDL_RenderClear(sdlRenderer);
SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, NULL);
SDL_RenderPresent(sdlRenderer);

Why is there a call to SDL_RenderClear since we copy the texture on
screen anyway just after ?

There's no clear color set anywhere in Hatari sources,
so it's using some (SDL2?) "default" color.

Hi

In that case, the default RGBA value is 0/0/0/0, so black.



At least, if I comment SDL_RenderClear I still get correct results on
screen. Maybe it's just to clear some parts of the screen near border
and status bar,

With NULL args, RenderCopy() is filling the whole target,
so no.

(Updating whole screen every frame is typical with 3D,
drivers may not even have support for partial updates.)


but isn't it too much to clear the whole screen on each frame ?
Or am I missing something ?

It's redundant[1], but overhead from it is only small
percentage of what you'd think.

Such clear doesn't actually write anything to the frame
buffer, just marks some bit(s) in an auxiliary buffer
that is used to indicate which of the (normally 32-bit)
pixels in the frame buffer have been "fast cleared", but
not yet written.

Then, just before the frame is shown on screen, only
pixels that haven't been overwritten yet, will actually
be set with the specified clear color (= driver asks GPU
to "resolve" fast clear).  In above case, no writes are
needed at this stage, as copy overwrote the whole buffer.

This is standard performance feature with GPUs and
their 3D drivers.


I know this kind of deferred rendering (this is used for example in the EFL libraries), but SDL2 doesn't do that.

In SW rendered mode, SDL_SetRenderDrawColor calls SDL_FillRect, which then calls SDL_memset and just fill as many bytes as in the surface, I saw no such thing as invalidating the rows and deferring color filling until the whole surface is copied on screen (same in other renderers (GL, GLES, ... ) the code path is similar to SW)

For a simpler test, in screen.c SDL_UpdateRects() if I set color to red:

  SDL_UpdateTexture(sdlTexture, NULL, screen->pixels, screen->pitch);
+  SDL_SetRenderDrawColor(sdlRenderer, 0xA0, 0x00, 0x00, 0xFF);
  SDL_RenderClear(sdlRenderer);
  SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, NULL);
  SDL_RenderPresent(sdlRenderer);

Then I never see any red pixel on screen, except a very brief time at boot when changing resolution from STF to falcon mode for example.

So in normal operations, all pixels filled with RenderClear seem to be overwritten by RenderCopy, making the Clear useless.

But if you comment SDL_RenderCopy, you will see the screen is indeed red, so the SDL_RenderClear was correctly applied.

Now, as SDL uses some SSE optimized path to do SDL_memset (or even the gpu), the effect of calling SDL_RenderClear will be rather low in cpu/gpu usage, but it's still there.

I will commit a change to remove it, unless someone notice a regression later.

Nicolas



    - Eero

[1] If there is some part of frame buffer that isn't
written during frame, that part is in undefined state.

Previous frame contents are not guaranteed to be copied
to new frame (for obvious performance reasons), especially
when double/triple buffering is used.

That's why 3D programs often start frame with clear.


this description doesn't seem related to how SDL works.





Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/