mirror of https://github.com/libsdl-org/SDL
Add internal SDL_UpdateTextureFromSurface(), making SDL_CreateTextureFromSurface() lighter
This commit is contained in:
parent
20a6193eaa
commit
a57c566988
|
@ -1495,10 +1495,111 @@ SDL_Texture *SDL_CreateTexture(SDL_Renderer *renderer, SDL_PixelFormat format, S
|
|||
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_bool needAlpha;
|
||||
SDL_bool direct_update;
|
||||
int i;
|
||||
SDL_PixelFormat format = SDL_PIXELFORMAT_UNKNOWN;
|
||||
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();
|
||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_COLORSPACE_NUMBER, texture_colorspace);
|
||||
if (surface_colorspace == texture_colorspace) {
|
||||
|
@ -1637,46 +1724,11 @@ SDL_Texture *SDL_CreateTextureFromSurface(SDL_Renderer *renderer, SDL_Surface *s
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (direct_update) {
|
||||
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);
|
||||
return NULL;
|
||||
}
|
||||
if (SDL_UpdateTextureFromSurface(texture, NULL, surface) < 0) {
|
||||
SDL_DestroyTexture(texture);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue