[SDL] SDL_RenderClear() performance issue

Sam Lantinga slouken at libsdl.org
Wed Oct 2 23:33:48 PDT 2013


Mac OS X 10.8 on a 2008 Mac Pro:
Hardware Render to screen - SDL_FillRect, average   1402.26 microseconds
Hardware Render to screen - SDL_RenderClear, average    611.11 microseconds
Hardware Render to texture - SDL_FillRect, average     84.64 microseconds
Hardware Render to texture - SDL_RenderClear, average     16.82 microseconds
Software Render to screen - SDL_FillRect, average   1065.36 microseconds
Software Render to screen - SDL_RenderClear, average   1003.36 microseconds
Software Render to texture - SDL_FillRect, average    889.33 microseconds
Software Render to texture - SDL_RenderClear, average    858.78 microseconds


On Wed, Oct 2, 2013 at 8:01 AM, lloyd_b <lloydbaz at msn.com> wrote:

> **
> I noticed an unexpected change in performance while tweaking a program,
> and put together a test case help clarify the reason for the change.
>
> Basically, on my system, when the render target is set to a texture, using
> SDL_RenderClear() takes a horrific amount of time (over 100 ms). But on the
> same target, doing a SDL_RenderFillRect() of the entire texture is quite
> reasonable (about 1.5 ms). This only happens with a texture as a target,
> and if I've specified SDL_RENDERER_ACCELERATED when creating the renderer.
> With SDL_RENDERER_SOFTWARE, the times for everything are much longer (no
> surprise), but they are consistent between SDL_RenderClear() and
> SDL_RenderFillRect().
>
> I don't see how this could be an SDL bug - I don't see anything in the
> code that could cause SDL_RenderClear() to behave differently for a texture
> target rather than a screen target. So I'm assuming the bug is at a lower
> level (Mesa, or the video driver).
>
> For the record - my "play around" system is an older Celeron, using an
> older Radeon card. System runs Xubuntu Precise, Mesa 1.2, and
> xserver-xorg-video-radeon 1.6.14.
>
> Could a few others please run this code, and verify that it's a "my
> machine" type issue (I suspect the Radeon driver as a culprit, but I'd like
> some confirmation). Here's my teset results:
>
>
>
>  Code:
>
>  lloyd at Dell:~/src/test$ ./testcase
> Hardware Render to screen - SDL_FillRect, average   1540.02 microseconds
> Hardware Render to screen - SDL_RenderClear, average   1618.40 microseconds
> Hardware Render to texture - SDL_FillRect, average   1594.33 microseconds
> Hardware Render to texture - SDL_RenderClear, average 100435.69
> microseconds
> Software Render to screen - SDL_FillRect, average  11118.92 microseconds
> Software Render to screen - SDL_RenderClear, average  11218.12 microseconds
> Software Render to texture - SDL_FillRect, average  11255.74 microseconds
> Software Render to texture - SDL_RenderClear, average  11253.91
> microseconds
> lloyd at Dell:~/src/test$
>
>
>
>
> And the test case code
>
>
>
>  Code:
>
>
> #include **
> #include **
> #include **
>
> void test_loop(struct SDL_Renderer * rend, const char * ident)
> {
>    int x, start, start2, stop, elapsed;
>    float average1, average2;
>    struct SDL_Rect rect;
>    struct timeval tv;
>    struct timezone tz;
>
>     rect.x = 0;
>         rect.y = 0;
>         rect.h = 480;
>         rect.w = 640;
>         for(x = 0; x < 255; x++) {
>                 gettimeofday(&tv, &tz);
>                 start = tv.tv_usec;
>                 start2 = tv.tv_sec;
>                 SDL_SetRenderDrawColor(rend, x, x, x, 255);
>                 SDL_RenderFillRect(rend, &rect);
>                 SDL_RenderPresent(rend);
>
>                 gettimeofday(&tv, &tz);
>                 stop = tv.tv_usec;
>                 if (start2 < tv.tv_sec)
>                         stop += ((tv.tv_sec - start2) * 1000000);
>                 elapsed = stop - start;
>
>                 if (x == 0) {
>                         average1 = elapsed;
>                 } else {
>                         average1 = ((average1 * x) + elapsed) / (x + 1);
>                 }
>         }
>    printf("%s - SDL_FillRect, average %9.2f microseconds\n", ident,
> average1);
>
>    for(x = 0; x < 255; x++) {
>                 gettimeofday(&tv, &tz);
>                 start = tv.tv_usec;
>                 start2 = tv.tv_sec;
>                 SDL_SetRenderDrawColor(rend, (255 - x), (255 - x), (255 -
> x), 255);
>                 SDL_RenderClear(rend);
>                 SDL_RenderPresent(rend);
>
>                 gettimeofday(&tv, &tz);
>                 stop = tv.tv_usec;
>                 if (start2 < tv.tv_sec)
>                         stop += ((tv.tv_sec - start2) * 1000000);
>                 elapsed = stop - start;
>
>                 if (x == 0) {
>                         average2 = elapsed;
>                 } else {
>                         average2 = ((average2 * x) + elapsed) / (x + 1);
>                 }
>         }
>    printf("%s - SDL_RenderClear, average %9.2f microseconds\n", ident,
> average2);
> }
>
> int main(int argc, char** argv) {
>
>    struct SDL_Window * wind[2] = {NULL, NULL};
>    struct SDL_Renderer * rend[2] = {NULL, NULL};
>    struct SDL_Texture * text[2] = {NULL, NULL};
>    struct SDL_RendererInfo info;
>    int x;
>
>    SDL_Init(SDL_INIT_EVERYTHING);
>
>    for (x = 0; x < 2; x++) {
>       wind[x] = SDL_CreateWindow("Testing", (x * 100) + 100, 100,
>                   640, 480, SDL_WINDOW_SHOWN);
>       if ( wind[x] == NULL ) {
>          printf("Couldn't create window %d - %s\n", x, SDL_GetError());
>          return -1;
>       }
>
>       if ( x == 0 ) {
>          rend[0] = SDL_CreateRenderer(wind[0], -1,
> SDL_RENDERER_ACCELERATED |
>
>  SDL_RENDERER_TARGETTEXTURE);
>          if ( rend[0] == NULL) {
>             printf("Error creating hardware renderer  - %s\n",
> SDL_GetError());
>             return -1;
>          }
>       } else {
>          rend[1] = SDL_CreateRenderer(wind[1], -1, SDL_RENDERER_SOFTWARE |
>                         SDL_RENDERER_TARGETTEXTURE);
>          if ( rend[1] == NULL ) {
>             printf("Error creating software renderer - %s\n",
> SDL_GetError());
>             return -1;
>          }
>       }
>
>       SDL_RenderClear(rend[x]);
>       SDL_RenderPresent(rend[x]);
>
>       text[x] = SDL_CreateTexture(rend[x], 0, SDL_TEXTUREACCESS_TARGET,
> 640, 480);
>
>       if ( text[x] == NULL ) {
>          printf("Error creating texutre %d - %s\n", x, SDL_GetError());
>          return -1;
>       }
>    }
>
>    test_loop(rend[0], "Hardware Render to screen");
>
>    SDL_SetRenderTarget(rend[0], text[0]);
>    test_loop(rend[0], "Hardware Render to texture");
>
>    test_loop(rend[1], "Software Render to screen");
>
>    SDL_SetRenderTarget(rend[1], text[1]);
>    test_loop(rend[1], "Software Render to texture");
>
>    SDL_DestroyTexture(text[0]);
>    SDL_DestroyTexture(text[1]);
>    SDL_DestroyRenderer(rend[0]);
>    SDL_DestroyRenderer(rend[1]);
>    SDL_Quit();
>    return 0;
> }
>
>
>
> _______________________________________________
> SDL mailing list
> SDL at lists.libsdl.org
> http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20131002/c031e639/attachment-0009.htm>


More information about the SDL mailing list