src/render/SDL_render.c
changeset 5158 b3ccd1947786
parent 5157 657543cc92f9
child 5166 4d39eeaad00b
     1.1 --- a/src/render/SDL_render.c	Thu Feb 03 00:22:18 2011 -0800
     1.2 +++ b/src/render/SDL_render.c	Thu Feb 03 00:54:29 2011 -0800
     1.3 @@ -250,13 +250,15 @@
     1.4  }
     1.5  
     1.6  SDL_Texture *
     1.7 -SDL_CreateTextureFromSurface(SDL_Renderer * renderer, Uint32 format, SDL_Surface * surface)
     1.8 +SDL_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface)
     1.9  {
    1.10 -    SDL_Texture *texture;
    1.11 -    Uint32 requested_format = format;
    1.12 -    SDL_PixelFormat *fmt;
    1.13 +    const SDL_PixelFormat *fmt;
    1.14 +    SDL_bool needAlpha;
    1.15 +    Uint32 i;
    1.16 +    Uint32 format;
    1.17      int bpp;
    1.18      Uint32 Rmask, Gmask, Bmask, Amask;
    1.19 +    SDL_Texture *texture;
    1.20  
    1.21      CHECK_RENDERER_MAGIC(renderer, NULL);
    1.22  
    1.23 @@ -264,255 +266,56 @@
    1.24          SDL_SetError("SDL_CreateTextureFromSurface() passed NULL surface");
    1.25          return NULL;
    1.26      }
    1.27 +
    1.28 +    /* See what the best texture format is */
    1.29      fmt = surface->format;
    1.30 -
    1.31 -    if (format) {
    1.32 -        if (!SDL_PixelFormatEnumToMasks
    1.33 -            (format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
    1.34 -            SDL_SetError("Unknown pixel format");
    1.35 -            return 0;
    1.36 -        }
    1.37 +    if (fmt->Amask || SDL_GetColorKey(surface, NULL) == 0) {
    1.38 +        needAlpha = SDL_TRUE;
    1.39      } else {
    1.40 -        SDL_bool hasColorkey;
    1.41 -        SDL_BlendMode blendMode;
    1.42 -        SDL_bool hasBlending;
    1.43 -
    1.44 -        hasColorkey = (SDL_GetColorKey(surface, NULL) == 0);
    1.45 -
    1.46 -        SDL_GetSurfaceBlendMode(surface, &blendMode);
    1.47 -        hasBlending = (blendMode == SDL_BLENDMODE_BLEND);
    1.48 -
    1.49 -        if (surface->format->Amask || (!hasColorkey && !hasBlending)) {
    1.50 -            Uint32 it;
    1.51 -            int pfmt;
    1.52 -
    1.53 -            /* Pixel formats, sorted by best first */
    1.54 -            static const Uint32 sdl_pformats[] = {
    1.55 -                SDL_PIXELFORMAT_ARGB8888,
    1.56 -                SDL_PIXELFORMAT_RGBA8888,
    1.57 -                SDL_PIXELFORMAT_ABGR8888,
    1.58 -                SDL_PIXELFORMAT_BGRA8888,
    1.59 -                SDL_PIXELFORMAT_RGB888,
    1.60 -                SDL_PIXELFORMAT_BGR888,
    1.61 -                SDL_PIXELFORMAT_RGB24,
    1.62 -                SDL_PIXELFORMAT_BGR24,
    1.63 -                SDL_PIXELFORMAT_RGB565,
    1.64 -                SDL_PIXELFORMAT_BGR565,
    1.65 -                SDL_PIXELFORMAT_ARGB1555,
    1.66 -                SDL_PIXELFORMAT_RGBA5551,
    1.67 -                SDL_PIXELFORMAT_ABGR1555,
    1.68 -                SDL_PIXELFORMAT_BGRA5551,
    1.69 -                SDL_PIXELFORMAT_RGB555,
    1.70 -                SDL_PIXELFORMAT_BGR555,
    1.71 -                SDL_PIXELFORMAT_ARGB4444,
    1.72 -                SDL_PIXELFORMAT_RGBA4444,
    1.73 -                SDL_PIXELFORMAT_ABGR4444,
    1.74 -                SDL_PIXELFORMAT_BGRA4444,
    1.75 -                SDL_PIXELFORMAT_RGB444,
    1.76 -                SDL_PIXELFORMAT_ARGB2101010,
    1.77 -                SDL_PIXELFORMAT_RGB332,
    1.78 -                SDL_PIXELFORMAT_UNKNOWN
    1.79 -            };
    1.80 -
    1.81 -            bpp = fmt->BitsPerPixel;
    1.82 -            Rmask = fmt->Rmask;
    1.83 -            Gmask = fmt->Gmask;
    1.84 -            Bmask = fmt->Bmask;
    1.85 -            Amask = fmt->Amask;
    1.86 -
    1.87 -            format =
    1.88 -                SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask);
    1.89 -            if (!format) {
    1.90 -                SDL_SetError("Unknown pixel format");
    1.91 -                return 0;
    1.92 -            }
    1.93 -
    1.94 -            /* Search requested format in the supported texture */
    1.95 -            /* formats by current renderer                      */
    1.96 -            for (it = 0; it < renderer->info.num_texture_formats; it++) {
    1.97 -                if (renderer->info.texture_formats[it] == format) {
    1.98 -                    break;
    1.99 -                }
   1.100 -            }
   1.101 -
   1.102 -            /* If requested format can't be found, search any best */
   1.103 -            /* format which renderer provides                      */
   1.104 -            if (it == renderer->info.num_texture_formats) {
   1.105 -                pfmt = 0;
   1.106 -                for (;;) {
   1.107 -                    if (sdl_pformats[pfmt] == SDL_PIXELFORMAT_UNKNOWN) {
   1.108 -                        break;
   1.109 -                    }
   1.110 -
   1.111 -                    for (it = 0; it < renderer->info.num_texture_formats;
   1.112 -                         it++) {
   1.113 -                        if (renderer->info.texture_formats[it] ==
   1.114 -                            sdl_pformats[pfmt]) {
   1.115 -                            break;
   1.116 -                        }
   1.117 -                    }
   1.118 -
   1.119 -                    if (it != renderer->info.num_texture_formats) {
   1.120 -                        /* The best format has been found */
   1.121 -                        break;
   1.122 -                    }
   1.123 -                    pfmt++;
   1.124 -                }
   1.125 -
   1.126 -                /* If any format can't be found, then return an error */
   1.127 -                if (it == renderer->info.num_texture_formats) {
   1.128 -                    SDL_SetError
   1.129 -                        ("Any of the supported pixel formats can't be found");
   1.130 -                    return 0;
   1.131 -                }
   1.132 -
   1.133 -                /* Convert found pixel format back to color masks */
   1.134 -                if (SDL_PixelFormatEnumToMasks
   1.135 -                    (renderer->info.texture_formats[it], &bpp, &Rmask, &Gmask,
   1.136 -                     &Bmask, &Amask) != SDL_TRUE) {
   1.137 -                    SDL_SetError("Unknown pixel format");
   1.138 -                    return 0;
   1.139 -                }
   1.140 -            }
   1.141 -        } else {
   1.142 -            /* Need a format with alpha */
   1.143 -            Uint32 it;
   1.144 -            int apfmt;
   1.145 -
   1.146 -            /* Pixel formats with alpha, sorted by best first */
   1.147 -            static const Uint32 sdl_alpha_pformats[] = {
   1.148 -                SDL_PIXELFORMAT_ARGB8888,
   1.149 -                SDL_PIXELFORMAT_RGBA8888,
   1.150 -                SDL_PIXELFORMAT_ABGR8888,
   1.151 -                SDL_PIXELFORMAT_BGRA8888,
   1.152 -                SDL_PIXELFORMAT_ARGB1555,
   1.153 -                SDL_PIXELFORMAT_RGBA5551,
   1.154 -                SDL_PIXELFORMAT_ABGR1555,
   1.155 -                SDL_PIXELFORMAT_BGRA5551,
   1.156 -                SDL_PIXELFORMAT_ARGB4444,
   1.157 -                SDL_PIXELFORMAT_RGBA4444,
   1.158 -                SDL_PIXELFORMAT_ABGR4444,
   1.159 -                SDL_PIXELFORMAT_BGRA4444,
   1.160 -                SDL_PIXELFORMAT_ARGB2101010,
   1.161 -                SDL_PIXELFORMAT_UNKNOWN
   1.162 -            };
   1.163 -
   1.164 -            if (surface->format->Amask) {
   1.165 -                /* If surface already has alpha, then try an original */
   1.166 -                /* surface format first                               */
   1.167 -                bpp = fmt->BitsPerPixel;
   1.168 -                Rmask = fmt->Rmask;
   1.169 -                Gmask = fmt->Gmask;
   1.170 -                Bmask = fmt->Bmask;
   1.171 -                Amask = fmt->Amask;
   1.172 -            } else {
   1.173 -                bpp = 32;
   1.174 -                Rmask = 0x00FF0000;
   1.175 -                Gmask = 0x0000FF00;
   1.176 -                Bmask = 0x000000FF;
   1.177 -                Amask = 0xFF000000;
   1.178 -            }
   1.179 -
   1.180 -            format =
   1.181 -                SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask);
   1.182 -            if (!format) {
   1.183 -                SDL_SetError("Unknown pixel format");
   1.184 -                return 0;
   1.185 -            }
   1.186 -
   1.187 -            /* Search this format in the supported texture formats */
   1.188 -            /* by current renderer                                 */
   1.189 -            for (it = 0; it < renderer->info.num_texture_formats; it++) {
   1.190 -                if (renderer->info.texture_formats[it] == format) {
   1.191 -                    break;
   1.192 -                }
   1.193 -            }
   1.194 -
   1.195 -            /* If this format can't be found, search any best       */
   1.196 -            /* compatible format with alpha which renderer provides */
   1.197 -            if (it == renderer->info.num_texture_formats) {
   1.198 -                apfmt = 0;
   1.199 -                for (;;) {
   1.200 -                    if (sdl_alpha_pformats[apfmt] == SDL_PIXELFORMAT_UNKNOWN) {
   1.201 -                        break;
   1.202 -                    }
   1.203 -
   1.204 -                    for (it = 0; it < renderer->info.num_texture_formats;
   1.205 -                         it++) {
   1.206 -                        if (renderer->info.texture_formats[it] ==
   1.207 -                            sdl_alpha_pformats[apfmt]) {
   1.208 -                            break;
   1.209 -                        }
   1.210 -                    }
   1.211 -
   1.212 -                    if (it != renderer->info.num_texture_formats) {
   1.213 -                        /* Compatible format has been found */
   1.214 -                        break;
   1.215 -                    }
   1.216 -                    apfmt++;
   1.217 -                }
   1.218 -
   1.219 -                /* If compatible format can't be found, then return an error */
   1.220 -                if (it == renderer->info.num_texture_formats) {
   1.221 -                    SDL_SetError("Compatible pixel format can't be found");
   1.222 -                    return 0;
   1.223 -                }
   1.224 -
   1.225 -                /* Convert found pixel format back to color masks */
   1.226 -                if (SDL_PixelFormatEnumToMasks
   1.227 -                    (renderer->info.texture_formats[it], &bpp, &Rmask, &Gmask,
   1.228 -                     &Bmask, &Amask) != SDL_TRUE) {
   1.229 -                    SDL_SetError("Unknown pixel format");
   1.230 -                    return 0;
   1.231 -                }
   1.232 -            }
   1.233 -        }
   1.234 -
   1.235 -        format = SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask);
   1.236 -        if (!format) {
   1.237 -            SDL_SetError("Unknown pixel format");
   1.238 -            return 0;
   1.239 +        needAlpha = SDL_FALSE;
   1.240 +    }
   1.241 +    format = renderer->info.texture_formats[0];
   1.242 +    for (i = 0; i < renderer->info.num_texture_formats; ++i) {
   1.243 +        if (SDL_ISPIXELFORMAT_ALPHA(renderer->info.texture_formats[i]) == needAlpha) {
   1.244 +            format = renderer->info.texture_formats[i];
   1.245 +            break;
   1.246          }
   1.247      }
   1.248  
   1.249 -    texture =
   1.250 -        SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_STATIC,
   1.251 -                          surface->w, surface->h);
   1.252 -    if (!texture && !requested_format) {
   1.253 -        SDL_DisplayMode desktop_mode;
   1.254 -        SDL_GetDesktopDisplayMode(&desktop_mode);
   1.255 -        format = desktop_mode.format;
   1.256 -        texture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_STATIC,
   1.257 -                                    surface->w, surface->h);
   1.258 +    if (!SDL_PixelFormatEnumToMasks(format, &bpp,
   1.259 +                                    &Rmask, &Gmask, &Bmask, &Amask)) {
   1.260 +        SDL_SetError("Unknown pixel format");
   1.261 +        return NULL;
   1.262      }
   1.263 +
   1.264 +    texture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_STATIC,
   1.265 +                                surface->w, surface->h);
   1.266      if (!texture) {
   1.267 -        return 0;
   1.268 +        return NULL;
   1.269      }
   1.270 +
   1.271      if (bpp == fmt->BitsPerPixel && Rmask == fmt->Rmask && Gmask == fmt->Gmask
   1.272          && Bmask == fmt->Bmask && Amask == fmt->Amask) {
   1.273          if (SDL_MUSTLOCK(surface)) {
   1.274              SDL_LockSurface(surface);
   1.275 -            SDL_UpdateTexture(texture, NULL, surface->pixels,
   1.276 -                              surface->pitch);
   1.277 +            SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch);
   1.278              SDL_UnlockSurface(surface);
   1.279          } else {
   1.280 -            SDL_UpdateTexture(texture, NULL, surface->pixels,
   1.281 -                              surface->pitch);
   1.282 +            SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch);
   1.283          }
   1.284      } else {
   1.285          SDL_PixelFormat dst_fmt;
   1.286 -        SDL_Surface *dst = NULL;
   1.287 +        SDL_Surface *temp = NULL;
   1.288  
   1.289          /* Set up a destination surface for the texture update */
   1.290          SDL_InitFormat(&dst_fmt, bpp, Rmask, Gmask, Bmask, Amask);
   1.291 -        dst = SDL_ConvertSurface(surface, &dst_fmt, 0);
   1.292 -        if (dst) {
   1.293 -            SDL_UpdateTexture(texture, NULL, dst->pixels, dst->pitch);
   1.294 -            SDL_FreeSurface(dst);
   1.295 -        }
   1.296 -        if (!dst) {
   1.297 +        temp = SDL_ConvertSurface(surface, &dst_fmt, 0);
   1.298 +        if (temp) {
   1.299 +            SDL_UpdateTexture(texture, NULL, temp->pixels, temp->pitch);
   1.300 +            SDL_FreeSurface(temp);
   1.301 +        } else {
   1.302              SDL_DestroyTexture(texture);
   1.303 -            return 0;
   1.304 +            return NULL;
   1.305          }
   1.306      }
   1.307