Switched the SDL 1.2 compatibility to use the window surface, so it's fast even when there's no hardware acceleration available.
authorSam Lantinga <slouken@libsdl.org>
Thu, 03 Feb 2011 21:13:55 -0800
changeset 5169ededa1ccf91c
parent 5168 db487f28419e
child 5171 34e2d5115786
Switched the SDL 1.2 compatibility to use the window surface, so it's fast even when there's no hardware acceleration available.
This means that the YUV overlay now uses software, but that's okay since fast YUV code should be using the textures now anyway.
include/SDL_compat.h
src/SDL_compat.c
src/video/SDL_video.c
     1.1 --- a/include/SDL_compat.h	Thu Feb 03 17:42:58 2011 -0800
     1.2 +++ b/include/SDL_compat.h	Thu Feb 03 21:13:55 2011 -0800
     1.3 @@ -273,8 +273,8 @@
     1.4  #define SDL_AllocSurface    SDL_CreateRGBSurface
     1.5  
     1.6  extern DECLSPEC const SDL_version *SDLCALL SDL_Linked_Version(void);
     1.7 -extern DECLSPEC char *SDLCALL SDL_AudioDriverName(char *namebuf, int maxlen);
     1.8 -extern DECLSPEC char *SDLCALL SDL_VideoDriverName(char *namebuf, int maxlen);
     1.9 +extern DECLSPEC const char *SDLCALL SDL_AudioDriverName(char *namebuf, int maxlen);
    1.10 +extern DECLSPEC const char *SDLCALL SDL_VideoDriverName(char *namebuf, int maxlen);
    1.11  extern DECLSPEC const SDL_VideoInfo *SDLCALL SDL_GetVideoInfo(void);
    1.12  extern DECLSPEC int SDLCALL SDL_VideoModeOK(int width,
    1.13                                              int height,
     2.1 --- a/src/SDL_compat.c	Thu Feb 03 17:42:58 2011 -0800
     2.2 +++ b/src/SDL_compat.c	Thu Feb 03 21:13:55 2011 -0800
     2.3 @@ -28,10 +28,10 @@
     2.4  
     2.5  #include "video/SDL_sysvideo.h"
     2.6  #include "video/SDL_pixels_c.h"
     2.7 +#include "render/SDL_yuv_sw_c.h"
     2.8 +
     2.9  
    2.10  static SDL_Window *SDL_VideoWindow = NULL;
    2.11 -static SDL_Renderer *SDL_VideoRenderer = NULL;
    2.12 -static SDL_Texture *SDL_VideoTexture = NULL;
    2.13  static SDL_Surface *SDL_VideoSurface = NULL;
    2.14  static SDL_Surface *SDL_ShadowSurface = NULL;
    2.15  static SDL_Surface *SDL_PublicSurface = NULL;
    2.16 @@ -41,18 +41,22 @@
    2.17  static SDL_Surface *SDL_VideoIcon;
    2.18  static int SDL_enabled_UNICODE = 0;
    2.19  
    2.20 -char *
    2.21 +const char *
    2.22  SDL_AudioDriverName(char *namebuf, int maxlen)
    2.23  {
    2.24      const char *name = SDL_GetCurrentAudioDriver();
    2.25      if (name) {
    2.26 -        SDL_strlcpy(namebuf, name, maxlen);
    2.27 -        return namebuf;
    2.28 +        if (namebuf) {
    2.29 +            SDL_strlcpy(namebuf, name, maxlen);
    2.30 +            return namebuf;
    2.31 +        } else {
    2.32 +            return name;
    2.33 +        }
    2.34      }
    2.35      return NULL;
    2.36  }
    2.37  
    2.38 -char *
    2.39 +const char *
    2.40  SDL_VideoDriverName(char *namebuf, int maxlen)
    2.41  {
    2.42      const char *name = SDL_GetCurrentVideoDriver();
    2.43 @@ -344,27 +348,6 @@
    2.44      }
    2.45  }
    2.46  
    2.47 -static SDL_Surface *
    2.48 -CreateVideoSurface(SDL_Texture * texture)
    2.49 -{
    2.50 -    Uint32 format;
    2.51 -    int w, h;
    2.52 -    int bpp;
    2.53 -    Uint32 Rmask, Gmask, Bmask, Amask;
    2.54 -
    2.55 -    if (SDL_QueryTexture(texture, &format, NULL, &w, &h) < 0) {
    2.56 -        return NULL;
    2.57 -    }
    2.58 -
    2.59 -    if (!SDL_PixelFormatEnumToMasks
    2.60 -        (format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
    2.61 -        SDL_SetError("Unknown texture format");
    2.62 -        return NULL;
    2.63 -    }
    2.64 -
    2.65 -    return SDL_CreateRGBSurface(0, w, h, bpp, Rmask, Gmask, Bmask, Amask);
    2.66 -}
    2.67 -
    2.68  static void
    2.69  ClearVideoSurface()
    2.70  {
    2.71 @@ -434,23 +417,11 @@
    2.72      }
    2.73  
    2.74      /* Destroy the screen texture and recreate it */
    2.75 -    SDL_QueryTexture(SDL_VideoTexture, &format, &access, &w, &h);
    2.76 -    SDL_DestroyTexture(SDL_VideoTexture);
    2.77 -    SDL_VideoTexture = SDL_CreateTexture(SDL_VideoRenderer, format,
    2.78 -                                         access, width, height);
    2.79 -    if (!SDL_VideoTexture) {
    2.80 +    SDL_VideoSurface = SDL_GetWindowSurface(SDL_VideoWindow);
    2.81 +    if (!SDL_VideoSurface) {
    2.82          return -1;
    2.83      }
    2.84  
    2.85 -    SDL_VideoSurface->w = width;
    2.86 -    SDL_VideoSurface->h = height;
    2.87 -    SDL_CalculatePitch(SDL_VideoSurface);
    2.88 -    SDL_VideoSurface->pixels =
    2.89 -        SDL_realloc(SDL_VideoSurface->pixels,
    2.90 -                    SDL_VideoSurface->h * SDL_VideoSurface->pitch);
    2.91 -    SDL_SetClipRect(SDL_VideoSurface, NULL);
    2.92 -    SDL_InvalidateMap(SDL_VideoSurface->map);
    2.93 -
    2.94      if (SDL_ShadowSurface) {
    2.95          SDL_ShadowSurface->w = width;
    2.96          SDL_ShadowSurface->h = height;
    2.97 @@ -460,6 +431,8 @@
    2.98                          SDL_ShadowSurface->h * SDL_ShadowSurface->pitch);
    2.99          SDL_SetClipRect(SDL_ShadowSurface, NULL);
   2.100          SDL_InvalidateMap(SDL_ShadowSurface->map);
   2.101 +    } else {
   2.102 +        SDL_PublicSurface = SDL_VideoSurface;
   2.103      }
   2.104  
   2.105      ClearVideoSurface();
   2.106 @@ -476,8 +449,6 @@
   2.107      Uint32 window_flags;
   2.108      Uint32 surface_flags;
   2.109      Uint32 i;
   2.110 -    SDL_RendererInfo info;
   2.111 -    Uint32 desired_format;
   2.112  
   2.113      if (!SDL_GetVideoDevice()) {
   2.114          if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0) {
   2.115 @@ -586,30 +557,8 @@
   2.116          return SDL_PublicSurface;
   2.117      }
   2.118  
   2.119 -    /* Create a renderer for the window */
   2.120 -    SDL_VideoRenderer = SDL_CreateRenderer(SDL_VideoWindow, -1, 0);
   2.121 -    if (!SDL_VideoRenderer) {
   2.122 -        return NULL;
   2.123 -    }
   2.124 -
   2.125 -    /* Create a texture for the screen surface */
   2.126 -    SDL_GetRendererInfo(SDL_VideoRenderer, &info);
   2.127 -    desired_format = info.texture_formats[0];
   2.128 -    for (i = 0; i < info.num_texture_formats; ++i) {
   2.129 -        if (!SDL_ISPIXELFORMAT_ALPHA(info.texture_formats[i])) {
   2.130 -            desired_format = info.texture_formats[i];
   2.131 -            break;
   2.132 -        }
   2.133 -    }
   2.134 -    SDL_VideoTexture = SDL_CreateTexture(SDL_VideoRenderer, desired_format,
   2.135 -                                         SDL_TEXTUREACCESS_STREAMING,
   2.136 -                                         width, height);
   2.137 -    if (!SDL_VideoTexture) {
   2.138 -        return NULL;
   2.139 -    }
   2.140 -
   2.141      /* Create the screen surface */
   2.142 -    SDL_VideoSurface = CreateVideoSurface(SDL_VideoTexture);
   2.143 +    SDL_VideoSurface = SDL_GetWindowSurface(SDL_VideoWindow);
   2.144      if (!SDL_VideoSurface) {
   2.145          return NULL;
   2.146      }
   2.147 @@ -774,22 +723,7 @@
   2.148          screen = SDL_VideoSurface;
   2.149      }
   2.150      if (screen == SDL_VideoSurface) {
   2.151 -        /* The surface memory needs to be copied to texture */
   2.152 -        int pitch = screen->pitch;
   2.153 -        int psize = screen->format->BytesPerPixel;
   2.154 -        for (i = 0; i < numrects; ++i) {
   2.155 -            const SDL_Rect *rect = &rects[i];
   2.156 -            void *pixels =
   2.157 -                (Uint8 *) screen->pixels + rect->y * pitch +
   2.158 -                rect->x * psize;
   2.159 -            SDL_UpdateTexture(SDL_VideoTexture, rect, pixels, pitch);
   2.160 -        }
   2.161 -        rect.x = 0;
   2.162 -        rect.y = 0;
   2.163 -        rect.w = screen->w;
   2.164 -        rect.h = screen->h;
   2.165 -        SDL_RenderCopy(SDL_VideoRenderer, SDL_VideoTexture, &rect, &rect);
   2.166 -        SDL_RenderPresent(SDL_VideoRenderer);
   2.167 +        SDL_UpdateWindowSurfaceRects(SDL_VideoWindow, numrects, rects);
   2.168      }
   2.169  }
   2.170  
   2.171 @@ -1395,11 +1329,9 @@
   2.172  
   2.173  struct private_yuvhwdata
   2.174  {
   2.175 -    Uint16 pitches[3];
   2.176 -    Uint8 *planes[3];
   2.177 -
   2.178 -    SDL_Texture *texture;
   2.179 -    Uint32 texture_format;
   2.180 +    SDL_SW_YUVTexture *texture;
   2.181 +    SDL_Surface *display;
   2.182 +    Uint32 display_format;
   2.183  };
   2.184  
   2.185  SDL_Overlay *
   2.186 @@ -1407,6 +1339,7 @@
   2.187  {
   2.188      SDL_Overlay *overlay;
   2.189      Uint32 texture_format;
   2.190 +    SDL_SW_YUVTexture *texture;
   2.191  
   2.192      if ((display->flags & SDL_OPENGL) == SDL_OPENGL) {
   2.193          SDL_SetError("YUV overlays are not supported in OpenGL mode");
   2.194 @@ -1454,6 +1387,16 @@
   2.195          return NULL;
   2.196      }
   2.197  
   2.198 +    texture = SDL_SW_CreateYUVTexture(texture_format, w, h);
   2.199 +    if (!texture) {
   2.200 +        SDL_free(overlay->hwdata);
   2.201 +        SDL_free(overlay);
   2.202 +        return NULL;
   2.203 +    }
   2.204 +    overlay->hwdata->texture = texture;
   2.205 +    overlay->hwdata->display = NULL;
   2.206 +    overlay->hwdata->display_format = SDL_PIXELFORMAT_UNKNOWN;
   2.207 +
   2.208      overlay->format = format;
   2.209      overlay->w = w;
   2.210      overlay->h = h;
   2.211 @@ -1462,31 +1405,8 @@
   2.212      } else {
   2.213          overlay->planes = 1;
   2.214      }
   2.215 -    overlay->pitches = overlay->hwdata->pitches;
   2.216 -    overlay->pixels = overlay->hwdata->planes;
   2.217 -
   2.218 -    switch (format) {
   2.219 -    case SDL_YV12_OVERLAY:
   2.220 -    case SDL_IYUV_OVERLAY:
   2.221 -        overlay->pitches[0] = overlay->w;
   2.222 -        overlay->pitches[1] = overlay->w / 2;
   2.223 -        overlay->pitches[2] = overlay->w / 2;
   2.224 -        break;
   2.225 -    case SDL_YUY2_OVERLAY:
   2.226 -    case SDL_UYVY_OVERLAY:
   2.227 -    case SDL_YVYU_OVERLAY:
   2.228 -        overlay->pitches[0] = overlay->w * 2;
   2.229 -        break;
   2.230 -    }
   2.231 -
   2.232 -    overlay->hwdata->texture =
   2.233 -        SDL_CreateTexture(SDL_VideoRenderer, texture_format,
   2.234 -                          SDL_TEXTUREACCESS_STREAMING, w, h);
   2.235 -    if (!overlay->hwdata->texture) {
   2.236 -        SDL_FreeYUVOverlay(overlay);
   2.237 -        return NULL;
   2.238 -    }
   2.239 -    overlay->hwdata->texture_format = texture_format;
   2.240 +    overlay->pitches = texture->pitches;
   2.241 +    overlay->pixels = texture->planes;
   2.242  
   2.243      return overlay;
   2.244  }
   2.245 @@ -1494,6 +1414,7 @@
   2.246  int
   2.247  SDL_LockYUVOverlay(SDL_Overlay * overlay)
   2.248  {
   2.249 +    SDL_Rect rect;
   2.250      void *pixels;
   2.251      int pitch;
   2.252  
   2.253 @@ -1501,9 +1422,16 @@
   2.254          SDL_SetError("Passed a NULL overlay");
   2.255          return -1;
   2.256      }
   2.257 -    if (SDL_LockTexture(overlay->hwdata->texture, NULL, &pixels, &pitch) < 0) {
   2.258 +
   2.259 +    rect.x = 0;
   2.260 +    rect.y = 0;
   2.261 +    rect.w = overlay->w;
   2.262 +    rect.h = overlay->h;
   2.263 +
   2.264 +    if (SDL_SW_LockYUVTexture(overlay->hwdata->texture, &rect, &pixels, &pitch) < 0) {
   2.265          return -1;
   2.266      }
   2.267 +
   2.268      overlay->pixels[0] = (Uint8 *) pixels;
   2.269      overlay->pitches[0] = pitch;
   2.270      switch (overlay->format) {
   2.271 @@ -1530,20 +1458,54 @@
   2.272      if (!overlay) {
   2.273          return;
   2.274      }
   2.275 -    SDL_UnlockTexture(overlay->hwdata->texture);
   2.276 +
   2.277 +    SDL_SW_UnlockYUVTexture(overlay->hwdata->texture);
   2.278  }
   2.279  
   2.280  int
   2.281  SDL_DisplayYUVOverlay(SDL_Overlay * overlay, SDL_Rect * dstrect)
   2.282  {
   2.283 +    SDL_Surface *display;
   2.284 +    SDL_Rect src_rect;
   2.285 +    SDL_Rect dst_rect;
   2.286 +    void *pixels;
   2.287 +
   2.288      if (!overlay || !dstrect) {
   2.289          SDL_SetError("Passed a NULL overlay or dstrect");
   2.290          return -1;
   2.291      }
   2.292 -    if (SDL_RenderCopy(SDL_VideoRenderer, overlay->hwdata->texture, NULL, dstrect) < 0) {
   2.293 +
   2.294 +    display = overlay->hwdata->display;
   2.295 +    if (display != SDL_VideoSurface) {
   2.296 +        overlay->hwdata->display = display = SDL_VideoSurface;
   2.297 +        overlay->hwdata->display_format = SDL_MasksToPixelFormatEnum(
   2.298 +                                                display->format->BitsPerPixel,
   2.299 +                                                display->format->Rmask,
   2.300 +                                                display->format->Gmask,
   2.301 +                                                display->format->Bmask,
   2.302 +                                                display->format->Amask);
   2.303 +    }
   2.304 +
   2.305 +    src_rect.x = 0;
   2.306 +    src_rect.y = 0;
   2.307 +    src_rect.w = overlay->w;
   2.308 +    src_rect.h = overlay->h;
   2.309 +
   2.310 +    if (!SDL_IntersectRect(&display->clip_rect, dstrect, &dst_rect)) {
   2.311 +        return 0;
   2.312 +    }
   2.313 +     
   2.314 +    pixels = (void *)((Uint8 *)display->pixels +
   2.315 +                        dst_rect.y * display->pitch +
   2.316 +                        dst_rect.x * display->format->BytesPerPixel);
   2.317 +
   2.318 +    if (SDL_SW_CopyYUVToRGB(overlay->hwdata->texture, &src_rect,
   2.319 +                            overlay->hwdata->display_format,
   2.320 +                            dst_rect.w, dst_rect.h,
   2.321 +                            pixels, display->pitch) < 0) {
   2.322          return -1;
   2.323      }
   2.324 -    SDL_RenderPresent(SDL_VideoRenderer);
   2.325 +    SDL_UpdateWindowSurface(SDL_VideoWindow);
   2.326      return 0;
   2.327  }
   2.328  
   2.329 @@ -1555,7 +1517,7 @@
   2.330      }
   2.331      if (overlay->hwdata) {
   2.332          if (overlay->hwdata->texture) {
   2.333 -            SDL_DestroyTexture(overlay->hwdata->texture);
   2.334 +            SDL_SW_DestroyYUVTexture(overlay->hwdata->texture);
   2.335          }
   2.336          SDL_free(overlay->hwdata);
   2.337      }
     3.1 --- a/src/video/SDL_video.c	Thu Feb 03 17:42:58 2011 -0800
     3.2 +++ b/src/video/SDL_video.c	Thu Feb 03 21:13:55 2011 -0800
     3.3 @@ -1391,6 +1391,9 @@
     3.4  
     3.5      if (!window->surface) {
     3.6          window->surface = SDL_CreateWindowFramebuffer(window);
     3.7 +        if (window->surface) {
     3.8 +            window->surface->refcount = 0x7FFFFFF;
     3.9 +        }
    3.10      }
    3.11      return window->surface;
    3.12  }
    3.13 @@ -1472,6 +1475,7 @@
    3.14  SDL_OnWindowResized(SDL_Window * window)
    3.15  {
    3.16      if (window->surface) {
    3.17 +        window->surface->refcount = 0;
    3.18          SDL_FreeSurface(window->surface);
    3.19          window->surface = NULL;
    3.20      }
    3.21 @@ -1552,6 +1556,10 @@
    3.22      /* Restore video mode, etc. */
    3.23      SDL_UpdateFullscreenMode(window, SDL_FALSE);
    3.24  
    3.25 +    if (window->surface) {
    3.26 +        window->surface->refcount = 0;
    3.27 +        SDL_FreeSurface(window->surface);
    3.28 +    }
    3.29      if (_this->DestroyWindowFramebuffer) {
    3.30          _this->DestroyWindowFramebuffer(_this, window);
    3.31      }