SDL_UpdateTexture ARGB much faster than RGBA

0

I was trying to use SDL_UpdateTexture to create a texture from an allocated buffer of pixels, and I was surprised that it wasn't even rendering at 60fps (with the main culprit being SDL_UpdateTexture):

#include <SDL2/SDL.h>
#include <sys/time.h>

static double time_in_ms(void) {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0;
}

int main(void) {
    SDL_Init(SDL_INIT_VIDEO);
    SDL_Window *window = SDL_CreateWindow("Pixel formats" , 0, 0, 1920, 1080, 0);
    SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    double last_frame = time_in_ms();
    while (1) {
        int width, height;
        SDL_Event e;
        while (SDL_PollEvent(&e)) {
            if (e.type == SDL_QUIT) {
                return 0;
            }
        }
        SDL_GetWindowSize(window, &width, &height);
        SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, width, height);
        Uint32 *pixels = malloc(width * height * sizeof(*pixels));
        /* fill buffer with blue pixels */
        for (int y = 0; y < height; y++) {
            Uint32 *row = pixels + y * width;
            for (int x = 0; x < width; x++) {
                row[x] = 0x0000FFFF;
            }
        }

        double update_begin = time_in_ms();
        SDL_UpdateTexture(texture, NULL, pixels, width * sizeof(*pixels));
        double update_end = time_in_ms();
        SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_NONE);
        SDL_RenderCopy(renderer, texture, NULL, NULL);
        SDL_RenderPresent(renderer);
        SDL_DestroyTexture(texture);
        free(pixels);
        double this_frame = time_in_ms();
        printf("frame took %fms\n", this_frame - last_frame);
        printf(" - update texture: %fms\n", update_end - update_begin);
        last_frame = this_frame;
    }

}

But, if I just change SDL_PIXELFORMAT_RGBA8888 to SDL_PIXELFORMAT_ARGB8888 (and update 0x0000FFFF to 0xFF0000FF), all of a sudden, SDL_UpdateTexture goes down from taking ~15ms per frame to ~1ms. This happens regardless of whether renderer is an accelerated or software renderer. This seems very strange to me, since even if SDL_Textures are internally ARGB, it takes far less than 15ms to convert from RGBA to ARGB:

for (int y = 0; y < height; y++) {
    Uint32 *row = pixels + y * width;
    for (int x = 0; x < width; x++) {
        Uint32 a = row[x] & 0xFF;
        row[x] >>= 8;
        row[x] |= a << 24;
    }
}

Why might it be that SDL_UpdateTexture is so much faster with ARGB than RGBA (and does this vary across platforms)?

(SDL_PIXELFORMAT_RGB888 is also quite fast (~2ms), but not as fast as ARGB)

c
sdl-2
rgba
argb
asked on Stack Overflow Aug 8, 2019 by pommicket

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0