mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-05-22 12:48:28 +00:00
Add internal SDL_UpdateTextureFromSurface(), making SDL_CreateTextureFromSurface() lighter
This commit is contained in:
parent
20a6193eaa
commit
a57c566988
1 changed files with 105 additions and 53 deletions
|
@ -1495,10 +1495,111 @@ SDL_Texture *SDL_CreateTexture(SDL_Renderer *renderer, SDL_PixelFormat format, S
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int SDL_UpdateTextureFromSurface(SDL_Texture *texture, SDL_Rect *rect, SDL_Surface *surface)
|
||||||
|
{
|
||||||
|
int access;
|
||||||
|
SDL_bool direct_update;
|
||||||
|
SDL_PixelFormat tex_format;
|
||||||
|
SDL_PropertiesID surface_props;
|
||||||
|
SDL_PropertiesID tex_props;
|
||||||
|
SDL_Colorspace surface_colorspace = SDL_COLORSPACE_UNKNOWN;
|
||||||
|
SDL_Colorspace texture_colorspace = SDL_COLORSPACE_UNKNOWN;
|
||||||
|
|
||||||
|
if (texture == NULL || surface == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tex_props = SDL_GetTextureProperties(texture);
|
||||||
|
if (!tex_props) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
surface_props = SDL_GetSurfaceProperties(surface);
|
||||||
|
if (!surface_props) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tex_format = SDL_GetNumberProperty(tex_props, SDL_PROP_TEXTURE_FORMAT_NUMBER, 0);
|
||||||
|
access = SDL_GetNumberProperty(tex_props, SDL_PROP_TEXTURE_ACCESS_NUMBER, 0);
|
||||||
|
|
||||||
|
if (access != SDL_TEXTUREACCESS_STATIC && access != SDL_TEXTUREACCESS_STREAMING) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
surface_colorspace = SDL_GetSurfaceColorspace(surface);
|
||||||
|
texture_colorspace = surface_colorspace;
|
||||||
|
|
||||||
|
if (surface_colorspace == SDL_COLORSPACE_SRGB_LINEAR ||
|
||||||
|
SDL_COLORSPACETRANSFER(surface_colorspace) == SDL_TRANSFER_CHARACTERISTICS_PQ) {
|
||||||
|
if (SDL_ISPIXELFORMAT_FLOAT(tex_format)) {
|
||||||
|
texture_colorspace = SDL_COLORSPACE_SRGB_LINEAR;
|
||||||
|
} else if (SDL_ISPIXELFORMAT_10BIT(tex_format)) {
|
||||||
|
texture_colorspace = SDL_COLORSPACE_HDR10;
|
||||||
|
} else {
|
||||||
|
texture_colorspace = SDL_COLORSPACE_SRGB;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tex_format == surface->format && texture_colorspace == surface_colorspace) {
|
||||||
|
if (SDL_ISPIXELFORMAT_ALPHA(surface->format) && SDL_SurfaceHasColorKey(surface)) {
|
||||||
|
/* Surface and Renderer formats are identical.
|
||||||
|
* Intermediate conversion is needed to convert color key to alpha (SDL_ConvertColorkeyToAlpha()). */
|
||||||
|
direct_update = SDL_FALSE;
|
||||||
|
} else {
|
||||||
|
/* Update Texture directly */
|
||||||
|
direct_update = SDL_TRUE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Surface and Renderer formats are different, it needs an intermediate conversion. */
|
||||||
|
direct_update = SDL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (direct_update) {
|
||||||
|
if (SDL_MUSTLOCK(surface)) {
|
||||||
|
SDL_LockSurface(surface);
|
||||||
|
SDL_UpdateTexture(texture, rect, surface->pixels, surface->pitch);
|
||||||
|
SDL_UnlockSurface(surface);
|
||||||
|
} else {
|
||||||
|
SDL_UpdateTexture(texture, rect, surface->pixels, surface->pitch);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SDL_Surface *temp = NULL;
|
||||||
|
|
||||||
|
/* Set up a destination surface for the texture update */
|
||||||
|
temp = SDL_ConvertSurfaceAndColorspace(surface, tex_format, NULL, texture_colorspace, surface_props);
|
||||||
|
if (temp) {
|
||||||
|
SDL_UpdateTexture(texture, NULL, temp->pixels, temp->pitch);
|
||||||
|
SDL_DestroySurface(temp);
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Uint8 r, g, b, a;
|
||||||
|
SDL_BlendMode blendMode;
|
||||||
|
|
||||||
|
SDL_GetSurfaceColorMod(surface, &r, &g, &b);
|
||||||
|
SDL_SetTextureColorMod(texture, r, g, b);
|
||||||
|
|
||||||
|
SDL_GetSurfaceAlphaMod(surface, &a);
|
||||||
|
SDL_SetTextureAlphaMod(texture, a);
|
||||||
|
|
||||||
|
if (SDL_SurfaceHasColorKey(surface)) {
|
||||||
|
/* We converted to a texture with alpha format */
|
||||||
|
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
|
||||||
|
} else {
|
||||||
|
SDL_GetSurfaceBlendMode(surface, &blendMode);
|
||||||
|
SDL_SetTextureBlendMode(texture, blendMode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
SDL_Texture *SDL_CreateTextureFromSurface(SDL_Renderer *renderer, SDL_Surface *surface)
|
SDL_Texture *SDL_CreateTextureFromSurface(SDL_Renderer *renderer, SDL_Surface *surface)
|
||||||
{
|
{
|
||||||
SDL_bool needAlpha;
|
SDL_bool needAlpha;
|
||||||
SDL_bool direct_update;
|
|
||||||
int i;
|
int i;
|
||||||
SDL_PixelFormat format = SDL_PIXELFORMAT_UNKNOWN;
|
SDL_PixelFormat format = SDL_PIXELFORMAT_UNKNOWN;
|
||||||
SDL_Palette *palette;
|
SDL_Palette *palette;
|
||||||
|
@ -1605,20 +1706,6 @@ SDL_Texture *SDL_CreateTextureFromSurface(SDL_Renderer *renderer, SDL_Surface *s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (format == surface->format && texture_colorspace == surface_colorspace) {
|
|
||||||
if (SDL_ISPIXELFORMAT_ALPHA(surface->format) && SDL_SurfaceHasColorKey(surface)) {
|
|
||||||
/* Surface and Renderer formats are identical.
|
|
||||||
* Intermediate conversion is needed to convert color key to alpha (SDL_ConvertColorkeyToAlpha()). */
|
|
||||||
direct_update = SDL_FALSE;
|
|
||||||
} else {
|
|
||||||
/* Update Texture directly */
|
|
||||||
direct_update = SDL_TRUE;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* Surface and Renderer formats are different, it needs an intermediate conversion. */
|
|
||||||
direct_update = SDL_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
props = SDL_CreateProperties();
|
props = SDL_CreateProperties();
|
||||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_COLORSPACE_NUMBER, texture_colorspace);
|
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_COLORSPACE_NUMBER, texture_colorspace);
|
||||||
if (surface_colorspace == texture_colorspace) {
|
if (surface_colorspace == texture_colorspace) {
|
||||||
|
@ -1637,46 +1724,11 @@ SDL_Texture *SDL_CreateTextureFromSurface(SDL_Renderer *renderer, SDL_Surface *s
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (direct_update) {
|
if (SDL_UpdateTextureFromSurface(texture, NULL, surface) < 0) {
|
||||||
if (SDL_MUSTLOCK(surface)) {
|
|
||||||
SDL_LockSurface(surface);
|
|
||||||
SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch);
|
|
||||||
SDL_UnlockSurface(surface);
|
|
||||||
} else {
|
|
||||||
SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
SDL_Surface *temp = NULL;
|
|
||||||
|
|
||||||
/* Set up a destination surface for the texture update */
|
|
||||||
temp = SDL_ConvertSurfaceAndColorspace(surface, format, NULL, texture_colorspace, surface->internal->props);
|
|
||||||
if (temp) {
|
|
||||||
SDL_UpdateTexture(texture, NULL, temp->pixels, temp->pitch);
|
|
||||||
SDL_DestroySurface(temp);
|
|
||||||
} else {
|
|
||||||
SDL_DestroyTexture(texture);
|
SDL_DestroyTexture(texture);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
Uint8 r, g, b, a;
|
|
||||||
SDL_BlendMode blendMode;
|
|
||||||
|
|
||||||
SDL_GetSurfaceColorMod(surface, &r, &g, &b);
|
|
||||||
SDL_SetTextureColorMod(texture, r, g, b);
|
|
||||||
|
|
||||||
SDL_GetSurfaceAlphaMod(surface, &a);
|
|
||||||
SDL_SetTextureAlphaMod(texture, a);
|
|
||||||
|
|
||||||
if (SDL_SurfaceHasColorKey(surface)) {
|
|
||||||
/* We converted to a texture with alpha format */
|
|
||||||
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
|
|
||||||
} else {
|
|
||||||
SDL_GetSurfaceBlendMode(surface, &blendMode);
|
|
||||||
SDL_SetTextureBlendMode(texture, blendMode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue