Scaling fallbacks for the SW renderer (bug 5313)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
diff --git a/src/video/SDL_surface.c b/src/video/SDL_surface.c
index dbb66aa..f748e43 100644
--- a/src/video/SDL_surface.c
+++ b/src/video/SDL_surface.c
@@ -927,17 +927,52 @@ SDL_PrivateLowerBlitScaled(SDL_Surface * src, SDL_Rect * srcrect,
SDL_InvalidateMap(src->map);
}
- if ( !(src->map->info.flags & complex_copy_flags) &&
- src->format->format == dst->format->format &&
- !SDL_ISPIXELFORMAT_INDEXED(src->format->format) ) {
-
- if (scaleMode != SDL_ScaleModeNearest && src->format->BytesPerPixel == 4 && src->format->format != SDL_PIXELFORMAT_ARGB2101010) {
- return SDL_SoftStretchLinear(src, srcrect, dst, dstrect);
- } else {
+ if (scaleMode == SDL_ScaleModeNearest) {
+ if ( !(src->map->info.flags & complex_copy_flags) &&
+ src->format->format == dst->format->format &&
+ !SDL_ISPIXELFORMAT_INDEXED(src->format->format) ) {
return SDL_SoftStretch( src, srcrect, dst, dstrect );
+ } else {
+ return SDL_LowerBlit( src, srcrect, dst, dstrect );
}
} else {
- return SDL_LowerBlit( src, srcrect, dst, dstrect );
+ if ( !(src->map->info.flags & complex_copy_flags) &&
+ src->format->format == dst->format->format &&
+ !SDL_ISPIXELFORMAT_INDEXED(src->format->format) &&
+ src->format->BytesPerPixel == 4 &&
+ src->format->format != SDL_PIXELFORMAT_ARGB2101010) {
+ /* fast path */
+ return SDL_SoftStretchLinear(src, srcrect, dst, dstrect);
+ } else {
+ /* Use an intermediate surface */
+ SDL_Surface *tmp;
+ int ret;
+ SDL_Rect tmprect;
+ Uint8 r, g, b, a;
+ Uint8 alpha;
+ SDL_BlendMode blendMode;
+
+ tmp = SDL_CreateRGBSurfaceWithFormat(src->flags, dstrect->w, dstrect->h, 0, src->format->format);
+
+ SDL_GetSurfaceColorMod(src, &r, &g, &b);
+ SDL_GetSurfaceAlphaMod(src, &alpha);
+ SDL_GetSurfaceBlendMode(src, &blendMode);
+
+ SDL_SoftStretchLinear(src, srcrect, tmp, NULL);
+
+ SDL_SetSurfaceColorMod(tmp, r, g, b);
+ SDL_SetSurfaceAlphaMod(tmp, alpha);
+ SDL_SetSurfaceBlendMode(tmp, blendMode);
+
+ tmprect.x = 0;
+ tmprect.y = 0;
+ tmprect.w = dstrect->w;
+ tmprect.h = dstrect->h;
+ ret = SDL_LowerBlit(tmp, &tmprect, dst, dstrect);
+
+ SDL_FreeSurface(tmp);
+ return ret;
+ }
}
}