=====================================================
SDL Source Analysis Series Articles list:
SDL2 Source Analysis 1: Initialization (Sdl_init ())
SDL2 Source Analysis 2: Form (Sdl_window)
SDL2 Source Analysis 3: Renderer (Sdl_renderer)
SDL2 Source Analysis 4: Textures (sdl_texture)
SDL2 Source Analysis 5: Update textures (sdl_updatetexture ())
SDL2 Source Analysis 6: Copy to Renderer (Sdl_rendercopy ())
SDL2 Source Analysis 7: Display (Sdl_renderpresent ())
SDL2 Source Analysis 8: Video Display summary
=====================================================
The previous article analyzed the creation of the SDL texture function sdl_createtexture (). This article continues to analyze SDL's source code. This article analyzes the SDL update texture data function sdl_updatetexture ().
The code flow for the SDL playback video is as seen below.
Initialize:
Sdl_init (): Initialize SDL.
Sdl_createwindow (): Create form (Window).
Sdl_createrenderer (): Creates a renderer (render) based on a form.
Sdl_createtexture (): Creates a texture (Texture).
To iterate over the rendered data:
sdl_updatetexture (): Sets the data for the texture.
Sdl_rendercopy (): Textures are copied to the renderer.
Sdl_renderpresent (): Display.
The 4th function in this process, sdl_createtexture (), was analyzed in the previous article. This article continues to analyze the 5th function sdl_updatetexture () in the process.
The Sdl_updatetexture () function provides a simple introduction to the pixel data used by SDL to set textures using sdl_updatetexture ().
The prototypes for Sdl_updatetexture () are as follows.
int Sdlcall sdl_updatetexture (sdl_texture * Texture, const sdl_rect * Rect, const void *pixels, int pitch);
The meaning of the parameters is as follows.
Texture: Target texture.
Rect: Updates the rectangular area of the pixel. When set to NULL, the entire area is updated.
Pixels: Pixel data.
Pitch: The number of bytes in a row of pixel data.
The successful words return 0, and the failure returns-1.
Function call Graph Sdl_updatetexture () the invocation relationship of the key function can be represented.
watermark/2/text/ahr0cdovl2jsb2cuy3nkbi5uzxqvbgvpeglhb2h1ytewmja=/font/5a6l5l2t/fontsize/400/fill/i0jbqkfcma== /dissolve/70/gravity/southeast "/>
The picture above is not very clear. A clearer picture is uploaded to the album:
http://my.csdn.net/leixiaohua1020/album/detail/1793769
Save the picture in the album to get a clear picture.
SOURCE Analysis
The source code for Sdl_updatetexture () is located in Render\sdl_render.c. For example, see below.
int Sdl_updatetexture (sdl_texture * Texture, const sdl_rect * Rect, const void *pixels, int pitch) { Sdl_renderer * renderer; Sdl_rect Full_rect; Check_texture_magic (TEXTURE,-1); if (!pixels) { return sdl_invalidparamerror ("Pixels"); } if (!pitch) { return sdl_invalidparamerror ("pitch"); } if (!rect) { full_rect.x = 0; Full_rect.y = 0; FULL_RECT.W = texture->w; Full_rect.h = texture->h; Rect = &full_rect; } if (TEXTURE->YUV) { return SDL_UPDATETEXTUREYUV (texture, rect, pixels, pitch); } else if (texture-> native) { return sdl_updatetexturenative (texture, rect, pixels, pitch); } else { renderer = texture-> renderer; Return renderer->updatetexture (renderer, texture, rect, pixels, pitch);} }
As can be seen from the source code, Sdl_updatetexture () the approximate process such as the following.
1. Check the rationality of the input parameters. such as whether the pixel format is supported, width and height is less than or equal to 0 and so on.
2. Assume that there are some special formats for certain processing:
a) assuming that the input pixel data is in YUV format, SDL_UPDATETEXTUREYUV () is called to process.
b) Assuming that the pixel format of the input pixel data is not the format supported by the renderer, sdl_updatetexturenative () is called to process.
3.
Call Sdl_render's Updatetexture () method to update the texture.
This step is the core of the whole function.
Here's a look at a couple of different renderer updatetexture () methods.
1.the function of the corresponding updatetexture () in the Direct3ddirect3d renderer is d3d_updatetexture (), and its source code, for example, is seen in the following (Render\direct3d\sdl_ RENDER_D3D.C).
Static Intd3d_updatetexture (Sdl_renderer * Renderer, Sdl_texture * Texture, const SDL_RECT * Rect, const void *pixels, int pitch) {D3d_texturedata *data = (D3d_texturedata *) texture->driverdata; Sdl_bool full_texture = sdl_false; #ifdef use_dynamic_texture if (texture->access = = Sdl_textureaccess_streaming & ;& rect->x = = 0 && Rect->y = = 0 && rect->w = texture->w && rect-> ; h = = texture->h) {full_texture = Sdl_true; } #endif if (!data) {sdl_seterror ("Texture is not currently available"); return-1; } if (D3d_updatetextureinternal (Data->texture, Texture->format, Full_texture, Rect->x, Rect->y, rect-> W, rect->h, pixels, pitch) < 0) {return-1; } if (DATA->YUV) {/* Skip to the correct offset into the next texture */pixels = (const void*) ((cons T uint8*) pixels + rect->h * pitch); if (D3d_updatetextureinternal (Texture->format = = Sdl_pixelformat_yv12 Data->vtexture:data->utexture, Texture->format, Full_ Texture, RECT->X/2, RECT->Y/2, RECT->W/2, RECT->H/2, pixels, PITCH/2) < 0) {return-1 ; }/* Skip to the correct offset into the next texture */pixels = (const void*) ((const uint8*) pixels + (rect ->h * pitch)/4); if (d3d_updatetextureinternal (Texture->format = = Sdl_pixelformat_yv12?)Data->utexture:data->vtexture, Texture->format, Full_texture, RECT->X/2, RECT->Y/2, RECT->W/2, R ECT->H/2, pixels, PITCH/2) < 0) {return-1; }} return 0;}
As can be seen from the code, the function calls the D3d_updatetextureinternal () function. It is important to note that the input pixel format is YUV. 3 textures will be used, and the extra 2 textures will be processed separately. Call the function d3d_updatetextureinternal () code such as the following.
static int d3d_updatetextureinternal (Idirect3dtexture9 *texture, Uint32 format, sdl_bool full_texture, int x, int y, int w , int h, const void *pixels, int pitch) {RECT d3drect; D3dlocked_rect locked; Const UINT8 *SRC; Uint8 *DST; int row, length; HRESULT result; if (full_texture) {result = Idirect3dtexture9_lockrect (texture, 0, &locked, NULL, D3dlock_discard); } else {d3drect.left = x; D3drect.right = x + W; D3drect.top = y; D3drect.bottom = y + H; result = Idirect3dtexture9_lockrect (texture, 0, &locked, &d3drect, 0); } if (FAILED (Result)) {return D3d_seterror ("LockRect ()", result); } src = (const Uint8 *) pixels; DST = locked.pbits; Length = w * sdl_bytesperpixel (format); if (length = = Pitch && length = = locked. Pitch) {sdl_memcpy (DST, SRC, length*h); } else {if (length > pitch) {length = pitch; } if (length > Locked. Pitch) {length = locked. Pitch; } for (row = 0; row < h; ++row) {sdl_memcpy (DST, src, length); src + = pitch; DST + = locked. Pitch; }} idirect3dtexture9_unlockrect (texture, 0); return 0;}
As can be seen from the code, the function first calls Idirect3dtexture9_lockrect () to lock the texture. Then use sdl_memcpy () to copy the new pixel data to the texture (sdl_memcpy () is actually memcpy ()), and finally use Idirect3dtexture9_unlockrect () to unlock the texture. 2.The function of the corresponding updatetexture () in the Openglopengl renderer is gl_updatetexture (). Its source code, for example, is seen below (located in render\opengl\sdl_render_gl.c).
static int Gl_updatetexture (Sdl_renderer * Renderer, Sdl_texture * Texture, const SDL_RECT * Rect, const V OID *pixels, int pitch) {Gl_renderdata *renderdata = (Gl_renderdata *) renderer->driverdata; Gl_texturedata *data = (Gl_texturedata *) texture->driverdata; Gl_activaterenderer (renderer); Renderdata->glenable (Data->type); Renderdata->glbindtexture (Data->type, data->texture); Renderdata->glpixelstorei (gl_unpack_alignment, 1); Renderdata->glpixelstorei (Gl_unpack_row_length, (Pitch/sdl_bytesperpixel (texture->for MAT)); Renderdata->gltexsubimage2d (data->type, 0, Rect->x, Rect->y, Rect->w, rect-& Gt;h, Data->format, data->formattype, pixels); if (DATA->YUV) {Renderdata->glpixelstorei (Gl_unpack_row_length, (PITCH/2)); /* Skip to the correct offset into the next texture */Pixels = (const void*) ((const uint8*) pixels + rect->h * pitch); if (Texture->format = = sdl_pixelformat_yv12) {renderdata->glbindtexture (Data->type, Data->vtexture ); } else {renderdata->glbindtexture (data->type, data->utexture); } renderdata->gltexsubimage2d (Data->type, 0, RECT->X/2, RECT->Y/2, R ECT->W/2, RECT->H/2, Data->format, data->formattype, pixels); /* Skip to the correct offset into the next texture */pixels = (const void*) ((const uint8*) pixels + (RECT->H * Pitch)/4); if (Texture->format = = sdl_pixelformat_yv12) {renderdata->glbindtexture (Data->type, Data->utexture ); } else {renderdata->glbindtexture (data->type, data->vtexture); } renderdata->gltexsubimage2d (Data->type, 0, RECT->X/2, RECT->Y/2, RECT->W/2, RECT->H/2, Data->format, data->formattype, pixels ); } renderdata->gldisable (Data->type); Return Gl_checkerror ("Gltexsubimage2d ()", renderer);}
Can be seen from the code. The function calls the OpenGL API function Glbindtexture (), gltexsubimage2d (), and so on to update a texture.
One thing to note here is that if the input pixel format is YUV, 3 textures will be used, and the extra 2 textures will be processed separately. 3.The function of the corresponding updatetexture () in the Softwaresoftware renderer is sw_updatetexture (). Its source code, for example, is seen below (located in render\software\sdl_render_sw.c).
static int Sw_updatetexture (Sdl_renderer * Renderer, Sdl_texture * Texture, const SDL_RECT * Rect, const void *pixels, int pitch) { Sdl_surface *surface = (sdl_surface *) texture->driverdata; Uint8 *src, *DST; int row; size_t length; if (Sdl_mustlock (surface)) sdl_locksurface (surface); src = (Uint8 *) pixels; DST = (Uint8 *) Surface->pixels + rect->y * surface->pitch + rect->x * surface->format-> Bytesperpixel; Length = rect->w * surface->format->bytesperpixel; for (row = 0; row < rect->h; ++row) { sdl_memcpy (DST, src, length); src + = pitch; DST + = surface->pitch; } if (Sdl_mustlock (surface)) sdl_unlocksurface (surface); return 0;}
The source code for this function has not been specifically analyzed. The most critical function is the number of sdl_memcpy (), and it is this function that updates the texture's pixel data. But is there a need for lock () and unlock () when the software renderer texture is changed? This has not been very clear.
SDL2 Source Analysis 5: Update textures (sdl_updatetexture ())