SDL_UpdateTexture vs Locking

Hello,

I am not new to SDL (2D software rendering part), but I am new to SDL2. I was wondering what is the proper way to update a streaming texture?

I have been experimenting with using SDL_UpdateTexture and with SDL_LockTexture(). From my highly non-scientific benchmarking, it seems that
SDL_UpdateTexture() is slightly faster than using SDL_LockTexture().

My experimentation consists of using a loop to get a frame from ffmpeg (ignoring timestamps) and rendering/blitting that frame
to the current window/texture. I have a single texture that uses SDL_TEXTUREACCESS_STREAMING. The pixel format for both the texture and the
frame that I get from ffmpeg is RGB24.

Using SDL_UpdateTexture() I do something along the lines of (in a loop):

const unsigned char *frame_data = function_that_gets_frame_using_ffmpeg();

SDL_UpdateTexture(texture, NULL, frame_data, pitch);

Where ‘texture’ is a single, streaming texture for the single renderer and window. Pitch is known as well.

My other experiment was to use SDL_LockTexture(), again in a loop (omitting error checking):

const unsigned char *frame_data = function_that_gets_frame_using_ffmpeg();

byte_t *texture_data = NULL;
int texture_pitch = 0;

SDL_LockTexture(texture, 0, (void**)&texture_data, &texture_pitch));

memcpy(texture_data, frame_data, whBpp);

SDL_UnlockTexture(texture);

Where, w, h and Bpp are known.

The reason I ask is that the docs for SDL_UpdateTexture() state the function is fairly slow. Could that be relative and not be noticeable
in my trivial experiments?

If it matters, I am planning on trying the same experiments on my Android (4.0) tablet. I have a working Android project thanks to the excellent
documentation in README.android.

Any advice, insights or comments would be greatly appreciated. Thanks.

Cheers,

Alvin

I have been experimenting with using SDL_UpdateTexture and with
SDL_LockTexture(). From my highly non-scientific benchmarking, it seems that
SDL_UpdateTexture() is slightly faster than using SDL_LockTexture().

Well I have a more complex program that uploads 25 times per second 24
h.264 video streams on 24 different textures that are blitted to a single
(fullscreen) window, and I found results similar to yours.

Using SDL_UpdateTexture over SDL_Lock/UnlockTexture uses 5% less CPU time.

The advantage of SDL_UpdateTexture over SDL_LockTexture() is logical
because when you unlock the texture you have to copy the “shadow” buffer
data to the texture doing something very similar to what SDL_UpdateTexture
does… so you save a copy operation for every frame you process.

If you your image is contained in a single memory area SDL_UpdateTexture is
better than SDL_Lock/UnlockTexture(), and this is also true now for YV12
textures (where usually you have three different planes) since with SDL
2.0.1 SDL_UpdateYUVTexture you can pass those different pointers straight
to the underlying hardware.

My experimentation consists of using a loop to get a frame from ffmpeg
(ignoring timestamps) and rendering/blitting that frame
to the current window/texture. I have a single texture that uses
SDL_TEXTUREACCESS_STREAMING. The pixel format for both the texture and the
frame that I get from ffmpeg is RGB24.

I’m working with YV12 format (ffmpeg calls it PIX_FMT_YUV420P, SDL calls it
SDL_PIXELFORMAT_YV12), this will help your performances since decoded
mpeg1/2/4/x video is in YUV format, and to give you a RGB image ffmpeg must
do a conversion that can be done in hardware by the GPU.>

Bye,
Gabry

Using SDL_UpdateTexture over SDL_Lock/UnlockTexture uses 5% less CPU time.

I think the use-case for this was that “locking” a texture was useful
when you had to read back the pixels (since SDL would cache a copy in
RAM, you didn’t have to read it back from the GPU), but at a minimum,
“streaming” was an unfortunate choice of words, since it implies
write-only semantics, which is the opposite of what SDL actually does
here. “Dynamic” might have been a better choice.

If you’re keeping a copy in memory anyhow, and/or updating every pixel
for each upload, SDL_UpdateTexture() is the better choice. There may be
questions about performance of texture access types, however, and I
haven’t measured these: even if you aren’t using SDL_LockTexture(), the
texture object might change its performance characteristics (Mac OS X
puts them in shared memory with the GPU, Direct3D marks it as "dynamic"
usage, etc).

We should probably clean this up in SDL 2.1.

–ryan.

Thank you Gabriele and Ryan. I will stick with using SDL_UpdateTexture() for now. Currently, my requirements are for write-only access
at this point.

BTW, the documentation in the wiki (e.g. API, Migrating from 1.2, etc.) are excellent! The various examples in test/ have been extremely
helpful as well.

Cheers,

AlvinOn 11/11/13 12:33, Ryan C. Gordon wrote:

Using SDL_UpdateTexture over SDL_Lock/UnlockTexture uses 5% less CPU time.

I think the use-case for this was that “locking” a texture was useful when you had to read back the pixels (since SDL would cache a copy in RAM, you didn’t have to read it back from the GPU), but at a minimum, “streaming” was an unfortunate choice of words, since it implies write-only semantics, which is the opposite of what SDL actually does here. “Dynamic” might have been a better choice.

If you’re keeping a copy in memory anyhow, and/or updating every pixel for each upload, SDL_UpdateTexture() is the better choice. There may be questions about performance of texture access types, however, and I haven’t measured these: even if you aren’t using SDL_LockTexture(), the texture object might change its performance characteristics (Mac OS X puts them in shared memory with the GPU, Direct3D marks it as “dynamic” usage, etc).

We should probably clean this up in SDL 2.1.

–ryan.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org