diff -r c005c49beaa9 src/render/SDL_render.c --- a/src/render/SDL_render.c Sat Feb 23 09:36:56 2019 +0100 +++ b/src/render/SDL_render.c Wed Feb 27 12:48:01 2019 -0500 @@ -1088,7 +1088,7 @@ } SDL_Texture * -SDL_CreateTexture(SDL_Renderer * renderer, Uint32 format, int access, int w, int h) +SDL_CreateTexture_Internal(SDL_Renderer * renderer, Uint32 format, int access, int w, int h, SDL_Surface* surface) { SDL_Texture *texture; @@ -1129,6 +1129,7 @@ texture->b = 255; texture->a = 255; texture->scaleMode = SDL_GetScaleMode(); + texture->surface = surface; texture->renderer = renderer; texture->next = renderer->textures; if (renderer->textures) { @@ -1142,9 +1143,9 @@ return NULL; } } else { - texture->native = SDL_CreateTexture(renderer, + texture->native = SDL_CreateTexture_Internal(renderer, GetClosestSupportedFormat(renderer, format), - access, w, h); + access, w, h, surface); if (!texture->native) { SDL_DestroyTexture(texture); return NULL; @@ -1183,6 +1184,12 @@ } SDL_Texture * +SDL_CreateTexture(SDL_Renderer *renderer, Uint32 format, int access, int w, int h) +{ + return SDL_CreateTexture_Internal(renderer, format, access, w, h, NULL); +} + +SDL_Texture * SDL_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface) { const SDL_PixelFormat *fmt; @@ -1227,12 +1234,6 @@ } } - texture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_STATIC, - surface->w, surface->h); - if (!texture) { - return NULL; - } - if (format == surface->format->format) { if (surface->format->Amask && SDL_HasColorKey(surface)) { /* Surface and Renderer formats are identicals. @@ -1248,12 +1249,23 @@ } 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); + int surface_ref_count = surface->refcount; + texture = SDL_CreateTexture_Internal(renderer, format, SDL_TEXTUREACCESS_STATIC, surface->w, surface->h, surface); + if (!texture) + { + return NULL; + } + /* ref count the same need update */ + if (surface_ref_count == surface->refcount) + { + 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_PixelFormat *dst_fmt; @@ -1262,18 +1274,23 @@ /* Set up a destination surface for the texture update */ dst_fmt = SDL_AllocFormat(format); if (!dst_fmt) { - SDL_DestroyTexture(texture); return NULL; } temp = SDL_ConvertSurface(surface, dst_fmt, 0); SDL_FreeFormat(dst_fmt); - if (temp) { - SDL_UpdateTexture(texture, NULL, temp->pixels, temp->pitch); - SDL_FreeSurface(temp); - } else { - SDL_DestroyTexture(texture); + if (!temp){ return NULL; } + int surface_ref_count = temp->refcount; + texture = SDL_CreateTexture_Internal(renderer, format, SDL_TEXTUREACCESS_STATIC, temp->w, temp->h, temp); + if (!texture) + { + SDL_FreeSurface(temp); + return NULL; + } + if (surface_ref_count == temp->refcount) // ref count the same need update + SDL_UpdateTexture(texture, NULL, temp->pixels, temp->pitch); + SDL_FreeSurface(temp); } { diff -r c005c49beaa9 src/render/SDL_sysrender.h --- a/src/render/SDL_sysrender.h Sat Feb 23 09:36:56 2019 +0100 +++ b/src/render/SDL_sysrender.h Wed Feb 27 12:48:01 2019 -0500 @@ -51,6 +51,7 @@ SDL_BlendMode blendMode; /**< The texture blend mode */ SDL_ScaleMode scaleMode; /**< The texture scale mode */ Uint8 r, g, b, a; /**< Texture modulation values */ + SDL_Surface *surface; SDL_Renderer *renderer; diff -r c005c49beaa9 src/render/software/SDL_render_sw.c --- a/src/render/software/SDL_render_sw.c Sat Feb 23 09:36:56 2019 +0100 +++ b/src/render/software/SDL_render_sw.c Wed Feb 27 12:48:01 2019 -0500 @@ -102,9 +102,15 @@ return SDL_SetError("Unknown texture format"); } - texture->driverdata = - SDL_CreateRGBSurface(0, texture->w, texture->h, bpp, Rmask, Gmask, - Bmask, Amask); + if (texture->surface) { + texture->driverdata = + SDL_CreateRGBSurfaceFrom(texture->surface->pixels, texture->w, texture->h, bpp, texture->surface->pitch, Rmask, Gmask, Bmask, Amask); + ++texture->surface->refcount; + } else { + texture->driverdata = + SDL_CreateRGBSurface(0, texture->w, texture->h, bpp, Rmask, Gmask, Bmask, Amask); + } + SDL_SetSurfaceColorMod(texture->driverdata, texture->r, texture->g, texture->b); SDL_SetSurfaceAlphaMod(texture->driverdata, texture->a); @@ -755,6 +761,7 @@ { SDL_Surface *surface = (SDL_Surface *) texture->driverdata; + SDL_FreeSurface(texture->surface); SDL_FreeSurface(surface); }